diff --git a/src/java/org/web3d/browser/BrowserComponent.java b/src/java/org/web3d/browser/BrowserComponent.java
index 88de6945f014e298602095e593c4823e5a8cf412..e17849f50b59d9db2eebe63c3ca5e4a9377748d4 100644
--- a/src/java/org/web3d/browser/BrowserComponent.java
+++ b/src/java/org/web3d/browser/BrowserComponent.java
@@ -1,94 +1,95 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2004 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-package org.web3d.browser;
-
-// External imports
-
-// Local imports
-import org.j3d.util.ErrorReporter;
-
-/**
- * Abstraction of a specific rendering component that can be placed on
- * screen regardless of renderer type.
- *
- * @author Justin Couch
- * @version $Revision: 1.4 $
- */
-public interface BrowserComponent {
-
-    /**
-     * Get the spec version that is supported.
-     *
-     * @return a number representing the spec major version
-     */
-    int supportedSpecificationVersion();
-
-    /**
-     * Get the UI toolkit specific component holding this browser.
-     *
-     * @return The component
-     */
-    Object getCanvas();
-
-    /**
-     * Get the renderer type.
-     *
-     * @return The BrowserCore type
-     */
-    int getRendererType();
-
-    /**
-     * Get the core browser implementation.
-     *
-     * @return the BrowserCore
-     */
-    BrowserCore getBrowserCore();
-
-    /**
-     * Fetch the error handler so that application code can post messages
-     * too.
-     *
-     * @return The current error handler instance
-     */
-    ErrorReporter getErrorReporter();
-
-    /**
-     * Set the minimum frame interval time to limit the CPU resources taken up
-     * by the 3D renderer. By default it will use all of them. The second
-     * parameter is used to control whether this is a user-set hard minimum or
-     * something set by the browser internals. User set values are always
-     * treated as the minimum unless the browser internals set a value that is
-     * a slower framerate than the user set. If the browser then sets a faster
-     * framerate than the user set value, the user value is used instead.
-     *
-     * @param millis The minimum time in milliseconds.
-     * @param userSet true if this is an end-user set minimum
-     */
-    void setMinimumFrameInterval(int millis, boolean userSet);
-
-    /**
-     * Called to instruct the component instance to start rendering now.
-     */
-    void start();
-
-    /**
-     * Called to instruct the component instance to stop and suspend its state.
-     * The renderer should stop at this point.
-     */
-    void stop();
-
-    /**
-     * Called to instruct the component instance to destroy itself and any
-     * used resources. It will not be used again.
-     */
-    void destroy();
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2004 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+package org.web3d.browser;
+
+// External imports
+
+// Local imports
+import org.j3d.util.ErrorReporter;
+
+/**
+ * Abstraction of a specific rendering component that can be placed on
+ * screen regardless of renderer type.
+ * <p>
+ *
+ * @author Justin Couch
+ * @version $Revision: 1.4 $
+ */
+public interface BrowserComponent {
+
+    /**
+     * Get the spec version that is supported.
+     *
+     * @return a number representing the spec major version
+     */
+    int supportedSpecificationVersion();
+
+    /**
+     * Get the UI toolkit specific component holding this browser.
+     *
+     * @return The component
+     */
+    Object getCanvas();
+
+    /**
+     * Get the renderer type.
+     *
+     * @return The BrowserCore type
+     */
+    int getRendererType();
+
+    /**
+     * Get the core browser implementation.
+     *
+     * @return the BrowserCore
+     */
+    BrowserCore getBrowserCore();
+
+    /**
+     * Fetch the error handler so that application code can post messages
+     * too.
+     *
+     * @return The current error handler instance
+     */
+    ErrorReporter getErrorReporter();
+
+    /**
+     * Set the minimum frame interval time to limit the CPU resources taken up
+     * by the 3D renderer. By default it will use all of them. The second
+     * parameter is used to control whether this is a user-set hard minimum or
+     * something set by the browser internals. User set values are always
+     * treated as the minimum unless the browser internals set a value that is
+     * a slower framerate than the user set. If the browser then sets a faster
+     * framerate than the user set value, the user value is used instead.
+     *
+     * @param millis The minimum time in milliseconds.
+     * @param userSet true if this is an end-user set minimum
+     */
+    void setMinimumFrameInterval(int millis, boolean userSet);
+
+    /**
+     * Called to instruct the component instance to start rendering now.
+     */
+    void start();
+
+    /**
+     * Called to instruct the component instance to stop and suspend its state.
+     * The renderer should stop at this point.
+     */
+    void stop();
+
+    /**
+     * Called to instruct the component instance to destroy itself and any
+     * used resources. It will not be used again.
+     */
+    void destroy();
+}
diff --git a/src/java/org/web3d/browser/InvalidConfigurationException.java b/src/java/org/web3d/browser/InvalidConfigurationException.java
index d51a13bae9d1a9718452240551a6b86ad4fca284..81e3b8aab9022eb1c08bde12ec650800412c196e 100644
--- a/src/java/org/web3d/browser/InvalidConfigurationException.java
+++ b/src/java/org/web3d/browser/InvalidConfigurationException.java
@@ -1,37 +1,37 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001-2005
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.browser;
-
-/**
- * Xj3D has failed to start due to a configuration error.  This is a fatal
- * condition.
- *
- * @author Alan Hudson
- * @version $Revision: 1.2 $
- */
-public class InvalidConfigurationException extends RuntimeException {
-    /**
-     * Create a default exception that does not contain a message.
-     */
-    public InvalidConfigurationException() {
-    }
-
-    /**
-     * Create an exception that contains the given message.
-     *
-     * @param msg The message to associate
-     */
-    public InvalidConfigurationException(String msg) {
-        super(msg);
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001-2005
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.browser;
+
+/**
+ * Xj3D has failed to start due to a configuration error.  This is a fatal
+ * condition.
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.2 $
+ */
+public class InvalidConfigurationException extends RuntimeException {
+    /**
+     * Create a default exception that does not contain a message.
+     */
+    public InvalidConfigurationException() {
+    }
+
+    /**
+     * Create an exception that contains the given message.
+     *
+     * @param msg The message to associate
+     */
+    public InvalidConfigurationException(String msg) {
+        super(msg);
+    }
+}
diff --git a/src/java/org/web3d/browser/NavigationStateListener.java b/src/java/org/web3d/browser/NavigationStateListener.java
index 596c982636a5bfb4bbf85bdea57f0bec0b68276c..4a73ed07bb9d65f9a098aca366e8152a460ba99a 100644
--- a/src/java/org/web3d/browser/NavigationStateListener.java
+++ b/src/java/org/web3d/browser/NavigationStateListener.java
@@ -21,6 +21,7 @@ package org.web3d.browser;
 /**
  * A listener interface used to communicate changes in the navigation state
  * from one handler to another.
+ * <p>
  *
  * @author Justin Couch, Alan Hudson
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/browser/ScreenCaptureListener.java b/src/java/org/web3d/browser/ScreenCaptureListener.java
index d9efe75e132d79e9b9e25603d1f443f50486ad60..f35a5ababdcbc3313d2e670e563987d8f4f170b1 100644
--- a/src/java/org/web3d/browser/ScreenCaptureListener.java
+++ b/src/java/org/web3d/browser/ScreenCaptureListener.java
@@ -1,38 +1,39 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.browser;
-
-// External imports
-import java.nio.Buffer;
-
-// Local imports
-// None
-
-/**
- * Notification of Screen captures.
- *
- * @author Alan Hudson
- * @version $Revision: 1.1 $
- */
-public interface ScreenCaptureListener {
-
-    /**
-     * Notification of a new screen capture.  This will be in openGL pixel
-     * order.
-     *
-     * @param buffer The screen capture
-     * @param width The width in pixels of the captured screen
-     * @param height The height in pixels of the captured screen
-     */
-    void screenCaptured(Buffer buffer, int width, int height);
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.browser;
+
+// External imports
+import java.nio.Buffer;
+
+// Local imports
+// None
+
+/**
+ * Notification of Screen captures.
+ * <p>
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.1 $
+ */
+public interface ScreenCaptureListener {
+
+    /**
+     * Notification of a new screen capture.  This will be in openGL pixel
+     * order.
+     *
+     * @param buffer The screen capture
+     * @param width The width in pixels of the captured screen
+     * @param height The height in pixels of the captured screen
+     */
+    void screenCaptured(Buffer buffer, int width, int height);
+}
diff --git a/src/java/org/web3d/browser/Xj3DConstants.java b/src/java/org/web3d/browser/Xj3DConstants.java
index d0a241d5f51fb56ad1e893f09446995354330cf2..18aa9d068f2829f034ab319f5ef838a62bc8020d 100644
--- a/src/java/org/web3d/browser/Xj3DConstants.java
+++ b/src/java/org/web3d/browser/Xj3DConstants.java
@@ -1,116 +1,116 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2006 - 2007
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.browser;
-
-// External imports
-// None
-
-// Local imports
-import org.xj3d.sai.Xj3DBrowser;
-
-/**
- * Collection of constants used across the browser internals.
- *
- *
- * @author Alan Hudson, Justin Couch
- * @version $Revision: 1.19 $
- */
-public interface Xj3DConstants {
-    
-    /**
-     * The release version. Milestone format will be
-     * <code>M<i>MainVersion</i>_<i>DevRelease#</i></code>
-     */
-    String VERSION = "2-0_RC1";
-
-    /** Definition of the Java3D renderer */
-    int JAVA3D_RENDERER = 1;
-
-    /** ID String of the Java3D renderer */
-    String JAVA3D_ID = "java3d";
-
-    /** Definition of the null renderer */
-    int NULL_RENDERER = 2;
-
-    /** ID String of the null renderer */
-    String NULL_ID = "norender";
-
-    /** Definition of the OpenGL immersive renderer */
-    int OPENGL_RENDERER = 3;
-
-    /** ID String of the OpenGL renderer */
-    String OPENGL_ID = "aviatrix3d";
-
-    /** Definition of the OpenGL mobile device renderer */
-    int MOBILE_RENDERER = 4;
-
-    /** ID String of the mobile renderer */
-    String MOBILE_ID = "mobile";
-
-    /** ID String of the AWT ui toolkit */
-    String AWT_ID = "awt";
-
-    /** ID String of the SWT ui toolkit */
-    String SWT_ID = "swt";
-
-    /** The rendering style uses point mode */
-    int RENDER_POINTS = Xj3DBrowser.RENDER_POINTS;
-
-    /** The rendering style uses wireframe mode */
-    int RENDER_LINES = Xj3DBrowser.RENDER_LINES;
-
-    /** The rendering style uses flat shading mode */
-    int RENDER_FLAT = Xj3DBrowser.RENDER_FLAT;
-
-    /** The rendering style uses a generic shading model */
-    int RENDER_SHADED = Xj3DBrowser.RENDER_SHADED;
-
-    /** Nav mode string representing the None mode */
-    String NONE_NAV_MODE = "NONE";
-
-    /** Nav mode string representing the Any mode */
-    String ANY_NAV_MODE = "ANY";
-
-    /** Nav mode string representing the Fly mode */
-    String FLY_NAV_MODE = "FLY";
-
-    /** Nav mode string representing the Walk mode */
-    String WALK_NAV_MODE = "WALK";
-
-    /** Nav mode string representing the Examine mode */
-    String EXAMINE_NAV_MODE = "EXAMINE";
-
-    /** Nav mode string representing the Orbit mode */
-    String ORBIT_NAV_MODE = "ORBIT";
-
-    /** Nav mode string representing the LookAt mode */
-    String LOOKAT_NAV_MODE = "LOOKAT";
-
-    /** Nav mode string representing the Pan mode */
-    String PAN_NAV_MODE = "xj3d_PAN";
-
-    /** Nav mode string representing the Tilt mode */
-    String TILT_NAV_MODE = "xj3d_TILT";
-
-    /** Nav mode string representing the Inspect mode */
-    String INSPECT_NAV_MODE = "xj3d_INSPECT";
-
-    /** Nav mode string representing the tracking Examine mode */
-    String TRACK_EXAMINE_NAV_MODE = "xj3d_TRACK_EXAMINE";
-
-    /** Nav mode string representing the tracking Pan mode */
-    String TRACK_PAN_NAV_MODE = "xj3d_TRACK_PAN";
-
-    /** Nav mode string representing the Fly Level */
-    String FLY_LEVEL_NAV_MODE = "xj3d_FLY_LEVEL";
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2006 - 2007
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.browser;
+
+// External imports
+// None
+
+// Local imports
+import org.xj3d.sai.Xj3DBrowser;
+
+/**
+ * Collection of constants used across the browser internals.
+ *
+ *
+ * @author Alan Hudson, Justin Couch
+ * @version $Revision: 1.19 $
+ */
+public interface Xj3DConstants {
+    
+    /**
+     * The release version. Milestone format will be
+     * <code>M<i>MainVersion</i>_<i>DevRelease#</i></code>
+     */
+    String VERSION = "2-0_RC1";
+
+    /** Definition of the Java3D renderer */
+    int JAVA3D_RENDERER = 1;
+
+    /** ID String of the Java3D renderer */
+    String JAVA3D_ID = "java3d";
+
+    /** Definition of the null renderer */
+    int NULL_RENDERER = 2;
+
+    /** ID String of the null renderer */
+    String NULL_ID = "norender";
+
+    /** Definition of the OpenGL immersive renderer */
+    int OPENGL_RENDERER = 3;
+
+    /** ID String of the OpenGL renderer */
+    String OPENGL_ID = "aviatrix3d";
+
+    /** Definition of the OpenGL mobile device renderer */
+    int MOBILE_RENDERER = 4;
+
+    /** ID String of the mobile renderer */
+    String MOBILE_ID = "mobile";
+
+    /** ID String of the AWT ui toolkit */
+    String AWT_ID = "awt";
+
+    /** ID String of the SWT ui toolkit */
+    String SWT_ID = "swt";
+
+    /** The rendering style uses point mode */
+    int RENDER_POINTS = Xj3DBrowser.RENDER_POINTS;
+
+    /** The rendering style uses wireframe mode */
+    int RENDER_LINES = Xj3DBrowser.RENDER_LINES;
+
+    /** The rendering style uses flat shading mode */
+    int RENDER_FLAT = Xj3DBrowser.RENDER_FLAT;
+
+    /** The rendering style uses a generic shading model */
+    int RENDER_SHADED = Xj3DBrowser.RENDER_SHADED;
+
+    /** Nav mode string representing the None mode */
+    String NONE_NAV_MODE = "NONE";
+
+    /** Nav mode string representing the Any mode */
+    String ANY_NAV_MODE = "ANY";
+
+    /** Nav mode string representing the Fly mode */
+    String FLY_NAV_MODE = "FLY";
+
+    /** Nav mode string representing the Walk mode */
+    String WALK_NAV_MODE = "WALK";
+
+    /** Nav mode string representing the Examine mode */
+    String EXAMINE_NAV_MODE = "EXAMINE";
+
+    /** Nav mode string representing the Orbit mode */
+    String ORBIT_NAV_MODE = "ORBIT";
+
+    /** Nav mode string representing the LookAt mode */
+    String LOOKAT_NAV_MODE = "LOOKAT";
+
+    /** Nav mode string representing the Pan mode */
+    String PAN_NAV_MODE = "xj3d_PAN";
+
+    /** Nav mode string representing the Tilt mode */
+    String TILT_NAV_MODE = "xj3d_TILT";
+
+    /** Nav mode string representing the Inspect mode */
+    String INSPECT_NAV_MODE = "xj3d_INSPECT";
+
+    /** Nav mode string representing the tracking Examine mode */
+    String TRACK_EXAMINE_NAV_MODE = "xj3d_TRACK_EXAMINE";
+
+    /** Nav mode string representing the tracking Pan mode */
+    String TRACK_PAN_NAV_MODE = "xj3d_TRACK_PAN";
+
+    /** Nav mode string representing the Fly Level */
+    String FLY_LEVEL_NAV_MODE = "xj3d_FLY_LEVEL";
+}
diff --git a/src/java/org/web3d/image/AreaAveragingScaleFilter.java b/src/java/org/web3d/image/AreaAveragingScaleFilter.java
index 7a85755bba0edd73b3d52fde498f853d5e4a2019..199a0dc4e74202d632834a4cf1f32076b6a56799 100644
--- a/src/java/org/web3d/image/AreaAveragingScaleFilter.java
+++ b/src/java/org/web3d/image/AreaAveragingScaleFilter.java
@@ -1,699 +1,699 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2007
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.image;
-
-// External imports
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-// Local imports
-// none
-
-/**
- * A ScaleFilter implementation for scaling NIOBufferImages using area averaging.
- *
- * @author Rex Melton
- * @version $Revision: 1.3 $
- */
-public class AreaAveragingScaleFilter implements ScaleFilter {
-
-    /** The width of the source image. */
-    private int srcWidth;
-
-    /** The height of the source image. */
-    private int srcHeight;
-
-    /** The source image type */
-    private NIOBufferImageType srcType;
-
-    /** Flag indicating that the image data should be treated as
-     *  grayscale, regardless of whether it has more than 2 components.
-     *  Used to compensate for 'deficiencies' in 2 component image
-     *  handling
-     */
-    private boolean srcIsGrayScale;
-
-    /** The number of components in the source image */
-    private int srcCmp;
-
-    /** The image buffer */
-    private ByteBuffer srcBuffer;
-
-    /** Constructor for the scale filter class object */
-    private static Constructor scale_filter_constructor;
-
-    /** Method within the scale filter class for generating the scaled image */
-    private static Method scale_image_method;
-
-    /** Flag indicating that native acceleration is available */
-    private static boolean hasNativeLib;
-
-    /** Scratch arrays for computing target pixel data */
-    private float red[], green[], blue[], alpha[];
-
-    /** precomputed pixel count of image */
-    private float srcPixelCount;
-
-    // static constructor
-    static {
-        Class<?> scale_filter_class;
-        try {
-            // get the class
-            scale_filter_class = Class.forName( "vlc.image.ImageScaleFilter" );
-
-            // get the class's constructor with the appropriate arguments
-            scale_filter_constructor = scale_filter_class.getConstructor( new Class<?>[]{
-                    String.class } );
-
-            // get the scalor method
-            scale_image_method = scale_filter_class.getMethod( "getScaledImage", new Class<?>[]{
-                    int.class,			// srcWidth
-                    int.class,			// srcHeight
-                    int.class,			// srcCmp
-                    ByteBuffer.class,           // srcBuffer
-                    int.class,			// dstWidth
-                    int.class,			// dstHeight
-                } );
-
-            // node-ify that we'll be going native
-            hasNativeLib = true;
-        }
-        catch ( ClassNotFoundException | NoSuchMethodException | SecurityException e ) {
-            //System.err.println( "Exception: "+ e.getMessage( ) );
-        }
-    }
-
-    /**
-     * Constructor
-     *
-     * @param image The source image that will be rescaled
-     */
-    public AreaAveragingScaleFilter( NIOBufferImage image ) {
-        if ( image == null ) {
-            throw new NullPointerException( "AreaAveragingScaleFilter: Argument image must be non-null" );
-        }
-        srcWidth = image.getWidth( );
-        srcHeight = image.getHeight( );
-        srcType = image.getType( );
-        srcCmp = srcType.size;
-        srcIsGrayScale = image.isGrayScale( );
-        srcBuffer = image.getBuffer( );
-        srcPixelCount = ((float)srcWidth) * srcHeight;
-    }
-
-    //----------------------------------------------------------
-    // Method defined by ScaleFilter
-    //----------------------------------------------------------
-
-    /**
-     * Return an image scaled to the specified width and height
-     *
-     * @param dstWidth The width of the returned image
-     * @param dstHeight The height of the returned image
-     * @return The scaled image
-     */
-    @Override
-    public NIOBufferImage getScaledImage( int dstWidth, int dstHeight ) {
-        NIOBufferImage dstImage = null;
-        if ( hasNativeLib ) {
-            // use the native version of this filter
-            try {
-                // instantiate the object
-                Object object = scale_filter_constructor.newInstance( new Object[]{
-                        "AreaAverage" } );
-
-                // invoke the scalor method to generate the buffer
-                ByteBuffer dstBuffer = (ByteBuffer)scale_image_method.invoke( object, new Object[]{
-                        srcWidth,
-                        srcHeight,
-                        srcCmp,
-                        srcBuffer,
-                        dstWidth,
-                        dstHeight,
-                    } );
-
-                // create the new image
-                dstImage = new NIOBufferImage(
-                    dstWidth,
-                    dstHeight,
-                    srcType,
-                    srcIsGrayScale,
-                    dstBuffer );
-
-            } catch ( InstantiationException | InvocationTargetException | IllegalAccessException e ) {
-                //System.out.println( "IllegalAccessException: "+ iae.getMessage( ) );
-            }
-        } else {
-            // no native version of this filter is available, fallback to Java impl
-            ByteBuffer dstBuffer = ByteBuffer.allocateDirect( dstWidth * dstHeight * srcCmp );
-            dstBuffer.order( ByteOrder.nativeOrder( ) );
-
-            srcBuffer.rewind( );
-
-            switch( srcCmp ) {
-            case 4:
-                fillFourCompBuffer( dstWidth, dstHeight, srcBuffer, dstBuffer );
-                break;
-            case 3:
-                fillThreeCompBuffer( dstWidth, dstHeight, srcBuffer, dstBuffer );
-                break;
-            case 2:
-                fillTwoCompBuffer( dstWidth, dstHeight, srcBuffer, dstBuffer );
-                break;
-            case 1:
-                fillOneCompBuffer( dstWidth, dstHeight, srcBuffer, dstBuffer );
-                break;
-
-            }
-
-            dstImage = new NIOBufferImage(
-                dstWidth,
-                dstHeight,
-                srcType,
-                srcIsGrayScale,
-                dstBuffer );
-        }
-
-        return( dstImage );
-    }
-
-    //----------------------------------------------------------
-    // Local Methods
-    //----------------------------------------------------------
-
-    /**
-     * Initialize the destination byte buffer with image data scaled to the
-     * width and height specified from the source byte buffer.
-     *
-     * @param destWidth The width of the destination image
-     * @param destHeight The height of the destination image
-     * @param srcBuffer The image source data
-     * @param destBuffer The buffer to initialize with the scaled image data
-     */
-    private void fillFourCompBuffer(
-        int destWidth,
-        int destHeight,
-        ByteBuffer srcBuffer,
-        ByteBuffer destBuffer ) {
-
-        red = new float[destWidth];
-        green = new float[destWidth];
-        blue = new float[destWidth];
-        alpha = new float[destWidth];
-
-        byte[] row_data = new byte[destWidth*srcCmp];
-
-        int sy = 0;
-        int syrem = destHeight;
-        int dy = 0;
-        int dyrem = 0;
-
-        int srcRowByteOffset = 0;
-
-        while ( sy < srcHeight ) {
-            int amty;
-            if ( dyrem == 0 ) {
-                for ( int i = 0; i < destWidth; i++ ) {
-                    alpha[i] = red[i] = green[i] = blue[i] = 0f;
-                }
-                dyrem = srcHeight;
-            }
-            if ( syrem < dyrem ) {
-                amty = syrem;
-            } else {
-                amty = dyrem;
-            }
-            int sx = 0;
-            int dx = 0;
-            int sxrem = 0;
-            int dxrem = srcWidth;
-            float a = 0f, r = 0f, g = 0f, b = 0f;
-            while ( sx < srcWidth ) {
-                if ( sxrem == 0 ) {
-                    sxrem = destWidth;
-                    int srcColByteOffset = sx * srcCmp;
-                    r = 0xff & srcBuffer.get( srcRowByteOffset + srcColByteOffset++ );
-                    g = 0xff & srcBuffer.get( srcRowByteOffset + srcColByteOffset++ );
-                    b = 0xff & srcBuffer.get( srcRowByteOffset + srcColByteOffset++ );
-                    a = 0xff & srcBuffer.get( srcRowByteOffset + srcColByteOffset );
-                    // premultiply the components if necessary
-                    if ( a != 255.0f ) {
-                        float ascale = a / 255.0f;
-                        r *= ascale;
-                        g *= ascale;
-                        b *= ascale;
-                    }
-                }
-                int amtx;
-                if ( sxrem < dxrem ) {
-                    amtx = sxrem;
-                } else {
-                    amtx = dxrem;
-                }
-                float mult = ((float)amtx) * amty;
-                alpha[dx] += mult * a;
-                red[dx] += mult * r;
-                green[dx] += mult * g;
-                blue[dx] += mult * b;
-                if ( ( sxrem -= amtx ) == 0 ) {
-                    sx++;
-                }
-                if ( ( dxrem -= amtx ) == 0 ) {
-                    dx++;
-                    dxrem = srcWidth;
-                }
-            }
-            if ( ( dyrem -= amty ) == 0 ) {
-                process4CompRow( destWidth, row_data );
-                do {
-                    destBuffer.put( row_data );
-                    dy++;
-                } while ( ( ( syrem -= amty ) >= amty ) && ( amty == srcHeight ) );
-            } else {
-                syrem -= amty;
-            }
-            if ( syrem == 0 ) {
-                syrem = destHeight;
-                sy++;
-                srcRowByteOffset += srcWidth * srcCmp;
-            }
-        }
-    }
-
-    /**
-     * Initialize the image data for a destination row.
-     *
-     * @param width The width of the target image row
-     * @param row_data The byte array to initialize with image data
-     */
-    private void process4CompRow( int width, byte[] row_data ) {
-        int index = 0;
-        for ( int x = 0; x < width; x++ ) {
-            float mult = srcPixelCount;
-            int a = Math.round( alpha[x] / mult );
-            if ( a <= 0 ) {
-                a = 0;
-            } else if ( a >= 255 ) {
-                a = 255;
-            } else {
-                // un-premultiply the components (by modifying mult here, we
-                // are effectively doing the divide by mult and divide by
-                // alpha in the same step)
-                mult = alpha[x] / 255;
-            }
-            int r = Math.round( red[x] / mult );
-            int g = Math.round( green[x] / mult );
-            int b = Math.round( blue[x] / mult );
-
-            if ( r < 0 ) {
-                r = 0;
-            } else if ( r > 255 ) {
-                r = 255;
-            }
-            if ( g < 0 ) {
-                g = 0;
-            } else if ( g > 255 ) {
-                g = 255;
-            }
-            if ( b < 0 ) {
-                b = 0;
-            } else if ( b > 255 ) {
-                b = 255;
-            }
-
-            row_data[index++] = (byte)r;
-            row_data[index++] = (byte)g;
-            row_data[index++] = (byte)b;
-            row_data[index++] = (byte)a;
-        }
-    }
-
-    /**
-     * Initialize the destination byte buffer with image data scaled to the
-     * width and height specified from the source byte buffer.
-     *
-     * @param destWidth The width of the destination image
-     * @param destHeight The height of the destination image
-     * @param srcBuffer The image source data
-     * @param destBuffer The buffer to initialize with the scaled image data
-     */
-    private void fillThreeCompBuffer(
-        int destWidth,
-        int destHeight,
-        ByteBuffer srcBuffer,
-        ByteBuffer destBuffer ) {
-
-        red = new float[destWidth];
-        green = new float[destWidth];
-        blue = new float[destWidth];
-
-        byte[] row_data = new byte[destWidth*srcCmp];
-
-        int sy = 0;
-        int syrem = destHeight;
-        int dy = 0;
-        int dyrem = 0;
-
-        int srcRowByteOffset = 0;
-
-        while ( sy < srcHeight ) {
-            int amty;
-            if ( dyrem == 0 ) {
-                for ( int i = 0; i < destWidth; i++ ) {
-                    red[i] = green[i] = blue[i] = 0f;
-                }
-                dyrem = srcHeight;
-            }
-            if ( syrem < dyrem ) {
-                amty = syrem;
-            } else {
-                amty = dyrem;
-            }
-            int sx = 0;
-            int dx = 0;
-            int sxrem = 0;
-            int dxrem = srcWidth;
-            float r = 0f, g = 0f, b = 0f;
-            while ( sx < srcWidth ) {
-                if ( sxrem == 0 ) {
-                    sxrem = destWidth;
-                    int srcColByteOffset = sx * srcCmp;
-                    r = 0xff & srcBuffer.get( srcRowByteOffset + srcColByteOffset++ );
-                    g = 0xff & srcBuffer.get( srcRowByteOffset + srcColByteOffset++ );
-                    b = 0xff & srcBuffer.get( srcRowByteOffset + srcColByteOffset );
-                }
-                int amtx;
-                if ( sxrem < dxrem ) {
-                    amtx = sxrem;
-                } else {
-                    amtx = dxrem;
-                }
-                float mult = ((float)amtx) * amty;
-                red[dx] += mult * r;
-                green[dx] += mult * g;
-                blue[dx] += mult * b;
-                if ( ( sxrem -= amtx ) == 0 ) {
-                    sx++;
-                }
-                if ( ( dxrem -= amtx ) == 0 ) {
-                    dx++;
-                    dxrem = srcWidth;
-                }
-            }
-            if ( ( dyrem -= amty ) == 0 ) {
-                process3CompRow( destWidth, row_data );
-                do {
-                    destBuffer.put( row_data );
-                    dy++;
-                } while ( ( ( syrem -= amty ) >= amty ) && ( amty == srcHeight ) );
-            } else {
-                syrem -= amty;
-            }
-            if ( syrem == 0 ) {
-                syrem = destHeight;
-                sy++;
-                srcRowByteOffset += srcWidth * srcCmp;
-            }
-        }
-    }
-
-    /**
-     * Initialize the image data for a destination row.
-     *
-     * @param width The width of the target image row
-     * @param row_data The byte array to initialize with image data
-     */
-    private void process3CompRow( int width, byte[] row_data ) {
-        int index = 0;
-        for ( int x = 0; x < width; x++ ) {
-            float mult = srcPixelCount;
-            int r = Math.round( red[x] / mult );
-            int g = Math.round( green[x] / mult );
-            int b = Math.round( blue[x] / mult );
-
-            if ( r < 0 ) {
-                r = 0;
-            } else if ( r > 255 ) {
-                r = 255;
-            }
-            if ( g < 0 ) {
-                g = 0;
-            } else if ( g > 255 ) {
-                g = 255;
-            }
-            if ( b < 0 ) {
-                b = 0;
-            } else if ( b > 255 ) {
-                b = 255;
-            }
-
-            row_data[index++] = (byte)r;
-            row_data[index++] = (byte)g;
-            row_data[index++] = (byte)b;
-        }
-    }
-
-    /**
-     * Initialize the destination byte buffer with image data scaled to the
-     * width and height specified from the source byte buffer.
-     *
-     * @param destWidth The width of the destination image
-     * @param destHeight The height of the destination image
-     * @param srcBuffer The image source data
-     * @param destBuffer The buffer to initialize with the scaled image data
-     */
-    private void fillTwoCompBuffer(
-        int destWidth,
-        int destHeight,
-        ByteBuffer srcBuffer,
-        ByteBuffer destBuffer ) {
-
-        red = new float[destWidth];
-        alpha = new float[destWidth];
-
-        byte[] row_data = new byte[destWidth*srcCmp];
-
-        int sy = 0;
-        int syrem = destHeight;
-        int dy = 0;
-        int dyrem = 0;
-
-        int srcRowByteOffset = 0;
-
-        while ( sy < srcHeight ) {
-            int amty;
-            if ( dyrem == 0 ) {
-                for ( int i = 0; i < destWidth; i++ ) {
-                    alpha[i] = red[i] = 0f;
-                }
-                dyrem = srcHeight;
-            }
-            if ( syrem < dyrem ) {
-                amty = syrem;
-            } else {
-                amty = dyrem;
-            }
-            int sx = 0;
-            int dx = 0;
-            int sxrem = 0;
-            int dxrem = srcWidth;
-            float a = 0f, r = 0f;
-            while ( sx < srcWidth ) {
-                if ( sxrem == 0 ) {
-                    sxrem = destWidth;
-                    int srcColByteOffset = sx * srcCmp;
-                    r = 0xff & srcBuffer.get( srcRowByteOffset + srcColByteOffset++ );
-                    a = 0xff & srcBuffer.get( srcRowByteOffset + srcColByteOffset );
-                    // premultiply the components if necessary
-                    if ( a != 255.0f ) {
-                        float ascale = a / 255.0f;
-                        r *= ascale;
-                    }
-                }
-                int amtx;
-                if ( sxrem < dxrem ) {
-                    amtx = sxrem;
-                } else {
-                    amtx = dxrem;
-                }
-                float mult = ((float)amtx) * amty;
-                alpha[dx] += mult * a;
-                red[dx] += mult * r;
-                if ( ( sxrem -= amtx ) == 0 ) {
-                    sx++;
-                }
-                if ( ( dxrem -= amtx ) == 0 ) {
-                    dx++;
-                    dxrem = srcWidth;
-                }
-            }
-            if ( ( dyrem -= amty ) == 0 ) {
-                process2CompRow( destWidth, row_data );
-                do {
-                    destBuffer.put( row_data );
-                    dy++;
-                } while ( ( ( syrem -= amty ) >= amty ) && ( amty == srcHeight ) );
-            } else {
-                syrem -= amty;
-            }
-            if ( syrem == 0 ) {
-                syrem = destHeight;
-                sy++;
-                srcRowByteOffset += srcWidth * srcCmp;
-            }
-        }
-    }
-
-    /**
-     * Initialize the image data for a destination row.
-     *
-     * @param width The width of the target image row
-     * @param row_data The byte array to initialize with image data
-     */
-    private void process2CompRow( int width, byte[] row_data ) {
-        int index = 0;
-        for ( int x = 0; x < width; x++ ) {
-            float mult = srcPixelCount;
-            int a = Math.round( alpha[x] / mult );
-            if ( a <= 0 ) {
-                a = 0;
-            } else if ( a >= 255 ) {
-                a = 255;
-            } else {
-                // un-premultiply the components (by modifying mult here, we
-                // are effectively doing the divide by mult and divide by
-                // alpha in the same step)
-                mult = alpha[x] / 255;
-            }
-            int r = Math.round( red[x] / mult );
-
-            if ( r < 0 ) {
-                r = 0;
-            } else if ( r > 255 ) {
-                r = 255;
-            }
-
-            row_data[index++] = (byte)r;
-            row_data[index++] = (byte)a;
-        }
-    }
-
-    /**
-     * Initialize the destination byte buffer with image data scaled to the
-     * width and height specified from the source byte buffer.
-     *
-     * @param destWidth The width of the destination image
-     * @param destHeight The height of the destination image
-     * @param srcBuffer The image source data
-     * @param destBuffer The buffer to initialize with the scaled image data
-     */
-    private void fillOneCompBuffer(
-        int destWidth,
-        int destHeight,
-        ByteBuffer srcBuffer,
-        ByteBuffer destBuffer ) {
-
-        red = new float[destWidth];
-
-        byte[] row_data = new byte[destWidth*srcCmp];
-
-        int sy = 0;
-        int syrem = destHeight;
-        int dy = 0;
-        int dyrem = 0;
-
-        int srcRowByteOffset = 0;
-
-        while ( sy < srcHeight ) {
-            int amty;
-            if ( dyrem == 0 ) {
-                for ( int i = 0; i < destWidth; i++ ) {
-                    red[i] = 0f;
-                }
-                dyrem = srcHeight;
-            }
-            if ( syrem < dyrem ) {
-                amty = syrem;
-            } else {
-                amty = dyrem;
-            }
-            int sx = 0;
-            int dx = 0;
-            int sxrem = 0;
-            int dxrem = srcWidth;
-            float r = 0f;
-            while ( sx < srcWidth ) {
-                if ( sxrem == 0 ) {
-                    sxrem = destWidth;
-                    int srcColByteOffset = sx * srcCmp;
-                    r = 0xff & srcBuffer.get( srcRowByteOffset + srcColByteOffset );
-                }
-                int amtx;
-                if ( sxrem < dxrem ) {
-                    amtx = sxrem;
-                } else {
-                    amtx = dxrem;
-                }
-                float mult = ((float)amtx) * amty;
-                red[dx] += mult * r;
-                if ( ( sxrem -= amtx ) == 0 ) {
-                    sx++;
-                }
-                if ( ( dxrem -= amtx ) == 0 ) {
-                    dx++;
-                    dxrem = srcWidth;
-                }
-            }
-            if ( ( dyrem -= amty ) == 0 ) {
-                process1CompRow( destWidth, row_data );
-                do {
-                    destBuffer.put( row_data );
-                    dy++;
-                } while ( ( ( syrem -= amty ) >= amty ) && ( amty == srcHeight ) );
-            } else {
-                syrem -= amty;
-            }
-            if ( syrem == 0 ) {
-                syrem = destHeight;
-                sy++;
-                srcRowByteOffset += srcWidth * srcCmp;
-            }
-        }
-    }
-
-    /**
-     * Initialize the image data for a destination row.
-     *
-     * @param width The width of the target image row
-     * @param row_data The byte array to initialize with image data
-     */
-    private void process1CompRow( int width, byte[] row_data ) {
-        int index = 0;
-        for ( int x = 0; x < width; x++ ) {
-            float mult = srcPixelCount;
-            int r = Math.round( red[x] / mult );
-
-            if ( r < 0 ) {
-                r = 0;
-            } else if ( r > 255 ) {
-                r = 255;
-            }
-
-            row_data[index++] = (byte)r;
-        }
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2007
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.image;
+
+// External imports
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+// Local imports
+// none
+
+/**
+ * A ScaleFilter implementation for scaling NIOBufferImages using area averaging.
+ *
+ * @author Rex Melton
+ * @version $Revision: 1.3 $
+ */
+public class AreaAveragingScaleFilter implements ScaleFilter {
+
+    /** The width of the source image. */
+    private int srcWidth;
+
+    /** The height of the source image. */
+    private int srcHeight;
+
+    /** The source image type */
+    private NIOBufferImageType srcType;
+
+    /** Flag indicating that the image data should be treated as
+     *  grayscale, regardless of whether it has more than 2 components.
+     *  Used to compensate for 'deficiencies' in 2 component image
+     *  handling
+     */
+    private boolean srcIsGrayScale;
+
+    /** The number of components in the source image */
+    private int srcCmp;
+
+    /** The image buffer */
+    private ByteBuffer srcBuffer;
+
+    /** Constructor for the scale filter class object */
+    private static Constructor scale_filter_constructor;
+
+    /** Method within the scale filter class for generating the scaled image */
+    private static Method scale_image_method;
+
+    /** Flag indicating that native acceleration is available */
+    private static boolean hasNativeLib;
+
+    /** Scratch arrays for computing target pixel data */
+    private float red[], green[], blue[], alpha[];
+
+    /** precomputed pixel count of image */
+    private float srcPixelCount;
+
+    // static constructor
+    static {
+        Class<?> scale_filter_class;
+        try {
+            // get the class
+            scale_filter_class = Class.forName( "vlc.image.ImageScaleFilter" );
+
+            // get the class's constructor with the appropriate arguments
+            scale_filter_constructor = scale_filter_class.getConstructor( new Class<?>[]{
+                    String.class } );
+
+            // get the scalor method
+            scale_image_method = scale_filter_class.getMethod( "getScaledImage", new Class<?>[]{
+                    int.class,			// srcWidth
+                    int.class,			// srcHeight
+                    int.class,			// srcCmp
+                    ByteBuffer.class,           // srcBuffer
+                    int.class,			// dstWidth
+                    int.class,			// dstHeight
+                } );
+
+            // node-ify that we'll be going native
+            hasNativeLib = true;
+        }
+        catch ( ClassNotFoundException | NoSuchMethodException | SecurityException e ) {
+            //System.err.println( "Exception: "+ e.getMessage( ) );
+        }
+    }
+
+    /**
+     * Constructor
+     *
+     * @param image The source image that will be rescaled
+     */
+    public AreaAveragingScaleFilter( NIOBufferImage image ) {
+        if ( image == null ) {
+            throw new NullPointerException( "AreaAveragingScaleFilter: Argument image must be non-null" );
+        }
+        srcWidth = image.getWidth( );
+        srcHeight = image.getHeight( );
+        srcType = image.getType( );
+        srcCmp = srcType.size;
+        srcIsGrayScale = image.isGrayScale( );
+        srcBuffer = image.getBuffer( );
+        srcPixelCount = ((float)srcWidth) * srcHeight;
+    }
+
+    //----------------------------------------------------------
+    // Method defined by ScaleFilter
+    //----------------------------------------------------------
+
+    /**
+     * Return an image scaled to the specified width and height
+     *
+     * @param dstWidth The width of the returned image
+     * @param dstHeight The height of the returned image
+     * @return The scaled image
+     */
+    @Override
+    public NIOBufferImage getScaledImage( int dstWidth, int dstHeight ) {
+        NIOBufferImage dstImage = null;
+        if ( hasNativeLib ) {
+            // use the native version of this filter
+            try {
+                // instantiate the object
+                Object object = scale_filter_constructor.newInstance( new Object[]{
+                        "AreaAverage" } );
+
+                // invoke the scalor method to generate the buffer
+                ByteBuffer dstBuffer = (ByteBuffer)scale_image_method.invoke( object, new Object[]{
+                        srcWidth,
+                        srcHeight,
+                        srcCmp,
+                        srcBuffer,
+                        dstWidth,
+                        dstHeight,
+                    } );
+
+                // create the new image
+                dstImage = new NIOBufferImage(
+                    dstWidth,
+                    dstHeight,
+                    srcType,
+                    srcIsGrayScale,
+                    dstBuffer );
+
+            } catch ( InstantiationException | InvocationTargetException | IllegalAccessException e ) {
+                //System.out.println( "IllegalAccessException: "+ iae.getMessage( ) );
+            }
+        } else {
+            // no native version of this filter is available, fallback to Java impl
+            ByteBuffer dstBuffer = ByteBuffer.allocateDirect( dstWidth * dstHeight * srcCmp );
+            dstBuffer.order( ByteOrder.nativeOrder( ) );
+
+            srcBuffer.rewind( );
+
+            switch( srcCmp ) {
+            case 4:
+                fillFourCompBuffer( dstWidth, dstHeight, srcBuffer, dstBuffer );
+                break;
+            case 3:
+                fillThreeCompBuffer( dstWidth, dstHeight, srcBuffer, dstBuffer );
+                break;
+            case 2:
+                fillTwoCompBuffer( dstWidth, dstHeight, srcBuffer, dstBuffer );
+                break;
+            case 1:
+                fillOneCompBuffer( dstWidth, dstHeight, srcBuffer, dstBuffer );
+                break;
+
+            }
+
+            dstImage = new NIOBufferImage(
+                dstWidth,
+                dstHeight,
+                srcType,
+                srcIsGrayScale,
+                dstBuffer );
+        }
+
+        return( dstImage );
+    }
+
+    //----------------------------------------------------------
+    // Local Methods
+    //----------------------------------------------------------
+
+    /**
+     * Initialize the destination byte buffer with image data scaled to the
+     * width and height specified from the source byte buffer.
+     *
+     * @param destWidth The width of the destination image
+     * @param destHeight The height of the destination image
+     * @param srcBuffer The image source data
+     * @param destBuffer The buffer to initialize with the scaled image data
+     */
+    private void fillFourCompBuffer(
+        int destWidth,
+        int destHeight,
+        ByteBuffer srcBuffer,
+        ByteBuffer destBuffer ) {
+
+        red = new float[destWidth];
+        green = new float[destWidth];
+        blue = new float[destWidth];
+        alpha = new float[destWidth];
+
+        byte[] row_data = new byte[destWidth*srcCmp];
+
+        int sy = 0;
+        int syrem = destHeight;
+        int dy = 0;
+        int dyrem = 0;
+
+        int srcRowByteOffset = 0;
+
+        while ( sy < srcHeight ) {
+            int amty;
+            if ( dyrem == 0 ) {
+                for ( int i = 0; i < destWidth; i++ ) {
+                    alpha[i] = red[i] = green[i] = blue[i] = 0f;
+                }
+                dyrem = srcHeight;
+            }
+            if ( syrem < dyrem ) {
+                amty = syrem;
+            } else {
+                amty = dyrem;
+            }
+            int sx = 0;
+            int dx = 0;
+            int sxrem = 0;
+            int dxrem = srcWidth;
+            float a = 0f, r = 0f, g = 0f, b = 0f;
+            while ( sx < srcWidth ) {
+                if ( sxrem == 0 ) {
+                    sxrem = destWidth;
+                    int srcColByteOffset = sx * srcCmp;
+                    r = 0xff & srcBuffer.get( srcRowByteOffset + srcColByteOffset++ );
+                    g = 0xff & srcBuffer.get( srcRowByteOffset + srcColByteOffset++ );
+                    b = 0xff & srcBuffer.get( srcRowByteOffset + srcColByteOffset++ );
+                    a = 0xff & srcBuffer.get( srcRowByteOffset + srcColByteOffset );
+                    // premultiply the components if necessary
+                    if ( a != 255.0f ) {
+                        float ascale = a / 255.0f;
+                        r *= ascale;
+                        g *= ascale;
+                        b *= ascale;
+                    }
+                }
+                int amtx;
+                if ( sxrem < dxrem ) {
+                    amtx = sxrem;
+                } else {
+                    amtx = dxrem;
+                }
+                float mult = ((float)amtx) * amty;
+                alpha[dx] += mult * a;
+                red[dx] += mult * r;
+                green[dx] += mult * g;
+                blue[dx] += mult * b;
+                if ( ( sxrem -= amtx ) == 0 ) {
+                    sx++;
+                }
+                if ( ( dxrem -= amtx ) == 0 ) {
+                    dx++;
+                    dxrem = srcWidth;
+                }
+            }
+            if ( ( dyrem -= amty ) == 0 ) {
+                process4CompRow( destWidth, row_data );
+                do {
+                    destBuffer.put( row_data );
+                    dy++;
+                } while ( ( ( syrem -= amty ) >= amty ) && ( amty == srcHeight ) );
+            } else {
+                syrem -= amty;
+            }
+            if ( syrem == 0 ) {
+                syrem = destHeight;
+                sy++;
+                srcRowByteOffset += srcWidth * srcCmp;
+            }
+        }
+    }
+
+    /**
+     * Initialize the image data for a destination row.
+     *
+     * @param width The width of the target image row
+     * @param row_data The byte array to initialize with image data
+     */
+    private void process4CompRow( int width, byte[] row_data ) {
+        int index = 0;
+        for ( int x = 0; x < width; x++ ) {
+            float mult = srcPixelCount;
+            int a = Math.round( alpha[x] / mult );
+            if ( a <= 0 ) {
+                a = 0;
+            } else if ( a >= 255 ) {
+                a = 255;
+            } else {
+                // un-premultiply the components (by modifying mult here, we
+                // are effectively doing the divide by mult and divide by
+                // alpha in the same step)
+                mult = alpha[x] / 255;
+            }
+            int r = Math.round( red[x] / mult );
+            int g = Math.round( green[x] / mult );
+            int b = Math.round( blue[x] / mult );
+
+            if ( r < 0 ) {
+                r = 0;
+            } else if ( r > 255 ) {
+                r = 255;
+            }
+            if ( g < 0 ) {
+                g = 0;
+            } else if ( g > 255 ) {
+                g = 255;
+            }
+            if ( b < 0 ) {
+                b = 0;
+            } else if ( b > 255 ) {
+                b = 255;
+            }
+
+            row_data[index++] = (byte)r;
+            row_data[index++] = (byte)g;
+            row_data[index++] = (byte)b;
+            row_data[index++] = (byte)a;
+        }
+    }
+
+    /**
+     * Initialize the destination byte buffer with image data scaled to the
+     * width and height specified from the source byte buffer.
+     *
+     * @param destWidth The width of the destination image
+     * @param destHeight The height of the destination image
+     * @param srcBuffer The image source data
+     * @param destBuffer The buffer to initialize with the scaled image data
+     */
+    private void fillThreeCompBuffer(
+        int destWidth,
+        int destHeight,
+        ByteBuffer srcBuffer,
+        ByteBuffer destBuffer ) {
+
+        red = new float[destWidth];
+        green = new float[destWidth];
+        blue = new float[destWidth];
+
+        byte[] row_data = new byte[destWidth*srcCmp];
+
+        int sy = 0;
+        int syrem = destHeight;
+        int dy = 0;
+        int dyrem = 0;
+
+        int srcRowByteOffset = 0;
+
+        while ( sy < srcHeight ) {
+            int amty;
+            if ( dyrem == 0 ) {
+                for ( int i = 0; i < destWidth; i++ ) {
+                    red[i] = green[i] = blue[i] = 0f;
+                }
+                dyrem = srcHeight;
+            }
+            if ( syrem < dyrem ) {
+                amty = syrem;
+            } else {
+                amty = dyrem;
+            }
+            int sx = 0;
+            int dx = 0;
+            int sxrem = 0;
+            int dxrem = srcWidth;
+            float r = 0f, g = 0f, b = 0f;
+            while ( sx < srcWidth ) {
+                if ( sxrem == 0 ) {
+                    sxrem = destWidth;
+                    int srcColByteOffset = sx * srcCmp;
+                    r = 0xff & srcBuffer.get( srcRowByteOffset + srcColByteOffset++ );
+                    g = 0xff & srcBuffer.get( srcRowByteOffset + srcColByteOffset++ );
+                    b = 0xff & srcBuffer.get( srcRowByteOffset + srcColByteOffset );
+                }
+                int amtx;
+                if ( sxrem < dxrem ) {
+                    amtx = sxrem;
+                } else {
+                    amtx = dxrem;
+                }
+                float mult = ((float)amtx) * amty;
+                red[dx] += mult * r;
+                green[dx] += mult * g;
+                blue[dx] += mult * b;
+                if ( ( sxrem -= amtx ) == 0 ) {
+                    sx++;
+                }
+                if ( ( dxrem -= amtx ) == 0 ) {
+                    dx++;
+                    dxrem = srcWidth;
+                }
+            }
+            if ( ( dyrem -= amty ) == 0 ) {
+                process3CompRow( destWidth, row_data );
+                do {
+                    destBuffer.put( row_data );
+                    dy++;
+                } while ( ( ( syrem -= amty ) >= amty ) && ( amty == srcHeight ) );
+            } else {
+                syrem -= amty;
+            }
+            if ( syrem == 0 ) {
+                syrem = destHeight;
+                sy++;
+                srcRowByteOffset += srcWidth * srcCmp;
+            }
+        }
+    }
+
+    /**
+     * Initialize the image data for a destination row.
+     *
+     * @param width The width of the target image row
+     * @param row_data The byte array to initialize with image data
+     */
+    private void process3CompRow( int width, byte[] row_data ) {
+        int index = 0;
+        for ( int x = 0; x < width; x++ ) {
+            float mult = srcPixelCount;
+            int r = Math.round( red[x] / mult );
+            int g = Math.round( green[x] / mult );
+            int b = Math.round( blue[x] / mult );
+
+            if ( r < 0 ) {
+                r = 0;
+            } else if ( r > 255 ) {
+                r = 255;
+            }
+            if ( g < 0 ) {
+                g = 0;
+            } else if ( g > 255 ) {
+                g = 255;
+            }
+            if ( b < 0 ) {
+                b = 0;
+            } else if ( b > 255 ) {
+                b = 255;
+            }
+
+            row_data[index++] = (byte)r;
+            row_data[index++] = (byte)g;
+            row_data[index++] = (byte)b;
+        }
+    }
+
+    /**
+     * Initialize the destination byte buffer with image data scaled to the
+     * width and height specified from the source byte buffer.
+     *
+     * @param destWidth The width of the destination image
+     * @param destHeight The height of the destination image
+     * @param srcBuffer The image source data
+     * @param destBuffer The buffer to initialize with the scaled image data
+     */
+    private void fillTwoCompBuffer(
+        int destWidth,
+        int destHeight,
+        ByteBuffer srcBuffer,
+        ByteBuffer destBuffer ) {
+
+        red = new float[destWidth];
+        alpha = new float[destWidth];
+
+        byte[] row_data = new byte[destWidth*srcCmp];
+
+        int sy = 0;
+        int syrem = destHeight;
+        int dy = 0;
+        int dyrem = 0;
+
+        int srcRowByteOffset = 0;
+
+        while ( sy < srcHeight ) {
+            int amty;
+            if ( dyrem == 0 ) {
+                for ( int i = 0; i < destWidth; i++ ) {
+                    alpha[i] = red[i] = 0f;
+                }
+                dyrem = srcHeight;
+            }
+            if ( syrem < dyrem ) {
+                amty = syrem;
+            } else {
+                amty = dyrem;
+            }
+            int sx = 0;
+            int dx = 0;
+            int sxrem = 0;
+            int dxrem = srcWidth;
+            float a = 0f, r = 0f;
+            while ( sx < srcWidth ) {
+                if ( sxrem == 0 ) {
+                    sxrem = destWidth;
+                    int srcColByteOffset = sx * srcCmp;
+                    r = 0xff & srcBuffer.get( srcRowByteOffset + srcColByteOffset++ );
+                    a = 0xff & srcBuffer.get( srcRowByteOffset + srcColByteOffset );
+                    // premultiply the components if necessary
+                    if ( a != 255.0f ) {
+                        float ascale = a / 255.0f;
+                        r *= ascale;
+                    }
+                }
+                int amtx;
+                if ( sxrem < dxrem ) {
+                    amtx = sxrem;
+                } else {
+                    amtx = dxrem;
+                }
+                float mult = ((float)amtx) * amty;
+                alpha[dx] += mult * a;
+                red[dx] += mult * r;
+                if ( ( sxrem -= amtx ) == 0 ) {
+                    sx++;
+                }
+                if ( ( dxrem -= amtx ) == 0 ) {
+                    dx++;
+                    dxrem = srcWidth;
+                }
+            }
+            if ( ( dyrem -= amty ) == 0 ) {
+                process2CompRow( destWidth, row_data );
+                do {
+                    destBuffer.put( row_data );
+                    dy++;
+                } while ( ( ( syrem -= amty ) >= amty ) && ( amty == srcHeight ) );
+            } else {
+                syrem -= amty;
+            }
+            if ( syrem == 0 ) {
+                syrem = destHeight;
+                sy++;
+                srcRowByteOffset += srcWidth * srcCmp;
+            }
+        }
+    }
+
+    /**
+     * Initialize the image data for a destination row.
+     *
+     * @param width The width of the target image row
+     * @param row_data The byte array to initialize with image data
+     */
+    private void process2CompRow( int width, byte[] row_data ) {
+        int index = 0;
+        for ( int x = 0; x < width; x++ ) {
+            float mult = srcPixelCount;
+            int a = Math.round( alpha[x] / mult );
+            if ( a <= 0 ) {
+                a = 0;
+            } else if ( a >= 255 ) {
+                a = 255;
+            } else {
+                // un-premultiply the components (by modifying mult here, we
+                // are effectively doing the divide by mult and divide by
+                // alpha in the same step)
+                mult = alpha[x] / 255;
+            }
+            int r = Math.round( red[x] / mult );
+
+            if ( r < 0 ) {
+                r = 0;
+            } else if ( r > 255 ) {
+                r = 255;
+            }
+
+            row_data[index++] = (byte)r;
+            row_data[index++] = (byte)a;
+        }
+    }
+
+    /**
+     * Initialize the destination byte buffer with image data scaled to the
+     * width and height specified from the source byte buffer.
+     *
+     * @param destWidth The width of the destination image
+     * @param destHeight The height of the destination image
+     * @param srcBuffer The image source data
+     * @param destBuffer The buffer to initialize with the scaled image data
+     */
+    private void fillOneCompBuffer(
+        int destWidth,
+        int destHeight,
+        ByteBuffer srcBuffer,
+        ByteBuffer destBuffer ) {
+
+        red = new float[destWidth];
+
+        byte[] row_data = new byte[destWidth*srcCmp];
+
+        int sy = 0;
+        int syrem = destHeight;
+        int dy = 0;
+        int dyrem = 0;
+
+        int srcRowByteOffset = 0;
+
+        while ( sy < srcHeight ) {
+            int amty;
+            if ( dyrem == 0 ) {
+                for ( int i = 0; i < destWidth; i++ ) {
+                    red[i] = 0f;
+                }
+                dyrem = srcHeight;
+            }
+            if ( syrem < dyrem ) {
+                amty = syrem;
+            } else {
+                amty = dyrem;
+            }
+            int sx = 0;
+            int dx = 0;
+            int sxrem = 0;
+            int dxrem = srcWidth;
+            float r = 0f;
+            while ( sx < srcWidth ) {
+                if ( sxrem == 0 ) {
+                    sxrem = destWidth;
+                    int srcColByteOffset = sx * srcCmp;
+                    r = 0xff & srcBuffer.get( srcRowByteOffset + srcColByteOffset );
+                }
+                int amtx;
+                if ( sxrem < dxrem ) {
+                    amtx = sxrem;
+                } else {
+                    amtx = dxrem;
+                }
+                float mult = ((float)amtx) * amty;
+                red[dx] += mult * r;
+                if ( ( sxrem -= amtx ) == 0 ) {
+                    sx++;
+                }
+                if ( ( dxrem -= amtx ) == 0 ) {
+                    dx++;
+                    dxrem = srcWidth;
+                }
+            }
+            if ( ( dyrem -= amty ) == 0 ) {
+                process1CompRow( destWidth, row_data );
+                do {
+                    destBuffer.put( row_data );
+                    dy++;
+                } while ( ( ( syrem -= amty ) >= amty ) && ( amty == srcHeight ) );
+            } else {
+                syrem -= amty;
+            }
+            if ( syrem == 0 ) {
+                syrem = destHeight;
+                sy++;
+                srcRowByteOffset += srcWidth * srcCmp;
+            }
+        }
+    }
+
+    /**
+     * Initialize the image data for a destination row.
+     *
+     * @param width The width of the target image row
+     * @param row_data The byte array to initialize with image data
+     */
+    private void process1CompRow( int width, byte[] row_data ) {
+        int index = 0;
+        for ( int x = 0; x < width; x++ ) {
+            float mult = srcPixelCount;
+            int r = Math.round( red[x] / mult );
+
+            if ( r < 0 ) {
+                r = 0;
+            } else if ( r > 255 ) {
+                r = 255;
+            }
+
+            row_data[index++] = (byte)r;
+        }
+    }
+}
diff --git a/src/java/org/web3d/image/BilinearScaleFilter.java b/src/java/org/web3d/image/BilinearScaleFilter.java
index f4c00060c80c91bb6ef8a9eb7f8d5ef4e6809e69..96626b2e51711e3d1cf2fe363084b3a72db00a5d 100644
--- a/src/java/org/web3d/image/BilinearScaleFilter.java
+++ b/src/java/org/web3d/image/BilinearScaleFilter.java
@@ -1,168 +1,168 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2007
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.image;
-
-// External imports
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-// Local imports
-// none
-
-//////////////////////////////////////////////////////////////////////////////
-// rem
-//
-// Not sure how robust this really is. Algorithm taken from here:
-//
-// http://www.codeproject.com/cs/media/imageprocessing4.asp?df=100&forumid=3657&exp=0&select=992091
-//
-// At a minimum, I think the handling of any image with an alpha channel is
-// incorrect. The original algorithm only handled RGB.
-//////////////////////////////////////////////////////////////////////////////
-
-/**
- * A ScaleFilter implementation for scaling NIOBufferImages.
- *
- * @author Rex Melton
- * @version $Revision: 1.1 $
- */
-public class BilinearScaleFilter implements ScaleFilter {
-
-    /** The image object that will rescaled */
-    private NIOBufferImage srcImage;
-
-    /** The width of the source image. */
-    private int srcWidth;
-
-    /** The height of the source image. */
-    private int srcHeight;
-
-    /** The number of components in the source image */
-    private int srcComponents;
-
-    /**
-     * Constructor
-     *
-     * @param image The source image that will be rescaled
-     */
-    public BilinearScaleFilter( NIOBufferImage image ) {
-        srcImage = image;
-        srcWidth = image.getWidth( );
-        srcHeight = image.getHeight( );
-        srcComponents = image.getType( ).size;
-    }
-
-    //----------------------------------------------------------
-    // Method defined by ScaleFilter
-    //----------------------------------------------------------
-
-    /**
-     * Return an image scaled to the specified width and height
-     *
-     * @param destWidth The width of the returned image
-     * @param destHeight The height of the returned image
-     * @return The scaled image
-     */
-    @Override
-    public NIOBufferImage getScaledImage( int destWidth, int destHeight ) {
-
-        ByteBuffer destBuffer = ByteBuffer.allocateDirect( destWidth * destHeight * srcComponents );
-        destBuffer.order( ByteOrder.nativeOrder( ) );
-
-        ByteBuffer srcBuffer = srcImage.getBuffer( );
-        srcBuffer.rewind( );
-
-        process( destWidth, destHeight, srcBuffer, destBuffer );
-
-        NIOBufferImage scaledImage = new NIOBufferImage(
-            destWidth,
-            destHeight,
-            srcImage.getType( ),
-            srcImage.isGrayScale( ),
-            destBuffer );
-
-        return( scaledImage );
-    }
-
-    //----------------------------------------------------------
-    // Local Methods
-    //----------------------------------------------------------
-
-    /**
-     * Initialize the destination byte buffer with image data scaled to the
-     * width and height specified from the source byte buffer.
-     *
-     * @param destWidth The width of the destination image
-     * @param destHeight The height of the destination image
-     * @param srcBuffer The image source data
-     * @param destBuffer The buffer to initialize with the scaled image data
-     */
-    private void process (
-        int destWidth,
-        int destHeight,
-        ByteBuffer srcBuffer,
-        ByteBuffer destBuffer ) {
-
-        float nXFactor = ((float)srcWidth)/destWidth;
-        float nYFactor = ((float)srcHeight)/destHeight;
-
-        float fraction_x, fraction_y, one_minus_x, one_minus_y;
-        int ceil_x, ceil_y, floor_x, floor_y;
-
-        for ( int y = 0; y < destHeight; ++y ) {
-            for ( int x = 0; x < destWidth; ++x ) {
-
-                floor_x = (int)Math.floor(x * nXFactor);
-                floor_y = (int)Math.floor(y * nYFactor);
-
-                ceil_x = floor_x + 1;
-                if (ceil_x >=srcWidth) {
-                    ceil_x = floor_x;
-                }
-                ceil_y = floor_y + 1;
-                if (ceil_y >= srcHeight) {
-                    ceil_y = floor_y;
-                }
-                fraction_x = x * nXFactor - floor_x;
-                fraction_y = y * nYFactor - floor_y;
-
-                one_minus_x = 1.0f - fraction_x;
-                one_minus_y = 1.0f - fraction_y;
-
-                int floor_y_off = floor_y * srcWidth * srcComponents;
-                int ceil_y_off = ceil_y * srcWidth * srcComponents;
-
-                int floor_x_off = floor_x * srcComponents;
-                int ceil_x_off = ceil_x * srcComponents;
-
-                int c1_off = floor_y_off + floor_x_off;
-                int c2_off = floor_y_off + ceil_x_off;
-                int c3_off = ceil_y_off + floor_x_off;
-                int c4_off = ceil_y_off + ceil_x_off;
-
-                for ( int i = 0; i < srcComponents; i++ ) {
-
-                    float tmp1 = one_minus_x * ( 0xff & srcBuffer.get(c1_off++) ) +
-                        fraction_x * ( 0xff & srcBuffer.get(c2_off++) );
-
-                    float tmp2 = one_minus_x * ( 0xff & srcBuffer.get(c3_off++) ) +
-                        fraction_x * ( 0xff & srcBuffer.get(c4_off++) );
-
-                    byte cmp = (byte)( one_minus_y * tmp1 + fraction_y * tmp2 );
-
-                    destBuffer.put( cmp );
-                }
-            }
-        }
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2007
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.image;
+
+// External imports
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+// Local imports
+// none
+
+//////////////////////////////////////////////////////////////////////////////
+// rem
+//
+// Not sure how robust this really is. Algorithm taken from here:
+//
+// http://www.codeproject.com/cs/media/imageprocessing4.asp?df=100&forumid=3657&exp=0&select=992091
+//
+// At a minimum, I think the handling of any image with an alpha channel is
+// incorrect. The original algorithm only handled RGB.
+//////////////////////////////////////////////////////////////////////////////
+
+/**
+ * A ScaleFilter implementation for scaling NIOBufferImages.
+ *
+ * @author Rex Melton
+ * @version $Revision: 1.1 $
+ */
+public class BilinearScaleFilter implements ScaleFilter {
+
+    /** The image object that will rescaled */
+    private NIOBufferImage srcImage;
+
+    /** The width of the source image. */
+    private int srcWidth;
+
+    /** The height of the source image. */
+    private int srcHeight;
+
+    /** The number of components in the source image */
+    private int srcComponents;
+
+    /**
+     * Constructor
+     *
+     * @param image The source image that will be rescaled
+     */
+    public BilinearScaleFilter( NIOBufferImage image ) {
+        srcImage = image;
+        srcWidth = image.getWidth( );
+        srcHeight = image.getHeight( );
+        srcComponents = image.getType( ).size;
+    }
+
+    //----------------------------------------------------------
+    // Method defined by ScaleFilter
+    //----------------------------------------------------------
+
+    /**
+     * Return an image scaled to the specified width and height
+     *
+     * @param destWidth The width of the returned image
+     * @param destHeight The height of the returned image
+     * @return The scaled image
+     */
+    @Override
+    public NIOBufferImage getScaledImage( int destWidth, int destHeight ) {
+
+        ByteBuffer destBuffer = ByteBuffer.allocateDirect( destWidth * destHeight * srcComponents );
+        destBuffer.order( ByteOrder.nativeOrder( ) );
+
+        ByteBuffer srcBuffer = srcImage.getBuffer( );
+        srcBuffer.rewind( );
+
+        process( destWidth, destHeight, srcBuffer, destBuffer );
+
+        NIOBufferImage scaledImage = new NIOBufferImage(
+            destWidth,
+            destHeight,
+            srcImage.getType( ),
+            srcImage.isGrayScale( ),
+            destBuffer );
+
+        return( scaledImage );
+    }
+
+    //----------------------------------------------------------
+    // Local Methods
+    //----------------------------------------------------------
+
+    /**
+     * Initialize the destination byte buffer with image data scaled to the
+     * width and height specified from the source byte buffer.
+     *
+     * @param destWidth The width of the destination image
+     * @param destHeight The height of the destination image
+     * @param srcBuffer The image source data
+     * @param destBuffer The buffer to initialize with the scaled image data
+     */
+    private void process (
+        int destWidth,
+        int destHeight,
+        ByteBuffer srcBuffer,
+        ByteBuffer destBuffer ) {
+
+        float nXFactor = ((float)srcWidth)/destWidth;
+        float nYFactor = ((float)srcHeight)/destHeight;
+
+        float fraction_x, fraction_y, one_minus_x, one_minus_y;
+        int ceil_x, ceil_y, floor_x, floor_y;
+
+        for ( int y = 0; y < destHeight; ++y ) {
+            for ( int x = 0; x < destWidth; ++x ) {
+
+                floor_x = (int)Math.floor(x * nXFactor);
+                floor_y = (int)Math.floor(y * nYFactor);
+
+                ceil_x = floor_x + 1;
+                if (ceil_x >=srcWidth) {
+                    ceil_x = floor_x;
+                }
+                ceil_y = floor_y + 1;
+                if (ceil_y >= srcHeight) {
+                    ceil_y = floor_y;
+                }
+                fraction_x = x * nXFactor - floor_x;
+                fraction_y = y * nYFactor - floor_y;
+
+                one_minus_x = 1.0f - fraction_x;
+                one_minus_y = 1.0f - fraction_y;
+
+                int floor_y_off = floor_y * srcWidth * srcComponents;
+                int ceil_y_off = ceil_y * srcWidth * srcComponents;
+
+                int floor_x_off = floor_x * srcComponents;
+                int ceil_x_off = ceil_x * srcComponents;
+
+                int c1_off = floor_y_off + floor_x_off;
+                int c2_off = floor_y_off + ceil_x_off;
+                int c3_off = ceil_y_off + floor_x_off;
+                int c4_off = ceil_y_off + ceil_x_off;
+
+                for ( int i = 0; i < srcComponents; i++ ) {
+
+                    float tmp1 = one_minus_x * ( 0xff & srcBuffer.get(c1_off++) ) +
+                        fraction_x * ( 0xff & srcBuffer.get(c2_off++) );
+
+                    float tmp2 = one_minus_x * ( 0xff & srcBuffer.get(c3_off++) ) +
+                        fraction_x * ( 0xff & srcBuffer.get(c4_off++) );
+
+                    byte cmp = (byte)( one_minus_y * tmp1 + fraction_y * tmp2 );
+
+                    destBuffer.put( cmp );
+                }
+            }
+        }
+    }
+}
diff --git a/src/java/org/web3d/image/NIOBufferImage.java b/src/java/org/web3d/image/NIOBufferImage.java
index d34ebf23b9d1951424559154c2a1536231dd29b5..3977d9d66c5cd5a7056d1a4082498464f7f5de16 100644
--- a/src/java/org/web3d/image/NIOBufferImage.java
+++ b/src/java/org/web3d/image/NIOBufferImage.java
@@ -1,292 +1,292 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2006 - 2007
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.image;
-
-// External imports
-import java.nio.ByteBuffer;
-
-// Local imports
-// none
-
-/**
- * A representation of an image contained in a <code>ByteBuffer</code>.
- *
- * @author Rex Melton
- * @version $Revision: 1.4 $
- */
-public class NIOBufferImage {
-
-    /**
-     * Invalid width error message
-     */
-    private static final String INVALID_WIDTH_PARAMETER
-            = "image width must be a positive integer";
-
-    /**
-     * Invalid height error message
-     */
-    private static final String INVALID_HEIGHT_PARAMETER
-            = "image height must be a positive integer";
-
-    /**
-     * Invalid type error message, null
-     */
-    private static final String TYPE_IS_NULL
-            = "image type must be non-null";
-
-    /**
-     * Invalid buffer error message, null
-     */
-    private static final String BUFFER_IS_NULL
-            = "image buffer must be non-null";
-
-    /**
-     * Invalid buffer error message, insufficient size
-     */
-    private static final String BUFFER_INSUFFICIENT
-            = "image buffer must be sufficiently sized to contain image";
-
-    /**
-     * The image width
-     */
-    private int width;
-
-    /**
-     * The image height
-     */
-    private int height;
-
-    /**
-     * The image format type
-     */
-    private NIOBufferImageType type;
-
-    /**
-     * The image buffer
-     */
-    private ByteBuffer[] buffer;
-
-    /**
-     * Flag indicating that the image should be treated as grayscale, regardless
-     * of the actual number of components
-     */
-    private boolean isGrayScale;
-
-    /**
-     * Flag indicating that the image includes alpha (1 - transparency) components
-     */
-    private boolean hasTransparency;
-
-    /**
-     * Constructor
-     *
-     * @param width The image width
-     * @param height The image height
-     * @param type The image format type
-     * @throws IllegalArgumentException if either the width or height arguments
-     * are not positive integers
-     * @throws NullPointerException if the type argument is <code>null</code>
-     */
-    public NIOBufferImage(int width, int height, NIOBufferImageType type) {
-        this(width,
-             height,
-             type,
-             ByteBuffer.allocateDirect(width * height * type.size));
-    }
-
-    /**
-     * Constructor
-     *
-     * @param width The image width
-     * @param height The image height
-     * @param type The image format type
-     * @param buffer The image data
-     * @throws IllegalArgumentException if either the width or height arguments
-     * are not positive integers
-     * @throws NullPointerException if either the type or buffer argument are
-     * <code>null</code>
-     * @throws IllegalArgumentException if the buffer is insufficiently sized
-     */
-    public NIOBufferImage(int width, int height, NIOBufferImageType type, ByteBuffer buffer) {
-        this(width,
-             height,
-             type,
-             (type == NIOBufferImageType.INTENSITY) | (type == NIOBufferImageType.INTENSITY_ALPHA),
-             buffer);
-    }
-
-    /**
-     * Constructor
-     *
-     * @param width The image width
-     * @param height The image height
-     * @param type The image format type
-     * @param isGrayScale Flag indicating that the image should be treated as
-     * grayscale, regardless of the format
-     * @param buffer The image data
-     * @throws IllegalArgumentException if either the width or height arguments
-     * are not positive integers
-     * @throws NullPointerException if either the type or buffer argument are
-     * <code>null</code>
-     * @throws IllegalArgumentException if the buffer is insufficiently sized
-     */
-    public NIOBufferImage(int width, int height, NIOBufferImageType type,
-            boolean isGrayScale, ByteBuffer buffer) {
-
-        if (width < 1) {
-            throw new IllegalArgumentException(INVALID_WIDTH_PARAMETER);
-        } else if (height < 1) {
-            throw new IllegalArgumentException(INVALID_HEIGHT_PARAMETER);
-        } else if (type == null) {
-            throw new NullPointerException(TYPE_IS_NULL);
-        } else if (buffer == null) {
-            throw new NullPointerException(BUFFER_IS_NULL);
-        } else if (buffer.limit() != width * height * type.size) {
-            throw new IllegalArgumentException(BUFFER_INSUFFICIENT);
-        }
-        this.width = width;
-        this.height = height;
-        this.type = type;
-        this.isGrayScale = isGrayScale;
-        this.hasTransparency = (type == NIOBufferImageType.INTENSITY_ALPHA) | (type == NIOBufferImageType.RGBA);
-        this.buffer = new ByteBuffer[]{buffer};
-    }
-
-    /**
-     * Return the image width
-     *
-     * @return The image width
-     */
-    public int getWidth() {
-        return width;
-    }
-
-    /**
-     * Return the image height
-     *
-     * @return The image height
-     */
-    public int getHeight() {
-        return height;
-    }
-
-    /**
-     * Return the image format type
-     *
-     * @return The image format type
-     */
-    public NIOBufferImageType getType() {
-        return type;
-    }
-
-    /**
-     * Return whether the image should be treated as grayscale
-     *
-     * @return whether the image should be treated as grayscale
-     */
-    public boolean isGrayScale() {
-        return isGrayScale;
-    }
-
-    /**
-     * Return whether the image includes alpha (1 - transparency) components
-     *
-     * @return whether the image should be treated as having alpha (1 - transparency) components
-     */
-    public boolean hasTransparency() {
-        return hasTransparency;
-    }
-
-    /**
-     * Return the number of image levels
-     *
-     * @return The number of image levels
-     */
-    public int getLevels() {
-        return buffer.length;
-    }
-
-    /**
-     * Return the image buffer
-     *
-     * @return The image buffer
-     */
-    public ByteBuffer getBuffer() {
-        buffer[0].rewind();
-        return buffer[0];
-    }
-
-    /**
-     * Return the image buffer array
-     *
-     * @param ret_buf
-     * @return The image buffer array
-     */
-    public ByteBuffer[] getBuffer(ByteBuffer[] ret_buf) {
-        int size = buffer.length;
-        if ((ret_buf == null) || (ret_buf.length < size)) {
-            ret_buf = new ByteBuffer[size];
-        }
-        for (int i = 0; i < size; i++) {
-            buffer[i].rewind();
-            ret_buf[i] = buffer[i];
-        }
-        return ret_buf;
-    }
-
-    /**
-     * Set the image buffer
-     *
-     * @param buffer The image buffer
-     * @throws NullPointerException if the argument buffer is <code>null</code>
-     * @throws IllegalArgumentException if the buffer is insufficiently sized
-     */
-    public void setBuffer(ByteBuffer buffer) {
-        if (buffer == null) {
-            throw new NullPointerException(BUFFER_IS_NULL);
-        } else if (buffer.limit() != width * height * type.size) {
-            throw new IllegalArgumentException(BUFFER_INSUFFICIENT);
-        }
-        this.buffer = new ByteBuffer[]{buffer};
-    }
-
-    /**
-     * Set the image buffer array
-     *
-     * @param buffer The image buffer
-     * @throws NullPointerException if the argument buffer is <code>null</code>
-     * @throws IllegalArgumentException if the buffer is insufficiently sized
-     */
-    public void setBuffer(ByteBuffer[] buffer) {
-        if (buffer == null) {
-            throw new NullPointerException(BUFFER_IS_NULL);
-        } else if (buffer[0].limit() != width * height * type.size) {
-            throw new IllegalArgumentException(BUFFER_INSUFFICIENT);
-        }
-        int size = buffer.length;
-        this.buffer = new ByteBuffer[size];
-        System.arraycopy(buffer, 0, this.buffer, 0, size);
-    }
-
-    /**
-     * Return a description of the image
-     *
-     * @return a description of the image
-     */
-    @Override
-    public String toString() {
-        return ("NIOBufferImage: type = " + type.name
-                + ", width = " + width
-                + ", height = " + height);
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2006 - 2007
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.image;
+
+// External imports
+import java.nio.ByteBuffer;
+
+// Local imports
+// none
+
+/**
+ * A representation of an image contained in a <code>ByteBuffer</code>.
+ *
+ * @author Rex Melton
+ * @version $Revision: 1.4 $
+ */
+public class NIOBufferImage {
+
+    /**
+     * Invalid width error message
+     */
+    private static final String INVALID_WIDTH_PARAMETER
+            = "image width must be a positive integer";
+
+    /**
+     * Invalid height error message
+     */
+    private static final String INVALID_HEIGHT_PARAMETER
+            = "image height must be a positive integer";
+
+    /**
+     * Invalid type error message, null
+     */
+    private static final String TYPE_IS_NULL
+            = "image type must be non-null";
+
+    /**
+     * Invalid buffer error message, null
+     */
+    private static final String BUFFER_IS_NULL
+            = "image buffer must be non-null";
+
+    /**
+     * Invalid buffer error message, insufficient size
+     */
+    private static final String BUFFER_INSUFFICIENT
+            = "image buffer must be sufficiently sized to contain image";
+
+    /**
+     * The image width
+     */
+    private int width;
+
+    /**
+     * The image height
+     */
+    private int height;
+
+    /**
+     * The image format type
+     */
+    private NIOBufferImageType type;
+
+    /**
+     * The image buffer
+     */
+    private ByteBuffer[] buffer;
+
+    /**
+     * Flag indicating that the image should be treated as grayscale, regardless
+     * of the actual number of components
+     */
+    private boolean isGrayScale;
+
+    /**
+     * Flag indicating that the image includes alpha (1 - transparency) components
+     */
+    private boolean hasTransparency;
+
+    /**
+     * Constructor
+     *
+     * @param width The image width
+     * @param height The image height
+     * @param type The image format type
+     * @throws IllegalArgumentException if either the width or height arguments
+     * are not positive integers
+     * @throws NullPointerException if the type argument is <code>null</code>
+     */
+    public NIOBufferImage(int width, int height, NIOBufferImageType type) {
+        this(width,
+             height,
+             type,
+             ByteBuffer.allocateDirect(width * height * type.size));
+    }
+
+    /**
+     * Constructor
+     *
+     * @param width The image width
+     * @param height The image height
+     * @param type The image format type
+     * @param buffer The image data
+     * @throws IllegalArgumentException if either the width or height arguments
+     * are not positive integers
+     * @throws NullPointerException if either the type or buffer argument are
+     * <code>null</code>
+     * @throws IllegalArgumentException if the buffer is insufficiently sized
+     */
+    public NIOBufferImage(int width, int height, NIOBufferImageType type, ByteBuffer buffer) {
+        this(width,
+             height,
+             type,
+             (type == NIOBufferImageType.INTENSITY) | (type == NIOBufferImageType.INTENSITY_ALPHA),
+             buffer);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param width The image width
+     * @param height The image height
+     * @param type The image format type
+     * @param isGrayScale Flag indicating that the image should be treated as
+     * grayscale, regardless of the format
+     * @param buffer The image data
+     * @throws IllegalArgumentException if either the width or height arguments
+     * are not positive integers
+     * @throws NullPointerException if either the type or buffer argument are
+     * <code>null</code>
+     * @throws IllegalArgumentException if the buffer is insufficiently sized
+     */
+    public NIOBufferImage(int width, int height, NIOBufferImageType type,
+            boolean isGrayScale, ByteBuffer buffer) {
+
+        if (width < 1) {
+            throw new IllegalArgumentException(INVALID_WIDTH_PARAMETER);
+        } else if (height < 1) {
+            throw new IllegalArgumentException(INVALID_HEIGHT_PARAMETER);
+        } else if (type == null) {
+            throw new NullPointerException(TYPE_IS_NULL);
+        } else if (buffer == null) {
+            throw new NullPointerException(BUFFER_IS_NULL);
+        } else if (buffer.limit() != width * height * type.size) {
+            throw new IllegalArgumentException(BUFFER_INSUFFICIENT);
+        }
+        this.width = width;
+        this.height = height;
+        this.type = type;
+        this.isGrayScale = isGrayScale;
+        this.hasTransparency = (type == NIOBufferImageType.INTENSITY_ALPHA) | (type == NIOBufferImageType.RGBA);
+        this.buffer = new ByteBuffer[]{buffer};
+    }
+
+    /**
+     * Return the image width
+     *
+     * @return The image width
+     */
+    public int getWidth() {
+        return width;
+    }
+
+    /**
+     * Return the image height
+     *
+     * @return The image height
+     */
+    public int getHeight() {
+        return height;
+    }
+
+    /**
+     * Return the image format type
+     *
+     * @return The image format type
+     */
+    public NIOBufferImageType getType() {
+        return type;
+    }
+
+    /**
+     * Return whether the image should be treated as grayscale
+     *
+     * @return whether the image should be treated as grayscale
+     */
+    public boolean isGrayScale() {
+        return isGrayScale;
+    }
+
+    /**
+     * Return whether the image includes alpha (1 - transparency) components
+     *
+     * @return whether the image should be treated as having alpha (1 - transparency) components
+     */
+    public boolean hasTransparency() {
+        return hasTransparency;
+    }
+
+    /**
+     * Return the number of image levels
+     *
+     * @return The number of image levels
+     */
+    public int getLevels() {
+        return buffer.length;
+    }
+
+    /**
+     * Return the image buffer
+     *
+     * @return The image buffer
+     */
+    public ByteBuffer getBuffer() {
+        buffer[0].rewind();
+        return buffer[0];
+    }
+
+    /**
+     * Return the image buffer array
+     *
+     * @param ret_buf
+     * @return The image buffer array
+     */
+    public ByteBuffer[] getBuffer(ByteBuffer[] ret_buf) {
+        int size = buffer.length;
+        if ((ret_buf == null) || (ret_buf.length < size)) {
+            ret_buf = new ByteBuffer[size];
+        }
+        for (int i = 0; i < size; i++) {
+            buffer[i].rewind();
+            ret_buf[i] = buffer[i];
+        }
+        return ret_buf;
+    }
+
+    /**
+     * Set the image buffer
+     *
+     * @param buffer The image buffer
+     * @throws NullPointerException if the argument buffer is <code>null</code>
+     * @throws IllegalArgumentException if the buffer is insufficiently sized
+     */
+    public void setBuffer(ByteBuffer buffer) {
+        if (buffer == null) {
+            throw new NullPointerException(BUFFER_IS_NULL);
+        } else if (buffer.limit() != width * height * type.size) {
+            throw new IllegalArgumentException(BUFFER_INSUFFICIENT);
+        }
+        this.buffer = new ByteBuffer[]{buffer};
+    }
+
+    /**
+     * Set the image buffer array
+     *
+     * @param buffer The image buffer
+     * @throws NullPointerException if the argument buffer is <code>null</code>
+     * @throws IllegalArgumentException if the buffer is insufficiently sized
+     */
+    public void setBuffer(ByteBuffer[] buffer) {
+        if (buffer == null) {
+            throw new NullPointerException(BUFFER_IS_NULL);
+        } else if (buffer[0].limit() != width * height * type.size) {
+            throw new IllegalArgumentException(BUFFER_INSUFFICIENT);
+        }
+        int size = buffer.length;
+        this.buffer = new ByteBuffer[size];
+        System.arraycopy(buffer, 0, this.buffer, 0, size);
+    }
+
+    /**
+     * Return a description of the image
+     *
+     * @return a description of the image
+     */
+    @Override
+    public String toString() {
+        return ("NIOBufferImage: type = " + type.name
+                + ", width = " + width
+                + ", height = " + height);
+    }
+}
diff --git a/src/java/org/web3d/image/NIOBufferImageType.java b/src/java/org/web3d/image/NIOBufferImageType.java
index 60209d13adde4e63d351520ee1f10e23ffe47bb8..25c8e9e44dcc19cbdd5bf347d70f76558721786a 100644
--- a/src/java/org/web3d/image/NIOBufferImageType.java
+++ b/src/java/org/web3d/image/NIOBufferImageType.java
@@ -1,106 +1,106 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.image;
-
-// External imports
-// none
-
-// Local imports
-// none
-
-/**
- * Constant object identifiers of the image type contained by an
- * <code>NIOBufferImage</code>.
- *
- * @author Rex Melton
- * @version $Revision: 1.2 $
- */
-public class NIOBufferImageType {
-
-    /**
-     * The INTENSITY type
-     */
-    public static final NIOBufferImageType INTENSITY
-            = new NIOBufferImageType("INTENSITY", 1);
-
-    /**
-     * The INTENSITY_ALPHA type
-     */
-    public static final NIOBufferImageType INTENSITY_ALPHA
-            = new NIOBufferImageType("INTENSITY_ALPHA", 2);
-
-    /**
-     * The RGB type
-     */
-    public static final NIOBufferImageType RGB
-            = new NIOBufferImageType("RGB", 3);
-
-    /**
-     * The RGBA type
-     */
-    public static final NIOBufferImageType RGBA
-            = new NIOBufferImageType("RGBA", 4);
-
-    /**
-     * The type identifier
-     */
-    public final String name;
-
-    /**
-     * The buffer allocation per pixel
-     */
-    public final int size;
-
-    /**
-     * Constructor
-     *
-     * @param name The type identifier
-     * @param size The buffer allocation per pixel of this type
-     */
-    protected NIOBufferImageType(String name, int size) {
-        this.name = name;
-        this.size = size;
-    }
-
-    /**
-     * Return the type object that corresponds to the specified number of
-     * components per pixel. If unknown, then null is returned.
-     *
-     * @param cmp The number of components per pixel
-     * @return The type object
-     */
-    public static NIOBufferImageType getType(int cmp) {
-        switch (cmp) {
-            case 1:
-                return INTENSITY;
-            case 2:
-                return INTENSITY_ALPHA;
-            case 3:
-                return RGB;
-            case 4:
-                return RGBA;
-            default:
-                return null;
-        }
-    }
-
-    /**
-     * Return the String identifier of the type
-     *
-     * @return the String identifier of the type
-     */
-    @Override
-    public String toString() {
-        return name;
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.image;
+
+// External imports
+// none
+
+// Local imports
+// none
+
+/**
+ * Constant object identifiers of the image type contained by an
+ * <code>NIOBufferImage</code>.
+ *
+ * @author Rex Melton
+ * @version $Revision: 1.2 $
+ */
+public class NIOBufferImageType {
+
+    /**
+     * The INTENSITY type
+     */
+    public static final NIOBufferImageType INTENSITY
+            = new NIOBufferImageType("INTENSITY", 1);
+
+    /**
+     * The INTENSITY_ALPHA type
+     */
+    public static final NIOBufferImageType INTENSITY_ALPHA
+            = new NIOBufferImageType("INTENSITY_ALPHA", 2);
+
+    /**
+     * The RGB type
+     */
+    public static final NIOBufferImageType RGB
+            = new NIOBufferImageType("RGB", 3);
+
+    /**
+     * The RGBA type
+     */
+    public static final NIOBufferImageType RGBA
+            = new NIOBufferImageType("RGBA", 4);
+
+    /**
+     * The type identifier
+     */
+    public final String name;
+
+    /**
+     * The buffer allocation per pixel
+     */
+    public final int size;
+
+    /**
+     * Constructor
+     *
+     * @param name The type identifier
+     * @param size The buffer allocation per pixel of this type
+     */
+    protected NIOBufferImageType(String name, int size) {
+        this.name = name;
+        this.size = size;
+    }
+
+    /**
+     * Return the type object that corresponds to the specified number of
+     * components per pixel. If unknown, then null is returned.
+     *
+     * @param cmp The number of components per pixel
+     * @return The type object
+     */
+    public static NIOBufferImageType getType(int cmp) {
+        switch (cmp) {
+            case 1:
+                return INTENSITY;
+            case 2:
+                return INTENSITY_ALPHA;
+            case 3:
+                return RGB;
+            case 4:
+                return RGBA;
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * Return the String identifier of the type
+     *
+     * @return the String identifier of the type
+     */
+    @Override
+    public String toString() {
+        return name;
+    }
+}
diff --git a/src/java/org/web3d/image/ScaleFilter.java b/src/java/org/web3d/image/ScaleFilter.java
index 247e7b450fa1e141a7f0e6f2df20460d4276ef20..55851a543e8de5134dc1c7c1ec1091a0b6215896 100644
--- a/src/java/org/web3d/image/ScaleFilter.java
+++ b/src/java/org/web3d/image/ScaleFilter.java
@@ -1,37 +1,37 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2007
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.image;
-
-// External imports
-// none
-
-// Local imports
-// none
-
-/**
- * Defines the requirements for a scaling filter for NIOBufferImage objects
- *
- * @author Rex Melton
- * @version $Revision: 1.1 $
- */
-public interface ScaleFilter {
-
-    /**
-     * Return an image scaled to the specified width and height
-     *
-     * @param width The width of the returned image
-     * @param height The height of the returned image
-     * @return The scaled image
-     */
-    NIOBufferImage getScaledImage( int width, int height );
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2007
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.image;
+
+// External imports
+// none
+
+// Local imports
+// none
+
+/**
+ * Defines the requirements for a scaling filter for NIOBufferImage objects
+ *
+ * @author Rex Melton
+ * @version $Revision: 1.1 $
+ */
+public interface ScaleFilter {
+
+    /**
+     * Return an image scaled to the specified width and height
+     *
+     * @param width The width of the returned image
+     * @param height The height of the returned image
+     * @return The scaled image
+     */
+    NIOBufferImage getScaledImage( int width, int height );
+}
diff --git a/src/java/org/web3d/net/protocol/FileResourceConnection.java b/src/java/org/web3d/net/protocol/FileResourceConnection.java
index 220f51d1f1ca99c48bd783d80111435296b54549..4642917238b9af95b85cefb3ea9791083e3cece4 100644
--- a/src/java/org/web3d/net/protocol/FileResourceConnection.java
+++ b/src/java/org/web3d/net/protocol/FileResourceConnection.java
@@ -1,140 +1,140 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2005
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.net.protocol;
-
-// External imports
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URLConnection;
-import java.util.HashSet;
-import java.util.Set;
-
-// Local imports
-// None
-
-/**
- * Extended implementation of the file resource connection that looks for
- * X3D-specific file extensions to set the content type correctly.
- */
-class FileResourceConnection extends vlc.net.protocol.file.FileResourceConnection
-{
-    /** Set of types that are internally labeled with the gzip input stream type */
-    private static final Set<String> X3D_GZIP_TYPES;
-
-    /**
-     * Set of types that are internally labeled as something we need to perform
-     * extra processing steps on. Anything not in this list is returned simply.
-     */
-    private static final Set<String> NONSTANDARD_TYPES;
-
-    /** The content encoding, if known */
-    private String encoding;
-
-    /** The MIME Type of the described file. Null if not yet known */
-    private String contentType;
-
-    /**
-     * Static constructor to populate the global set.
-     */
-    static {    
-        NONSTANDARD_TYPES = new HashSet<>();
-        NONSTANDARD_TYPES.add("application/x-gzip");
-        NONSTANDARD_TYPES.add("model/x3d+vrml");
-        NONSTANDARD_TYPES.add("model/x3d+xml");
-
-        X3D_GZIP_TYPES = new HashSet<>();
-        X3D_GZIP_TYPES.add("x3dvz");
-        X3D_GZIP_TYPES.add("x3dz");
-    }
-
-    /**
-     * Create an instance of this connection.
-     *
-     * @param uri The URI to establish the connection to
-     * @exception MalformedURLException We stuffed up something in the filename
-     */
-    FileResourceConnection(String uri) throws MalformedURLException {
-        super(uri);
-    }
-
-    /**
-     * Get the content type of the resource that this stream points to.
-     * Returns a standard MIME type string. If the content type is not known then
-     * <code>unknown/unknown</code> is returned (the default implementation).
-     *
-     * @return The content type of this resource
-     */
-    @Override
-    public String getContentType() {
-
-        if(contentType != null)
-            return contentType;
-
-        // Only works with <= JDK8
-        String content_type = super.getContentType();
-        
-        // ${java.home}/lib/content-types.properties was removed in JDK9.
-        // So, as a workaround, we now do this
-        if (content_type == null) {
-            try {
-                content_type = 
-                        URLConnection.guessContentTypeFromName(getURI().getURL().getPath());
-            } catch (IOException e) {}
-        }
-
-        if(!NONSTANDARD_TYPES.contains(content_type)) {
-            contentType = content_type;
-            return contentType;
-        }
-
-        int dot_idx = path.lastIndexOf(".");
-
-        // If this is a gzip extension, then look back one further "." and
-        // see if we have anything matching that.
-
-        if(content_type != null && content_type.equals("application/x-gzip")) {
-            String sub_path = path.substring(0, dot_idx);
-            String new_type = findContentType(sub_path);
-
-            if(new_type != null) {
-                encoding = "x-gzip";
-                contentType = new_type;
-            }
-        } else {
-            String ext = path.substring(dot_idx + 1);
-
-            if(X3D_GZIP_TYPES.contains(ext)) {
-                encoding = "x-gzip";
-            }
-
-            contentType = content_type;
-        }
-
-        return contentType;
-    }
-
-    /**
-     * Get the encoding type of the content. Allows for dealing with
-     * multi-lingual content and also multiple buried types. If it cannot be
-     * determined then null is returned (which is the default implementation).
-     *
-     * @return The encoding string or null
-     */
-    @Override
-    public String getContentEncoding() {
-        if((encoding == null) && (contentType == null))
-            getContentType();
-
-        return encoding;
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2005
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.net.protocol;
+
+// External imports
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URLConnection;
+import java.util.HashSet;
+import java.util.Set;
+
+// Local imports
+// None
+
+/**
+ * Extended implementation of the file resource connection that looks for
+ * X3D-specific file extensions to set the content type correctly.
+ */
+class FileResourceConnection extends vlc.net.protocol.file.FileResourceConnection
+{
+    /** Set of types that are internally labeled with the gzip input stream type */
+    private static final Set<String> X3D_GZIP_TYPES;
+
+    /**
+     * Set of types that are internally labeled as something we need to perform
+     * extra processing steps on. Anything not in this list is returned simply.
+     */
+    private static final Set<String> NONSTANDARD_TYPES;
+
+    /** The content encoding, if known */
+    private String encoding;
+
+    /** The MIME Type of the described file. Null if not yet known */
+    private String contentType;
+
+    /**
+     * Static constructor to populate the global set.
+     */
+    static {    
+        NONSTANDARD_TYPES = new HashSet<>();
+        NONSTANDARD_TYPES.add("application/x-gzip");
+        NONSTANDARD_TYPES.add("model/x3d+vrml");
+        NONSTANDARD_TYPES.add("model/x3d+xml");
+
+        X3D_GZIP_TYPES = new HashSet<>();
+        X3D_GZIP_TYPES.add("x3dvz");
+        X3D_GZIP_TYPES.add("x3dz");
+    }
+
+    /**
+     * Create an instance of this connection.
+     *
+     * @param uri The URI to establish the connection to
+     * @exception MalformedURLException We stuffed up something in the filename
+     */
+    FileResourceConnection(String uri) throws MalformedURLException {
+        super(uri);
+    }
+
+    /**
+     * Get the content type of the resource that this stream points to.
+     * Returns a standard MIME type string. If the content type is not known then
+     * <code>unknown/unknown</code> is returned (the default implementation).
+     *
+     * @return The content type of this resource
+     */
+    @Override
+    public String getContentType() {
+
+        if(contentType != null)
+            return contentType;
+
+        // Only works with <= JDK8
+        String content_type = super.getContentType();
+        
+        // ${java.home}/lib/content-types.properties was removed in JDK9.
+        // So, as a workaround, we now do this
+        if (content_type == null) {
+            try {
+                content_type = 
+                        URLConnection.guessContentTypeFromName(getURI().getURL().getPath());
+            } catch (IOException e) {}
+        }
+
+        if(!NONSTANDARD_TYPES.contains(content_type)) {
+            contentType = content_type;
+            return contentType;
+        }
+
+        int dot_idx = path.lastIndexOf(".");
+
+        // If this is a gzip extension, then look back one further "." and
+        // see if we have anything matching that.
+
+        if(content_type != null && content_type.equals("application/x-gzip")) {
+            String sub_path = path.substring(0, dot_idx);
+            String new_type = findContentType(sub_path);
+
+            if(new_type != null) {
+                encoding = "x-gzip";
+                contentType = new_type;
+            }
+        } else {
+            String ext = path.substring(dot_idx + 1);
+
+            if(X3D_GZIP_TYPES.contains(ext)) {
+                encoding = "x-gzip";
+            }
+
+            contentType = content_type;
+        }
+
+        return contentType;
+    }
+
+    /**
+     * Get the encoding type of the content. Allows for dealing with
+     * multi-lingual content and also multiple buried types. If it cannot be
+     * determined then null is returned (which is the default implementation).
+     *
+     * @return The encoding string or null
+     */
+    @Override
+    public String getContentEncoding() {
+        if((encoding == null) && (contentType == null))
+            getContentType();
+
+        return encoding;
+    }
+}
diff --git a/src/java/org/web3d/net/protocol/FileResourceStream.java b/src/java/org/web3d/net/protocol/FileResourceStream.java
index 44f9631f54e1ed02646c0ddffb8916df2b8e833d..9a253c178f3c69c33ab220e3175ea4e55cdffe4f 100644
--- a/src/java/org/web3d/net/protocol/FileResourceStream.java
+++ b/src/java/org/web3d/net/protocol/FileResourceStream.java
@@ -1,100 +1,100 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2005
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.net.protocol;
-
-// External imports
-import java.io.IOException;
-import java.net.MalformedURLException;
-
-import org.ietf.uri.ResourceConnection;
-import org.ietf.uri.URIResourceStream;
-
-// Local imports
-// None
-
-/**
- * A File protocol handler.
- *  <p>
- *
- * The basic connection handler for dealing with URLs of the
- * type <code>file:///</code> and URNs that resolve to items on the
- * local filesystem.
- *  <p>
- *
- * The path defines the object as needed from the root of the system.
- * It must be fully qualified - including either machine names for
- * UNC enunciated paths or drive letters where appropriate to the
- * operating system.
- *  <p>
- *
- * For details on URIs see the IETF working group:
- * <a href="http://www.ietf.org/html.charters/urn-charter.html">URN</a>
- *  <p>
- *
- * This software is released under the
- * <a href="http://www.gnu.org/copyleft/lgpl.html">GNU LGPL</a>
- *  <p>
- *
- * DISCLAIMER: <br>
- * This software is the under development, incomplete, and is
- * known to contain bugs. This software is made available for
- * review purposes only. Do not rely on this software for
- * production-quality applications or for mission-critical
- * applications.
- *  <p>
- *
- * Portions of the APIs for some new features have not
- * been finalized and APIs may change. Some features are
- * not fully implemented in this release. Use at your own risk.
- *  <p>
- *
- * @author  Justin Couch
- * @version $Revision: 1.1 $
- */
-class FileResourceStream extends URIResourceStream {
-
-    /**
-     * Explicit public constructor as required by java reflection.
-     * Currently does nothing.
-     */
-    public FileResourceStream() {
-    }
-
-    /**
-    * Open a connection for the given URI. The host and port arguments for
-    * this stream type are ignored. If a host is needed for a UNC name
-    * then that is included in the path.
-    *
-    * @param host The host name to connect to
-    * @param port The port on the host
-    * @param path The path needed to access the resource using the given protocol
-    * @exception IOException I/O errors reading from the stream
-    * @exception IllegalArgumentException host, port or URI were invalid
-    */
-    @Override
-    protected ResourceConnection openConnection(String host,
-                                          int port,
-                                          String path)
-        throws IOException, IllegalArgumentException {
-
-        ResourceConnection res = null;
-
-        try {
-            res = new FileResourceConnection(path);
-        } catch(MalformedURLException mue) {
-            throw new IllegalArgumentException("Cannot construct URL");
-        }
-
-        return res;
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2005
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.net.protocol;
+
+// External imports
+import java.io.IOException;
+import java.net.MalformedURLException;
+
+import org.ietf.uri.ResourceConnection;
+import org.ietf.uri.URIResourceStream;
+
+// Local imports
+// None
+
+/**
+ * A File protocol handler.
+ *  <p>
+ *
+ * The basic connection handler for dealing with URLs of the
+ * type <code>file:///</code> and URNs that resolve to items on the
+ * local filesystem.
+ *  <p>
+ *
+ * The path defines the object as needed from the root of the system.
+ * It must be fully qualified - including either machine names for
+ * UNC enunciated paths or drive letters where appropriate to the
+ * operating system.
+ *  <p>
+ *
+ * For details on URIs see the IETF working group:
+ * <a href="http://www.ietf.org/html.charters/urn-charter.html">URN</a>
+ *  <p>
+ *
+ * This software is released under the
+ * <a href="http://www.gnu.org/copyleft/lgpl.html">GNU LGPL</a>
+ *  <p>
+ *
+ * DISCLAIMER: <br>
+ * This software is the under development, incomplete, and is
+ * known to contain bugs. This software is made available for
+ * review purposes only. Do not rely on this software for
+ * production-quality applications or for mission-critical
+ * applications.
+ *  <p>
+ *
+ * Portions of the APIs for some new features have not
+ * been finalized and APIs may change. Some features are
+ * not fully implemented in this release. Use at your own risk.
+ *  <p>
+ *
+ * @author  Justin Couch
+ * @version $Revision: 1.1 $
+ */
+class FileResourceStream extends URIResourceStream {
+
+    /**
+     * Explicit public constructor as required by java reflection.
+     * Currently does nothing.
+     */
+    public FileResourceStream() {
+    }
+
+    /**
+    * Open a connection for the given URI. The host and port arguments for
+    * this stream type are ignored. If a host is needed for a UNC name
+    * then that is included in the path.
+    *
+    * @param host The host name to connect to
+    * @param port The port on the host
+    * @param path The path needed to access the resource using the given protocol
+    * @exception IOException I/O errors reading from the stream
+    * @exception IllegalArgumentException host, port or URI were invalid
+    */
+    @Override
+    protected ResourceConnection openConnection(String host,
+                                          int port,
+                                          String path)
+        throws IOException, IllegalArgumentException {
+
+        ResourceConnection res = null;
+
+        try {
+            res = new FileResourceConnection(path);
+        } catch(MalformedURLException mue) {
+            throw new IllegalArgumentException("Cannot construct URL");
+        }
+
+        return res;
+    }
+}
diff --git a/src/java/org/web3d/net/protocol/JarResourceFactory.java b/src/java/org/web3d/net/protocol/JarResourceFactory.java
index 3868154c9d021a13afa7444db370f7831e428530..284ab1358889e4a44088962de83368a5b3cb8082 100644
--- a/src/java/org/web3d/net/protocol/JarResourceFactory.java
+++ b/src/java/org/web3d/net/protocol/JarResourceFactory.java
@@ -23,8 +23,10 @@ import org.j3d.util.HashSet;
 
 /**
  * A factory for producing resources specific to VRML97/X3D.
+ *  <p>
  *
  * The factory supports handlers for the jar protocol types only.
+ *  <p>
  *
  * @author  Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/net/protocol/JarResourceStream.java b/src/java/org/web3d/net/protocol/JarResourceStream.java
index 3243d0dba16690ec9d1f19533ea180d774fc4732..73b25ad477e5060f2c0369cd4143c93e00019793 100644
--- a/src/java/org/web3d/net/protocol/JarResourceStream.java
+++ b/src/java/org/web3d/net/protocol/JarResourceStream.java
@@ -1,95 +1,95 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.net.protocol;
-
-// Standard imports
-import java.io.IOException;
-import java.net.MalformedURLException;
-
-import org.ietf.uri.URI;
-import org.ietf.uri.URIUtils;
-import org.ietf.uri.ResourceConnection;
-import org.ietf.uri.URIResourceStream;
-import org.ietf.uri.MalformedURNException;
-
-// Application specific imports
-// None
-
-/**
- * A JAR protocol handler.
- *  <p>
- *
- * The basic connection handler for dealing with URLs of the
- * type <code>jar:&lt;url&gt;!/&lt;entry&gt;</code> and URNs that resolve to
- * an item in a jar file.
- *  <p>
- *
- * The path defines the name of JAR file and the entry in that file. If no
- * file is defined, then the whole JAR file is referred to.
- *  <p>
- *
- * For details on URIs see the IETF working group:
- * <a href="http://www.ietf.org/html.charters/urn-charter.html">URN</a>
- *  <p>
- *
- * @author  Justin Couch
- * @version $Revision: 1.1 $
- */
-class JarResourceStream extends URIResourceStream {
-    /**
-     * Explicit public constructor as required by java reflection.
-     * Currently does nothing.
-     */
-    JarResourceStream() {
-    }
-
-    /**
-     * Open a connection for the given URI. The host and port arguments for
-     * this stream type are ignored. If a host is needed for a UNC name
-     * then that is included in the path.
-     *
-     * @param host The host name to connect to
-     * @param port The port on the host
-     * @param path The path needed to access the resource using the given protocol
-     * @exception IOException I/O errors reading from the stream
-     * @exception IllegalArgumentException host, port or URI were invalid
-     */
-    @Override
-    protected ResourceConnection openConnection(String host,
-                                                int port,
-                                                String path)
-        throws IOException, IllegalArgumentException {
-
-        ResourceConnection res = null;
-
-        // split the path into the two parts
-        int index = path.indexOf('!');
-        String uri_str = path.substring(0, index);
-        String entry = null;
-
-        if(path.length() > index + 1)
-            entry = path.substring(index + 2);
-
-        try {
-            URI uri = URIUtils.createURI(uri_str);
-
-            res = new JarResourceConnection(uri, entry);
-        } catch(MalformedURLException mue) {
-            throw new IllegalArgumentException("Cannot construct JAR file URL");
-        } catch(MalformedURNException mne) {
-            throw new IllegalArgumentException("Cannot construct JAR file URN");
-        }
-
-        return res;
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.net.protocol;
+
+// Standard imports
+import java.io.IOException;
+import java.net.MalformedURLException;
+
+import org.ietf.uri.URI;
+import org.ietf.uri.URIUtils;
+import org.ietf.uri.ResourceConnection;
+import org.ietf.uri.URIResourceStream;
+import org.ietf.uri.MalformedURNException;
+
+// Application specific imports
+// None
+
+/**
+ * A JAR protocol handler.
+ *  <p>
+ *
+ * The basic connection handler for dealing with URLs of the
+ * type <code>jar:&lt;url&gt;!/&lt;entry&gt;</code> and URNs that resolve to
+ * an item in a jar file.
+ *  <p>
+ *
+ * The path defines the name of JAR file and the entry in that file. If no
+ * file is defined, then the whole JAR file is referred to.
+ *  <p>
+ *
+ * For details on URIs see the IETF working group:
+ * <a href="http://www.ietf.org/html.charters/urn-charter.html">URN</a>
+ *  <p>
+ *
+ * @author  Justin Couch
+ * @version $Revision: 1.1 $
+ */
+class JarResourceStream extends URIResourceStream {
+    /**
+     * Explicit public constructor as required by java reflection.
+     * Currently does nothing.
+     */
+    JarResourceStream() {
+    }
+
+    /**
+     * Open a connection for the given URI. The host and port arguments for
+     * this stream type are ignored. If a host is needed for a UNC name
+     * then that is included in the path.
+     *
+     * @param host The host name to connect to
+     * @param port The port on the host
+     * @param path The path needed to access the resource using the given protocol
+     * @exception IOException I/O errors reading from the stream
+     * @exception IllegalArgumentException host, port or URI were invalid
+     */
+    @Override
+    protected ResourceConnection openConnection(String host,
+                                                int port,
+                                                String path)
+        throws IOException, IllegalArgumentException {
+
+        ResourceConnection res = null;
+
+        // split the path into the two parts
+        int index = path.indexOf('!');
+        String uri_str = path.substring(0, index);
+        String entry = null;
+
+        if(path.length() > index + 1)
+            entry = path.substring(index + 2);
+
+        try {
+            URI uri = URIUtils.createURI(uri_str);
+
+            res = new JarResourceConnection(uri, entry);
+        } catch(MalformedURLException mue) {
+            throw new IllegalArgumentException("Cannot construct JAR file URL");
+        } catch(MalformedURNException mne) {
+            throw new IllegalArgumentException("Cannot construct JAR file URN");
+        }
+
+        return res;
+    }
+}
diff --git a/src/java/org/web3d/net/protocol/JavascriptResourceConnection.java b/src/java/org/web3d/net/protocol/JavascriptResourceConnection.java
index 6be2a529f8dec902a33ac6b0b4b0a9dc4b898657..ef770b9a028fd78c92c4693d38358a20f7fe410c 100644
--- a/src/java/org/web3d/net/protocol/JavascriptResourceConnection.java
+++ b/src/java/org/web3d/net/protocol/JavascriptResourceConnection.java
@@ -1,158 +1,158 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.net.protocol;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.IOException;
-
-import java.net.MalformedURLException;
-
-import org.ietf.uri.URL;
-import org.ietf.uri.ResourceConnection;
-
-/**
- * Representation of a Javascript/ECMAScript resource.
- *  <p>
- *
- * Implements the connection as a standard byte input stream. The javascript
- * protocol defined by the VRML97 specification allows you to inline the script
- * information. Therefore, for this system we just strip the protocol prefix
- * from the incoming URL and return the rest of the information as the input
- * stream.
- *  <p>
- *
- * We have a number of limitations on the data supplied. From the base string
- * there is no way to determine the encoding type. This, in turn leads us to
- * generate an output stream of a byte array. When the content handler grabs
- * that stream, we don't know what the original encoding was and so
- * re-interpret the string contents using the default from the platform. This
- * will trash the original string's characters. Not good. Not sure of a good
- * way around this yet.
- *  <p>
- *
- * This connection only supports input streams. The last modified time is not
- * known and always returns the default value.
- *  <p>
- *
- * For details on URIs see the IETF working group:
- * <a href="http://www.ietf.org/html.charters/urn-charter.html">URN</a>
- *  <p>
- *
- * This software is released under the
- * <a href="http://www.gnu.org/copyleft/lgpl.html">GNU LGPL</a>
- *  <p>
- *
- * @author  Justin Couch
- * @version $Revision: 1.2 $
- */
-class JavascriptResourceConnection extends ResourceConnection {
-
-    /** The default content type if none is supplied */
-    private static final String DEFAULT_CONTENT_TYPE = "application/x-javascript";
-
-    /** Alternate protocol type if the user defines ECMAScript as the protocol */
-    private static final String ECMA_CONTENT_TYPE = "application/ecmascript";
-
-    /** The parsed data after having header data removed */
-    private String script;
-
-    /** The content type of the data */
-    private String contentType = DEFAULT_CONTENT_TYPE;
-
-    /** The length of the content if we know what it is */
-    private int contentLength = -1;
-
-    /** Stream containing the current data */
-    private InputStream stream;
-
-    /**
-     * Create an instance of this connection.
-     *
-     * @param uri The URI to establish the connection to
-     * @exception MalformedURLException We stuffed up something in the filename
-     */
-    JavascriptResourceConnection(boolean isEcma, URL url, String path)
-        throws MalformedURLException {
-
-        super(url);
-
-
-        script = path;
-
-        // Not necessarily correct, but good first approximation
-        contentLength = path.length();
-
-        if(isEcma)
-            contentType = ECMA_CONTENT_TYPE;
-    }
-
-    /**
-     * Get the input stream for this.
-     *
-     * @return The stream
-     */
-    @Override
-    public InputStream getInputStream() throws IOException {
-        // convertn the stream to
-        if(stream == null) {
-            stream = new ByteArrayInputStream(script.substring(11).getBytes());
-            contentLength = stream.available();
-        }
-
-        return stream;
-    }
-
-    /**
-     * Get the content type of the resource that this stream points to.
-     * Returns a standard MIME type string. If the content type is not known then
-     * <code>text/plain</code> is returned (the default for data protocol).
-     *
-     * @return The content type of this resource
-     */
-    @Override
-    public String getContentType() {
-        return contentType;
-    }
-
-    /**
-     * Connect to the named resource if not already connected. This is ignored
-     * by this implementation.
-     *
-     * @exception An error occurred during the connection process
-     */
-    @Override
-    public void connect() throws IOException {
-    }
-
-    /**
-     * Get the length of the content that is to follow on the stream. If the
-     * length is unknown then -1 is returned. The content length could be the
-     * the length of the raw stream or the object. Don't know yet????
-     *
-     * @return The length of the content in bytes or -1
-     */
-    @Override
-    public int getContentLength() {
-        try {
-          getInputStream();
-        } catch(IOException ioe) {
-          contentLength = -1;
-        }
-
-        // we could do some intelligent guessing here by looking to see if the
-        // getContent returns an array and then return that??
-        return contentLength;
-    }
-
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.net.protocol;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+
+import java.net.MalformedURLException;
+
+import org.ietf.uri.URL;
+import org.ietf.uri.ResourceConnection;
+
+/**
+ * Representation of a Javascript/ECMAScript resource.
+ *  <p>
+ *
+ * Implements the connection as a standard byte input stream. The javascript
+ * protocol defined by the VRML97 specification allows you to inline the script
+ * information. Therefore, for this system we just strip the protocol prefix
+ * from the incoming URL and return the rest of the information as the input
+ * stream.
+ *  <p>
+ *
+ * We have a number of limitations on the data supplied. From the base string
+ * there is no way to determine the encoding type. This, in turn leads us to
+ * generate an output stream of a byte array. When the content handler grabs
+ * that stream, we don't know what the original encoding was and so
+ * re-interpret the string contents using the default from the platform. This
+ * will trash the original string's characters. Not good. Not sure of a good
+ * way around this yet.
+ *  <p>
+ *
+ * This connection only supports input streams. The last modified time is not
+ * known and always returns the default value.
+ *  <p>
+ *
+ * For details on URIs see the IETF working group:
+ * <a href="http://www.ietf.org/html.charters/urn-charter.html">URN</a>
+ *  <p>
+ *
+ * This software is released under the
+ * <a href="http://www.gnu.org/copyleft/lgpl.html">GNU LGPL</a>
+ *  <p>
+ *
+ * @author  Justin Couch
+ * @version $Revision: 1.2 $
+ */
+class JavascriptResourceConnection extends ResourceConnection {
+
+    /** The default content type if none is supplied */
+    private static final String DEFAULT_CONTENT_TYPE = "application/x-javascript";
+
+    /** Alternate protocol type if the user defines ECMAScript as the protocol */
+    private static final String ECMA_CONTENT_TYPE = "application/ecmascript";
+
+    /** The parsed data after having header data removed */
+    private String script;
+
+    /** The content type of the data */
+    private String contentType = DEFAULT_CONTENT_TYPE;
+
+    /** The length of the content if we know what it is */
+    private int contentLength = -1;
+
+    /** Stream containing the current data */
+    private InputStream stream;
+
+    /**
+     * Create an instance of this connection.
+     *
+     * @param uri The URI to establish the connection to
+     * @exception MalformedURLException We stuffed up something in the filename
+     */
+    JavascriptResourceConnection(boolean isEcma, URL url, String path)
+        throws MalformedURLException {
+
+        super(url);
+
+
+        script = path;
+
+        // Not necessarily correct, but good first approximation
+        contentLength = path.length();
+
+        if(isEcma)
+            contentType = ECMA_CONTENT_TYPE;
+    }
+
+    /**
+     * Get the input stream for this.
+     *
+     * @return The stream
+     */
+    @Override
+    public InputStream getInputStream() throws IOException {
+        // convertn the stream to
+        if(stream == null) {
+            stream = new ByteArrayInputStream(script.substring(11).getBytes());
+            contentLength = stream.available();
+        }
+
+        return stream;
+    }
+
+    /**
+     * Get the content type of the resource that this stream points to.
+     * Returns a standard MIME type string. If the content type is not known then
+     * <code>text/plain</code> is returned (the default for data protocol).
+     *
+     * @return The content type of this resource
+     */
+    @Override
+    public String getContentType() {
+        return contentType;
+    }
+
+    /**
+     * Connect to the named resource if not already connected. This is ignored
+     * by this implementation.
+     *
+     * @exception An error occurred during the connection process
+     */
+    @Override
+    public void connect() throws IOException {
+    }
+
+    /**
+     * Get the length of the content that is to follow on the stream. If the
+     * length is unknown then -1 is returned. The content length could be the
+     * the length of the raw stream or the object. Don't know yet????
+     *
+     * @return The length of the content in bytes or -1
+     */
+    @Override
+    public int getContentLength() {
+        try {
+          getInputStream();
+        } catch(IOException ioe) {
+          contentLength = -1;
+        }
+
+        // we could do some intelligent guessing here by looking to see if the
+        // getContent returns an array and then return that??
+        return contentLength;
+    }
+
+}
diff --git a/src/java/org/web3d/net/protocol/JavascriptResourceFactory.java b/src/java/org/web3d/net/protocol/JavascriptResourceFactory.java
index 698bc4e58bf023b9b4f844f3d4c2317608be8790..ae506d0a1bb232b769393114e9b2a4ab7ca265a3 100644
--- a/src/java/org/web3d/net/protocol/JavascriptResourceFactory.java
+++ b/src/java/org/web3d/net/protocol/JavascriptResourceFactory.java
@@ -1,85 +1,88 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.net.protocol;
-
-// Standard imports
-import org.ietf.uri.URIResourceStream;
-import org.ietf.uri.URIResourceStreamFactory;
-
-// Application specific imports
-import org.j3d.util.HashSet;
-
-/**
- * A factory for producing resources specific to VRML97/X3D.
- *
- * The current factory supports handlers for the javascript and ecmascript
- * protocol types.
- *
- * This software is released under the
- * <a href="http://www.gnu.org/copyleft/lgpl.html">GNU LGPL</a>
- *
- * @author  Justin Couch
- * @version $Revision: 1.3 $
- */
-public class JavascriptResourceFactory implements URIResourceStreamFactory {
-
-    /** Set containing the supported protocol types */
-    private static final HashSet<String> supportedTypes;
-
-    /** Reference to the next factory to delegate too if needed */
-    private URIResourceStreamFactory nestedFactory;
-
-    /**
-     * Static initialiser to set up the supported types.
-     */
-    static {
-        supportedTypes = new HashSet<>();
-        supportedTypes.add("ecmascript");
-        supportedTypes.add("javascript");
-    }
-
-    /**
-     * Create a new instance of the factory that uses the nested factory
-     * for anything this instance cannot support. Use a value of null if
-     * not used.
-     *
-     * @param fac The factory instance to be used
-     */
-    public JavascriptResourceFactory(URIResourceStreamFactory fac) {
-        nestedFactory = fac;
-    }
-
-    /**
-     * Create a new resource stream for the given protocol. If none of the
-     * factories support it, return null.
-     *
-     * @param protocol The protocol handler
-     * @return A new resource stream as needed or null
-     */
-    @Override
-    public URIResourceStream createURIResourceStream(String protocol) {
-
-        URIResourceStream ret_val = null;
-
-        // check if it is one of our local types
-        if(supportedTypes.contains(protocol)) {
-            boolean ecma = protocol.equals("ecmascript");
-            ret_val = new JavascriptResourceStream(ecma);
-        } else if(nestedFactory != null) {
-            // no? check the nested factory
-            ret_val = nestedFactory.createURIResourceStream(protocol);
-        }
-
-        return ret_val;
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.net.protocol;
+
+// Standard imports
+import org.ietf.uri.URIResourceStream;
+import org.ietf.uri.URIResourceStreamFactory;
+
+// Application specific imports
+import org.j3d.util.HashSet;
+
+/**
+ * A factory for producing resources specific to VRML97/X3D.
+ *  <p>
+ *
+ * The current factory supports handlers for the javascript and ecmascript
+ * protocol types.
+ *  <p>
+ *
+ * This software is released under the
+ * <a href="http://www.gnu.org/copyleft/lgpl.html">GNU LGPL</a>
+ *  <p>
+ *
+ * @author  Justin Couch
+ * @version $Revision: 1.3 $
+ */
+public class JavascriptResourceFactory implements URIResourceStreamFactory {
+
+    /** Set containing the supported protocol types */
+    private static final HashSet<String> supportedTypes;
+
+    /** Reference to the next factory to delegate too if needed */
+    private URIResourceStreamFactory nestedFactory;
+
+    /**
+     * Static initialiser to set up the supported types.
+     */
+    static {
+        supportedTypes = new HashSet<>();
+        supportedTypes.add("ecmascript");
+        supportedTypes.add("javascript");
+    }
+
+    /**
+     * Create a new instance of the factory that uses the nested factory
+     * for anything this instance cannot support. Use a value of null if
+     * not used.
+     *
+     * @param fac The factory instance to be used
+     */
+    public JavascriptResourceFactory(URIResourceStreamFactory fac) {
+        nestedFactory = fac;
+    }
+
+    /**
+     * Create a new resource stream for the given protocol. If none of the
+     * factories support it, return null.
+     *
+     * @param protocol The protocol handler
+     * @return A new resource stream as needed or null
+     */
+    @Override
+    public URIResourceStream createURIResourceStream(String protocol) {
+
+        URIResourceStream ret_val = null;
+
+        // check if it is one of our local types
+        if(supportedTypes.contains(protocol)) {
+            boolean ecma = protocol.equals("ecmascript");
+            ret_val = new JavascriptResourceStream(ecma);
+        } else if(nestedFactory != null) {
+            // no? check the nested factory
+            ret_val = nestedFactory.createURIResourceStream(protocol);
+        }
+
+        return ret_val;
+    }
+}
diff --git a/src/java/org/web3d/net/protocol/JavascriptResourceStream.java b/src/java/org/web3d/net/protocol/JavascriptResourceStream.java
index 14dd82c63c364fb8e9113325817926e9f97827ff..61025869d6b76029e4d59f7047ecc448e5c3a6aa 100644
--- a/src/java/org/web3d/net/protocol/JavascriptResourceStream.java
+++ b/src/java/org/web3d/net/protocol/JavascriptResourceStream.java
@@ -1,69 +1,69 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.net.protocol;
-
-import java.io.IOException;
-
-import org.ietf.uri.ResourceConnection;
-import org.ietf.uri.UnknownProtocolException;
-import org.ietf.uri.URIResourceStream;
-import org.ietf.uri.URL;
-
-/**
- * A factory for producing resources specific to VRML97/X3D.
- *  <p>
- *
- * The current factory supports handlers for the javascript and ecmascript
- * protocol types. Because these protocols have the content type inlined
- * into string, the factory ignores the host and port parameters.
- *  <p>
- *
- * For details on URIs see the IETF working group:
- * <a href="http://www.ietf.org/html.charters/urn-charter.html">URN</a>
- *  <p>
- *
- * This software is released under the
- * <a href="http://www.gnu.org/copyleft/lgpl.html">GNU LGPL</a>
- *  <p>
- *
- * @author  Justin Couch
- * @version $Revision: 1.1 $
- */
-class JavascriptResourceStream extends URIResourceStream {
-
-    /** Flag to indicate if this is an ecmascript or javascipt connection */
-    private boolean useEcma;
-
-    JavascriptResourceStream(boolean isEcma) {
-        useEcma = isEcma;
-    }
-
-    @Override
-    public ResourceConnection openConnection(String host,
-                                             int port,
-                                             String path)
-        throws UnknownProtocolException,
-               IOException,
-               IllegalArgumentException {
-
-        ResourceConnection ret_val;
-
-        // check if it is one of our local types
-        String url_str = (useEcma ? "ecmascript:" : "javascript:") + path;
-        URL url = new URL(url_str);
-
-        ret_val = new JavascriptResourceConnection(useEcma, url, path);
-
-        return ret_val;
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.net.protocol;
+
+import java.io.IOException;
+
+import org.ietf.uri.ResourceConnection;
+import org.ietf.uri.UnknownProtocolException;
+import org.ietf.uri.URIResourceStream;
+import org.ietf.uri.URL;
+
+/**
+ * A factory for producing resources specific to VRML97/X3D.
+ *  <p>
+ *
+ * The current factory supports handlers for the javascript and ecmascript
+ * protocol types. Because these protocols have the content type inlined
+ * into string, the factory ignores the host and port parameters.
+ *  <p>
+ *
+ * For details on URIs see the IETF working group:
+ * <a href="http://www.ietf.org/html.charters/urn-charter.html">URN</a>
+ *  <p>
+ *
+ * This software is released under the
+ * <a href="http://www.gnu.org/copyleft/lgpl.html">GNU LGPL</a>
+ *  <p>
+ *
+ * @author  Justin Couch
+ * @version $Revision: 1.1 $
+ */
+class JavascriptResourceStream extends URIResourceStream {
+
+    /** Flag to indicate if this is an ecmascript or javascipt connection */
+    private boolean useEcma;
+
+    JavascriptResourceStream(boolean isEcma) {
+        useEcma = isEcma;
+    }
+
+    @Override
+    public ResourceConnection openConnection(String host,
+                                             int port,
+                                             String path)
+        throws UnknownProtocolException,
+               IOException,
+               IllegalArgumentException {
+
+        ResourceConnection ret_val;
+
+        // check if it is one of our local types
+        String url_str = (useEcma ? "ecmascript:" : "javascript:") + path;
+        URL url = new URL(url_str);
+
+        ret_val = new JavascriptResourceConnection(useEcma, url, path);
+
+        return ret_val;
+    }
+}
diff --git a/src/java/org/web3d/net/protocol/VRML97ResourceFactory.java b/src/java/org/web3d/net/protocol/VRML97ResourceFactory.java
index 2d5ac8245642c4ccaf8e9a8ec63e4acc740f37a2..4973e1f0525746b0e901176195f8cc16dcd26abb 100644
--- a/src/java/org/web3d/net/protocol/VRML97ResourceFactory.java
+++ b/src/java/org/web3d/net/protocol/VRML97ResourceFactory.java
@@ -21,9 +21,11 @@ import org.j3d.util.HashSet;
 
 /**
  * A factory for producing resources specific to VRML97-only.
+ *  <p>
  *
  * The current factory supports handlers for the ecmascript and jar
  * protocol types.
+ *  <p>
  *
  * @author  Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/net/protocol/Web3DResourceFactory.java b/src/java/org/web3d/net/protocol/Web3DResourceFactory.java
index 140cf72aabbb7e70e54e8943de5c6ea47c7114ce..901f1625dcea6110759482981d685175f223e2c9 100644
--- a/src/java/org/web3d/net/protocol/Web3DResourceFactory.java
+++ b/src/java/org/web3d/net/protocol/Web3DResourceFactory.java
@@ -22,9 +22,11 @@ import org.j3d.util.HashSet;
 
 /**
  * A factory for producing resources specific to Web3D-only.
+ *  <p>
  *
  * The current factory supports handlers for the ecmascript and jar
  * protocol types.
+ *  <p>
  *
  * @author  Justin Couch
  * @version $Revision: 1.4 $
diff --git a/src/java/org/web3d/net/protocol/X3DResourceFactory.java b/src/java/org/web3d/net/protocol/X3DResourceFactory.java
index 69b5874ee69b86db0111660d304fc0931b46773d..5c0b5f07cc7ab27eb9ec0d918760badc6d267247 100644
--- a/src/java/org/web3d/net/protocol/X3DResourceFactory.java
+++ b/src/java/org/web3d/net/protocol/X3DResourceFactory.java
@@ -21,9 +21,11 @@ import org.j3d.util.HashSet;
 
 /**
  * A factory for producing resources specific to X3D-only.
+ *  <p>
  *
  * The current factory supports handlers for the ecmascript and jar
  * protocol types.
+ *  <p>
  *
  * @author  Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/net/resolve/Web3DURNResolver.java b/src/java/org/web3d/net/resolve/Web3DURNResolver.java
index c733ddad182f269da501caac45e6ce97922b7b0e..92d41891b7ed70d7450c28593a1f029c65d979aa 100644
--- a/src/java/org/web3d/net/resolve/Web3DURNResolver.java
+++ b/src/java/org/web3d/net/resolve/Web3DURNResolver.java
@@ -29,6 +29,7 @@ import org.j3d.util.ErrorReporter;
 /**
  * A URN resolver to allow the integration of URNs that use the
  * <code>web3d</code> Namespace ID.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.4 $
diff --git a/src/java/org/web3d/parser/DefaultFieldParserFactory.java b/src/java/org/web3d/parser/DefaultFieldParserFactory.java
index 662b6a03b53780ae21c27e68cb0828bf34e1c368..12be053336eb0c36f6a13068beb6695970a592ce 100644
--- a/src/java/org/web3d/parser/DefaultFieldParserFactory.java
+++ b/src/java/org/web3d/parser/DefaultFieldParserFactory.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.parser.VRMLFieldReader;
 
 /**
  * Representation of a parser factory for field content.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/parser/vrml97/VRML97FieldReader.java b/src/java/org/web3d/parser/vrml97/VRML97FieldReader.java
index f10691478ef6ca885ece0338cc1ede109573428c..6331ffbbbf4efb7c71af4b99f28e44198e8bc927 100644
--- a/src/java/org/web3d/parser/vrml97/VRML97FieldReader.java
+++ b/src/java/org/web3d/parser/vrml97/VRML97FieldReader.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.sav.Locator;
 /**
  * The default field parser implementation class for raw field values to turn
  * them into Java primitive types.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.9 $
diff --git a/src/java/org/web3d/parser/x3d/FastInfosetElementReader.java b/src/java/org/web3d/parser/x3d/FastInfosetElementReader.java
index 4acac951cdefa5bb39b7311c27ae6e05cd161542..b3086496405c4cd6ace24dd20173385c9a5b6189 100644
--- a/src/java/org/web3d/parser/x3d/FastInfosetElementReader.java
+++ b/src/java/org/web3d/parser/x3d/FastInfosetElementReader.java
@@ -1,1044 +1,1044 @@
-/*****************************************************************************
- *                        Web3d Consortium Copyright (c) 2005
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- *****************************************************************************/
-
-package org.web3d.parser.x3d;
-
-// External imports
-import org.xml.sax.SAXException;
-import org.xml.sax.Attributes;
-
-import com.sun.xml.fastinfoset.sax.AttributesHolder;
-
-import org.jvnet.fastinfoset.EncodingAlgorithmIndexes;
-import org.jvnet.fastinfoset.sax.PrimitiveTypeContentHandler;
-import org.jvnet.fastinfoset.sax.EncodingAlgorithmContentHandler;
-
-// Local imports
-import org.web3d.util.*;
-import org.web3d.vrml.sav.*;
-
-import org.web3d.vrml.lang.InvalidFieldException;
-import org.web3d.x3d.jaxp.X3DSAVAdapter;
-import org.web3d.vrml.export.compressors.NodeCompressor;
-//import org.web3d.vrml.export.compressors.TestCompressor;
-
-/**
- * Handles the reading of elements from a FastInfoSet stream and converts
- * it to an X3D world.
- *
- * This expects attributes of type TypeAttributes instead of just Attributes.
- *
- * @author Alan Hudson
- * @version $Revision: 1.15 $
- */
-class FastInfosetElementReader extends X3DSAVAdapter
-    implements PrimitiveTypeContentHandler, EncodingAlgorithmContentHandler {
-
-    private BooleanStack inCompressorStack;
-
-    private BooleanStack skipEEStack;
-
-    private NodeCompressor currentCompressor;
-
-    private String lastNodeName;
-
-    private boolean skipEndElement;
-
-    /** After the payload any metadata is ignored */
-    private boolean pastPayload;
-
-    /** Switch between methods, should go away */
-    private boolean compressedAttWay = false;
-
-    /**
-     * Initialise a new instance of the reader
-     */
-    FastInfosetElementReader() {
-
-        inCompressorStack = new BooleanStack();
-        inCompressorStack.push(false);
-
-        skipEEStack = new BooleanStack();
-    }
-
-    /**
-     * Start the processing of a new element with the given collection of
-     * attribute information.
-     *
-     * @param namespace The namespace for the element. Null if not used
-     * @param name The local name of the element to create
-     * @param qName The qualified name of the element including prefix
-     * @param attribs The collection of attributes to use
-     * @throws SAXException The element can't be found in the underlying
-     *     factory
-     */
-    @Override
-    public void startElement(String namespace,
-                             String localName,
-                             String qName,
-                             Attributes attribs)
-        throws SAXException {
-
-//System.out.println("SE: " + qName);
-        boolean inCompressor = inCompressorStack.peek();
-
-        if(useIsCurrent)
-            throw new SAXException(USE_WITH_KIDS_MSG);
-
-        // Remove X3D: namespace prefix.  Need to handle generically
-        if(qName.startsWith("X3D:"))
-            qName = qName.substring(4);
-
-        Integer el_type = elementMap.get(qName);
-
-        String value;
-        AttributesHolder atts = (AttributesHolder) attribs;
-        BinaryContentHandler bch = (BinaryContentHandler) contentHandler;
-
-        // TODO: Would a HashMap be faster here?
-        if (qName.equals("MetadataSet")) {
-            String name = attribs.getValue("name");
-
-            if (name.equals(".x3db")) {
-                // Pop Parents inCompressor and replace with true
-                inCompressorStack.pop();
-                inCompressorStack.push(true);
-                inCompressor = true;
-
-                inCompressorStack.push(inCompressor);
-                skipEEStack.push(true);
-                pastPayload = false;
-                return;
-            } else if (pastPayload) {
-                pastPayload = false;
-
-                inCompressorStack.push(inCompressor);
-                skipEEStack.push(true);
-
-                return;
-            }
-        }
-
-        if (inCompressor) {
-            String name = attribs.getValue("name");
-
-            if (name != null) {
-                switch (name) {
-                    case "encoding":
-                        //                    currentCompressor = new TestCompressor();
-
-                        inCompressorStack.push(inCompressor);
-                        skipEEStack.push(true);
-                        return;
-                    case "payload":
-                        int idx = attribs.getIndex("value");
-                        int algo = atts.getAlgorithmIndex(idx);
-
-                        switch (algo) {
-                            case EncodingAlgorithmIndexes.INT:
-                                int[] ival = (int[]) atts.getAlgorithmData(idx);
-                                currentCompressor.decompress(ival);
-                                currentCompressor.fillData(lastNodeName, bch);
-                                break;
-                            case X3DBinaryConstants.DELTA_ZLIB_INT_ARRAY_ALGORITHM_ID:
-                                int[] i4val = (int[]) atts.getAlgorithmData(idx);
-                                currentCompressor.decompress(i4val);
-                                currentCompressor.fillData(lastNodeName, bch);
-                                break;
-                            default:
-                                errorReporter.errorReport("Data in wrong format! " +
-                                        atts.getAlgorithmIndex(idx),
-                                        null);
-                                break;
-                        }
-
-                        pastPayload = true;
-                        inCompressorStack.push(inCompressor);
-                        skipEEStack.push(true);
-                    return;
-
-                }
-            }
-        } else {
-            lastNodeName = qName;
-        }
-
-        if(el_type == null) {
-            if(checkForSceneTag)
-                throw new SAXException(NO_SCENE_TAG_MSG);
-
-            // We're obviously in a new node, so go look for
-            // the container field attribute to do a "startField"
-            // call. However, no point doing anything if we don't have a
-            // content handler to call. Need to weed out the one case were
-            // we are the root node of a proto declaration body.
-
-            if(fieldDeclDepth != 0) {
-                String field_name = attribs.getValue(CONTAINER_ATTR);
-
-                // No container field name defined? Look one up. If that
-                // fails, guess and put in "children" since that is the
-                // most commonly used default.
-                if(field_name == null) {
-                    field_name = containerFields.getProperty(qName);
-
-                    if(field_name == null)
-                        field_name = "children";
-                }
-
-                if(contentHandler != null) {
-                    try {
-                        contentHandler.startField(field_name);
-                    } catch(InvalidFieldException ife) {
-                       errorReporter.errorReport("No field: " + field_name +
-                                                 " for: " + qName,
-                                                 null);
-                    }
-                }
-
-            }
-
-            value = attribs.getValue(USE_ATTR);
-            fieldDeclDepth++;
-
-            if(value != null) {
-                if(contentHandler != null)
-                    contentHandler.useDecl(value);
-                useIsCurrent = true;
-            } else {
-                value = attribs.getValue(DEF_ATTR);
-                if(contentHandler != null)
-                    contentHandler.startNode(qName, value);
-            }
-
-            Object type;
-            String att_name;
-            Integer id_int;
-
-/*
-            if (inCompressor) {
-                currentCompressor.fillData(qName, bch);
-            }
-*/
-            // now process all the attributes!
-            int num_attr = attribs.getLength();
-            for(int i = 0; !useIsCurrent && i < num_attr; i++) {
-                att_name = atts.getLocalName(i);
-//System.out.println("att_name: " + att_name);
-                switch (att_name) {
-                    case "encoder":
-                        // TODO: make hashmap
-                        if (atts.getValue(i).equals("1")) {
-                            inCompressor = true;
-
-//                        currentCompressor = new TestCompressor();
-                        }
-                        continue;
-                    case "data":
-                        type = atts.getAlgorithmData(i);
-
-                        if (atts.getAlgorithmIndex(i) == EncodingAlgorithmIndexes.INT) {
-                            // TODO: Assume all INT's are arrays
-                            int[] ival = (int[]) atts.getAlgorithmData(i);
-                            currentCompressor.decompress(ival);
-                            currentCompressor.fillData(qName, bch);
-
-                        } else {
-                            errorReporter.errorReport("Data in wrong format!", null);
-                        }
-
-                    continue;
-                }
-
-                // Check to see if the attribute is one of the reserved
-                // set. If so, treat separately from the normal field
-                // processing.
-                id_int = attributeMap.get(att_name);
-
-                if (id_int != null) {
-                    continue;
-                }
-
-                decodeField(atts,i,bch,att_name);
-            }
-
-            inCompressorStack.push(inCompressor);
-            skipEEStack.push(false);
-
-            return;
-        }
-
-        switch(el_type) {
-            case X3D_TAG:
-                loadContainerProperties(Float.parseFloat(versionString.substring(1)));
-
-                String version = attribs.getValue("version");
-
-                if (version == null) {
-                    version = "V3.0";
-                } else {
-                    version = "V" + version;
-                }
-
-                if(contentHandler != null) {
-                    contentHandler.startDocument(null,  // TODO: Not sure how to get filename
-                                                 worldURL,
-                                                 XML_ENCODING,
-                                                 "#X3D",
-                                                 version,
-                                                 null);
-                }
-
-                value = attribs.getValue("profile");
-
-                if(value == null)
-                    throw new SAXException(NO_PROFILE_MSG);
-
-                if(contentHandler != null)
-                    contentHandler.profileDecl(value);
-
-                // Setup cData
-                if(overrideLex)
-                    characterDataBuffer.append("\"");
-
-                useIsCurrent = false;
-                checkForSceneTag = true;
-                break;
-
-            case HEAD_TAG:
-                // do nothing
-                break;
-
-            case COMPONENT_TAG:
-                value = attribs.getValue(NAME_ATTR) + ':' +
-                        attribs.getValue("level");
-                if(contentHandler != null)
-                    contentHandler.componentDecl(value);
-                break;
-
-            case SCENE_TAG:
-                checkForSceneTag = false;
-                break;
-
-            case PROTO_DECL_TAG:
-                if(checkForSceneTag)
-                    throw new SAXException(NO_SCENE_TAG_MSG);
-
-                if(protoHandler != null)
-                    protoHandler.startProtoDecl(attribs.getValue(NAME_ATTR));
-
-                scriptFlagStack.push(false);
-                inScript = false;
-                break;
-
-            case PROTO_INTERFACE_TAG:
-                if(checkForSceneTag)
-                    throw new SAXException(NO_SCENE_TAG_MSG);
-
-                // Don't do anything from here. We've already started the
-                // proto decl handling in the PROTO_DECL_TAG.
-                break;
-
-            case PROTO_BODY_TAG:
-                if(checkForSceneTag)
-                    throw new SAXException(NO_SCENE_TAG_MSG);
-
-                if(protoHandler != null) {
-                    protoHandler.endProtoDecl();
-                    protoHandler.startProtoBody();
-                }
-
-                break;
-
-            case EXTERNPROTO_DECL_TAG:
-                if(checkForSceneTag)
-                    throw new SAXException(NO_SCENE_TAG_MSG);
-
-                if(protoHandler != null) {
-                    value = attribs.getValue(NAME_ATTR);
-                    protoHandler.startExternProtoDecl(value);
-
-                    epUrl = attribs.getValue("url");
-
-                }
-
-                scriptFlagStack.push(false);
-                inScript = false;
-
-                break;
-
-            case IS_TAG:
-                if(checkForSceneTag)
-                    throw new SAXException(NO_SCENE_TAG_MSG);
-
-                break;
-
-            case CONNECT_TAG:
-                if(checkForSceneTag)
-                    throw new SAXException(NO_SCENE_TAG_MSG);
-
-                if(contentHandler != null)
-                    contentHandler.startField(attribs.getValue("nodeField"));
-
-                if(protoHandler != null)
-                    protoHandler.protoIsDecl(attribs.getValue("protoField"));
-                break;
-
-            case FIELD_TAG:
-                if(checkForSceneTag)
-                    throw new SAXException(NO_SCENE_TAG_MSG);
-
-                int access_type =
-                    processFieldAccess(attribs.getValue("accessType"), attribs.getValue(NAME_ATTR));
-
-                // perhaps this should do some prior checking of the
-                // access type to make sure that the user don't do anything
-                // dumb like set a value for eventIn/Out.
-                boolean is_used = false;
-                depthCountStack.push(fieldDeclDepth);
-                fieldDeclDepth = 0;
-
-                if((value = attribs.getValue("USE")) != null)
-                    is_used = true;
-                else
-                    value = attribs.getValue(VALUE_ATTR);
-
-                if(inScript) {
-                    if(is_used) {
-                        if(scriptHandler != null) {
-                            scriptHandler.scriptFieldDecl(access_type,
-                                                          attribs.getValue("type"),
-                                                          attribs.getValue(NAME_ATTR),
-                                                          null);
-                        }
-
-                        if(contentHandler != null)
-                            contentHandler.useDecl(value);
-                    } else {
-                        if (value != null && value.length() == 0) {
-                            value = null;
-                        }
-
-                        if(scriptHandler != null)
-                            scriptHandler.scriptFieldDecl(access_type,
-                                                          attribs.getValue("type"),
-                                                          attribs.getValue(NAME_ATTR),
-                                                          value);
-                    }
-                } else {
-                    if(is_used) {
-                        if(protoHandler != null) {
-                            protoHandler.protoFieldDecl(access_type,
-                                                        attribs.getValue("type"),
-                                                        attribs.getValue(NAME_ATTR),
-                                                        null);
-                        }
-
-                        if(contentHandler != null)
-                            contentHandler.useDecl(value);
-                    } else {
-                        if (value != null && value.length() == 0) {
-                            value = null;
-                        }
-
-                        if(protoHandler != null)
-                            protoHandler.protoFieldDecl(access_type,
-                                                        attribs.getValue("type"),
-                                                        attribs.getValue(NAME_ATTR),
-                                                        value);
-                    }
-                }
-                break;
-
-            case META_TAG:
-                if(contentHandler != null) {
-                    contentHandler.metaDecl(attribs.getValue(NAME_ATTR),
-                                            attribs.getValue("type"));
-                }
-                break;
-
-            case PROTO_INSTANCE_TAG:
-                if(checkForSceneTag)
-                    throw new SAXException(NO_SCENE_TAG_MSG);
-
-                if(contentHandler != null) {
-                    String field_name = attribs.getValue(CONTAINER_ATTR);
-
-                    // No container field name defined? Look one up. If that
-                    // fails, guess and put in "children" since that is the
-                    // most commonly used default.
-                    if(field_name == null) {
-                        field_name = containerFields.getProperty(localName);
-
-                        if(field_name == null)
-                            field_name = "children";
-                    }
-
-                    if(fieldDeclDepth != 0) {
-                        contentHandler.startField(field_name);
-                    }
-
-                    fieldDeclDepth++;
-
-                    contentHandler.startNode(attribs.getValue(NAME_ATTR),
-                                             attribs.getValue(DEF_ATTR));
-                }
-
-/*
-                // All of the above was commented out, restored for now?
-                if (contentHandler != null)
-                    contentHandler.startNode(attribs.getValue(NAME_ATTR),
-                                             attribs.getValue(DEF_ATTR));
-*/
-                inScript = false;
-                break;
-
-            case IMPORT_TAG:
-                if(contentHandler != null)
-                    contentHandler.importDecl(attribs.getValue("inlineDEF"),
-                                              attribs.getValue("exportedDEF"),
-                                              attribs.getValue(AS_ATTR));
-                break;
-
-            case EXPORT_TAG:
-                if(checkForSceneTag)
-                    throw new SAXException(NO_SCENE_TAG_MSG);
-
-                if(contentHandler != null)
-                    contentHandler.exportDecl(attribs.getValue("localDEF"),
-                                              attribs.getValue(AS_ATTR));
-                break;
-
-            case ROUTE_TAG:
-                if(checkForSceneTag)
-                    throw new SAXException(NO_SCENE_TAG_MSG);
-
-                if(routeHandler != null)
-                    routeHandler.routeDecl(attribs.getValue("fromNode"),
-                                           attribs.getValue("fromField"),
-                                           attribs.getValue("toNode"),
-                                           attribs.getValue("toField"));
-                break;
-
-            case SCRIPT_TAG:
-                if(checkForSceneTag)
-                    throw new SAXException(NO_SCENE_TAG_MSG);
-
-                // Force an automatic startCDATA in parser doesn't
-                startScript();
-
-                scriptFlagStack.push(true);
-                inScript = true;
-
-                // Clear any CData garbage
-                characterDataBuffer.setLength(0);
-                characterDataBuffer.append('\"');
-
-                String field_name = attribs.getValue(CONTAINER_ATTR);
-
-                // No container field name defined? Look one up. If that
-                // fails, guess and put in "children" since that is the
-                // most commonly used default.
-                if(field_name == null) {
-                    field_name = containerFields.getProperty(localName);
-
-                    if(field_name == null)
-                        field_name = "children";
-                }
-
-                if(fieldDeclDepth != 0) {
-                    if(contentHandler != null)
-                        contentHandler.startField(field_name);
-                }
-
-                fieldDeclDepth++;
-                value = attribs.getValue(USE_ATTR);
-
-                if(value != null) {
-                    if(contentHandler != null)
-                        contentHandler.useDecl(value);
-                    is_used = true;
-                    useIsCurrent = true;
-                } else {
-                    value = attribs.getValue(DEF_ATTR);
-                    is_used = false;
-                    if(contentHandler != null)
-                        contentHandler.startNode(qName, value);
-                }
-
-                if(scriptHandler != null && !is_used)
-                    scriptHandler.startScriptDecl();
-
-                // The definite fields of a script need to be passed through.
-                // Only pass through if you're not in a USE though.
-                if(!is_used && contentHandler != null) {
-                    value = attribs.getValue("url");
-                    if(value != null) {
-                        scriptUrlStack.push(true);
-                        bch.startField("url");
-                        bch.fieldValue(value);
-                    } else {
-                        scriptUrlStack.push(false);
-                    }
-
-                    value = attribs.getValue("mustEvaluate");
-                    if(value != null) {
-                        bch.startField("mustEvaluate");
-                        bch.fieldValue(value);
-                    }
-
-                    value = attribs.getValue("directOutput");
-                    if(value != null) {
-                        bch.startField("directOutput");
-                        bch.fieldValue(value);
-                    }
-                }
-
-                break;
-
-            case FIELD_VALUE_TAG:
-                if(checkForSceneTag)
-                    throw new SAXException(NO_SCENE_TAG_MSG);
-
-                if(contentHandler != null) {
-
-                    String DEFName = attribs.getValue(USE_ATTR);
-                    if (DEFName != null) {
-                        contentHandler.startField(attribs.getValue(NAME_ATTR));
-                        contentHandler.useDecl(DEFName);
-                    } else {
-                        String att_name;
-
-                        int val_attr = attribs.getIndex(VALUE_ATTR);
-
-                        decodeField(atts,val_attr,bch,attribs.getValue(NAME_ATTR));
-                    }
-                }
-
-                declDepthStack.push(fieldDeclDepth);
-                fieldDeclDepth = 0;
-
-                break;
-
-            default:
-                errorReporter.errorReport("Unknown start element type " + qName, null);
-        }
-
-        inCompressorStack.push(inCompressor);
-        skipEEStack.push(false);
-//System.out.println("End SE");
-    }
-
-    /**
-     * End the element processing.
-     *
-     * @param namespace The namespace for the element. Null if not used
-     * @param name The local name of the element to create
-     * @param qName The qualified name of the element including prefix
-     * @throws SAXException Not thrown in this implementation
-     */
-    @Override
-    public void endElement(String namespace, String name, String qName)
-        throws SAXException {
-
-        boolean inCompressor = inCompressorStack.pop();
-        skipEndElement = skipEEStack.pop();
-
-        if (inCompressor && currentCompressor != null) {
-            BinaryContentHandler bch = (BinaryContentHandler) contentHandler;
-
-            currentCompressor.fillData(qName, bch);
-        }
-
-        if (!skipEndElement)
-            super.endElement(namespace, name, qName);
-    }
-
-    // Methods implementing PrimitiveTypeContentHandler
-
-    /**
-     * Receive notification of character data as an array of boolean.
-     *
-     * <p>The application must not attempt to read from the array
-     * outside of the specified range.</p>
-     *
-     * <p>Such notifications will occur for a Fast Infoset SAX parser
-     * when processing data encoded using the "boolean" encoding
-     * algorithm, see subclause 10.7<p>.
-     *
-     * @param b the array of boolean
-     * @param start the start position in the array
-     * @param length the number of boolean to read from the array
-     * @throws org.xml.sax.SAXException any SAX exception, possibly
-     *            wrapping another exception
-     */
-    @Override
-    public void booleans(boolean [] b, int start, int length) throws SAXException {
-    }
-
-    /**
-     * Receive notification of character data as an array of byte.
-     *
-     * <p>The application must not attempt to read from the array
-     * outside of the specified range.</p>
-     *
-     * <p>Such notifications will occur for a Fast Infoset SAX parser
-     * when processing data encoded using the "base64" encoding
-     * algorithm, see subclause 10.3.
-     *
-     * <p>Such a notification may occur for binary data that would
-     * normally require base 64 encoding and reported as character data
-     * using the {@link org.xml.sax.ContentHandler#characters characters}
-     * method <p>.
-     *
-     * @param b the array of byte
-     * @param start the start position in the array
-     * @param length the number of byte to read from the array
-     * @throws org.xml.sax.SAXException any SAX exception, possibly
-     *            wrapping another exception
-     */
-    @Override
-    public void bytes(byte[] b, int start, int length) throws SAXException {
-    }
-
-    /**
-     * Receive notification of character data as an array of short.
-     *
-     * <p>The application must not attempt to read from the array
-     * outside of the specified range.</p>
-     *
-     * <p>Such notifications will occur for a Fast Infoset SAX parser
-     * when processing data encoded using the "short" encoding
-     * algorithm, see subclause 10.4<p>.
-     *
-     * @param s the array of short
-     * @param start the start position in the array
-     * @param length the number of short to read from the array
-     * @throws org.xml.sax.SAXException any SAX exception, possibly
-     *            wrapping another exception
-     */
-    @Override
-    public void shorts(short[] s, int start, int length) throws SAXException {
-    }
-
-    /**
-     * Receive notification of character data as an array of int.
-     *
-     * <p>The application must not attempt to read from the array
-     * outside of the specified range.</p>
-     *
-     * <p>Such notifications will occur for a Fast Infoset SAX parser
-     * when processing data encoded using the "int" encoding
-     * algorithm, see subclause 10.5<p>.
-     *
-     * @param i the array of int
-     * @param start the start position in the array
-     * @param length the number of int to read from the array
-     * @throws org.xml.sax.SAXException any SAX exception, possibly
-     *            wrapping another exception
-     */
-    @Override
-    public void ints(int [] i, int start, int length) throws SAXException {
-    }
-
-    /**
-     * Receive notification of character data as an array of long.
-     *
-     * <p>The application must not attempt to read from the array
-     * outside of the specified range.</p>
-     *
-     * <p>Such notifications will occur for a Fast Infoset SAX parser
-     * when processing data encoded using the "long" encoding
-     * algorithm, see subclause 10.6<p>.
-     *
-     * @param l the array of long
-     * @param start the start position in the array
-     * @param length the number of long to read from the array
-     * @throws org.xml.sax.SAXException any SAX exception, possibly
-     *            wrapping another exception
-     */
-    @Override
-    public void longs(long [] l, int start, int length) throws SAXException {
-    }
-
-    /**
-     * Receive notification of character data as an array of float.
-     *
-     * <p>The application must not attempt to read from the array
-     * outside of the specified range.</p>
-     *
-     * <p>Such notifications will occur for a Fast Infoset SAX parser
-     * when processing data encoded using the "float" encoding
-     * algorithm, see subclause 10.8<p>.
-     *
-     * @param f the array of float
-     * @param start the start position in the array
-     * @param length the number of float to read from the array
-     * @throws org.xml.sax.SAXException any SAX exception, possibly
-     *            wrapping another exception
-     */
-    @Override
-    public void floats(float [] f, int start, int length) throws SAXException {
-    }
-
-    /**
-     * Receive notification of character data as an array of double.
-     *
-     * <p>The application must not attempt to read from the array
-     * outside of the specified range.</p>
-     *
-     * <p>Such notifications will occur for a Fast Infoset SAX parser
-     * when processing data encoded using the "double" encoding
-     * algorithm, see subclause 10.9<p>.
-     *
-     * @param d the array of double
-     * @param start the start position in the array
-     * @param length the number of double to read from the array
-     * @throws org.xml.sax.SAXException any SAX exception, possibly
-     *            wrapping another exception
-     */
-    @Override
-    public void doubles(double [] d, int start, int length) throws SAXException {
-    }
-
-    /**
-     * Receive notification of character data as an two array of UUID.
-     *
-     * <p>The application must not attempt to read from the array
-     * outside of the specified range.</p>
-     *
-     * <p>Such notifications will occur for a Fast Infoset SAX parser
-     * when processing data encoded using the "uuid" encoding
-     * algorithm, see subclause 10.10<p>.
-     *
-     * @param msblsb the array of long containing pairs of most signficant
-     * bits and least significant bits of the UUIDs
-     * @param start the start position in the array
-     * @param length the number of long to read from the array. This will
-     * be twice the number of UUIDs, which are pairs of two long values
-     * @throws org.xml.sax.SAXException any SAX exception, possibly
-     *            wrapping another exception
-     */
-    @Override
-    public void uuids(long[] msblsb, int start, int length) throws SAXException {
-    }
-
-    /**
-     * Receive notification of character data as an two array of UUID.
-     *
-     * <p>The application must not attempt to read from the array
-     * outside of the specified range.</p>
-     *
-     * <p>Such notifications will occur for a Fast Infoset SAX parser
-     * when processing data encoded using the "uuid" encoding
-     * algorithm, see subclause 10.10<p>.
-     *
-     * @param msb the array of long of the most sigificant bits of
-     * the UUIDs
-     * @param lsb the array of long of the least sigificant bits of
-     * the UUIDs
-     * @param start the start position in the array
-     * @param length the number of UUID to read from the array
-     * @throws org.xml.sax.SAXException any SAX exception, possibly
-     *            wrapping another exception
-     */
-    public void uuids(long[] msb, long[] lsb, int start, int length) throws SAXException {
-    }
-
-
-    // Methods from EncodingAlgorithmContentHandler
-
-    /**
-     * Receive notification of encoding algorithm data as an array
-     * of byte.
-     *
-     * <p>The application must not attempt to read from the array
-     * outside of the specified range.</p>
-     *
-     * <p>Such notifications will occur for a Fast Infoset SAX parser
-     * when processing encoding algorithm data.<p>
-     *
-     * <p>The Parser will call the method of this interface to report each
-     * encoding algorithm data. Parsers MUST return all contiguous
-     * characters in a single chunk</p>
-     *
-     * <p>Parsers may return all contiguous bytes in a single chunk, or
-     * they may split it into several chunks providing that the length of
-     * each chunk is of the required length to successfully apply the
-     * encoding algorithm to the chunk.</p>
-     *
-     * @param URI the URI of the encoding algorithm
-     * @param algorithm the encoding algorithm index
-     * @param b the array of byte
-     * @param start the start position in the array
-     * @param length the number of byte to read from the array
-     * @throws org.xml.sax.SAXException any SAX exception, possibly
-     *            wrapping another exception
-     * @see org.jvnet.fastinfoset.EncodingAlgorithmIndexes
-     */
-    @Override
-    public void octets(String URI, int algorithm, byte[] b, int start, int length)  throws SAXException {
-    }
-
-    /**
-     * Receive notification of encoding algorithm data as an object.
-     *
-     * <p>Such notifications will occur for a Fast Infoset SAX parser
-     * when processing encoding algorithm data that is converted from an
-     * array of byte to an object more suitable for processing.<p>
-     *
-     * @param URI the URI of the encoding algorithm
-     * @param algorithm the encoding algorithm index
-     * @param o the encoding algorithm object
-     * @throws org.xml.sax.SAXException any SAX exception, possibly
-     *            wrapping another exception
-     * @see org.jvnet.fastinfoset.EncodingAlgorithmIndexes
-     */
-    @Override
-    public void object(String URI, int algorithm, Object o)  throws SAXException {
-    }
-
-    /**
-     * Decode a field
-     */
-    private void decodeField(AttributesHolder atts,
-                             int i,
-                             BinaryContentHandler bch,
-                             String att_name) {
-        if (i < 0) {
-            bch.startField(att_name);
-            return;
-        }
-
-        Object type = atts.getAlgorithmData(i);
-
-        if (type == null) {
-            // No typed data, handle as a string
-
-            bch.startField(att_name);
-            bch.fieldValue(atts.getValue(i));
-
-        } else {
-            // TODO: DODGY!!!  algo != data type
-            // Handle most correctly now, not sure about byte
-            Object o = atts.getAlgorithmData(i);
-
-            if (o instanceof float[]) {
-                float[] f2val = (float[]) atts.getAlgorithmData(i);
-                bch.startField(att_name);
-                bch.fieldValue(f2val, f2val.length);
-                return;
-            } else if (o instanceof int[]) {
-                int[] ival = (int[]) atts.getAlgorithmData(i);
-                bch.startField(att_name);
-                bch.fieldValue(ival, ival.length);
-                return;
-            } else if(o instanceof double[]) {
-                double[] dval = (double[]) atts.getAlgorithmData(i);
-
-                bch.startField(att_name);
-                bch.fieldValue(dval, dval.length);
-                bch.endField();
-                return;
-            } else if (o instanceof short[]) {
-                short[] sval = (short[]) atts.getAlgorithmData(i);
-                int alen = sval.length;
-                int[] i2val = new int[alen];
-
-                for(int j=0; j < alen; j++) {
-                    i2val[j] = sval[j];
-                }
-                bch.startField(att_name);
-                bch.fieldValue(i2val, i2val.length);
-            }
-
-
-            switch(atts.getAlgorithmIndex(i)) {
-/*
-                // Still not sure how to tell single from double
-                case EncodingAlgorithmIndexes.BOOLEAN:
-                    boolean[] fval = (boolean[]) atts.getAlgorithmData(i);
-
-                    bch.startField(att_name);
-                    bch.fieldValue(fval, fval.length);
-                    break;
-*/
-                case EncodingAlgorithmIndexes.FLOAT:
-                    // TODO: Assume all FLOAT's are arrays
-                    float[] fval = (float[]) atts.getAlgorithmData(i);
-                    bch.startField(att_name);
-                    bch.fieldValue(fval, fval.length);
-                    break;
-                case EncodingAlgorithmIndexes.DOUBLE:
-                    // TODO: Assume all DOUBLES's are arrays
-                    double[] dval = (double[]) atts.getAlgorithmData(i);
-
-                    bch.startField(att_name);
-                    bch.fieldValue(dval, dval.length);
-                    bch.endField();
-                    break;
-                case EncodingAlgorithmIndexes.INT:
-                    // TODO: Assume all INT's are arrays
-                    int[] ival = (int[]) atts.getAlgorithmData(i);
-                    bch.startField(att_name);
-                    bch.fieldValue(ival, ival.length);
-                    break;
-
-                case EncodingAlgorithmIndexes.SHORT:
-                    // TODO: Assume all INT's are arrays
-                    short[] sval = (short[]) atts.getAlgorithmData(i);
-                    int alen = sval.length;
-                    int[] i2val = new int[alen];
-
-                    for(int j=0; j < alen; j++) {
-                        i2val[j] = sval[j];
-                    }
-                    bch.startField(att_name);
-                    bch.fieldValue(i2val, i2val.length);
-                    break;
-
-                case X3DBinaryConstants.BYTE_ALGORITHM_ID:
-                    // TODO: stop hardcoding number for BYTE, reference from tables
-                    byte[] bval = (byte[]) atts.getAlgorithmData(i);
-                    int blen = bval.length;
-                    int[] i3val = new int[blen];
-
-                    for(int j=0; j < blen; j++) {
-                        i3val[j] = bval[j];
-                    }
-
-                    bch.startField(att_name);
-                    bch.fieldValue(i3val, i3val.length);
-                    break;
-
-                case X3DBinaryConstants.DELTA_ZLIB_INT_ARRAY_ALGORITHM_ID:
-                    int[] i4val = (int[]) atts.getAlgorithmData(i);
-//System.out.println("FI Element reader " + att_name + " " +  java.util.Arrays.toString(i4val));
-
-                    bch.startField(att_name);
-                    bch.fieldValue(i4val, i4val.length);
-                    break;
-
-                case X3DBinaryConstants.QUANTIZED_ZLIB_FLOAT_ARRAY_ALGORITHM_ID:
-                case X3DBinaryConstants.QUANTIZED_ZLIB_FLOAT_ARRAY_ALGORITHM_ID2:
-                    float[] f2val = (float[]) atts.getAlgorithmData(i);
-                    bch.startField(att_name);
-                    bch.fieldValue(f2val, f2val.length);
-                    break;
-                default:
-                    errorReporter.warningReport("Unhandled algorithm: " +
-                                                atts.getAlgorithmIndex(i),
-                                                null);
-            }
-        }
-    }
-}
+/*****************************************************************************
+ *                        Web3d Consortium Copyright (c) 2005
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ *****************************************************************************/
+
+package org.web3d.parser.x3d;
+
+// External imports
+import org.xml.sax.SAXException;
+import org.xml.sax.Attributes;
+
+import com.sun.xml.fastinfoset.sax.AttributesHolder;
+
+import org.jvnet.fastinfoset.EncodingAlgorithmIndexes;
+import org.jvnet.fastinfoset.sax.PrimitiveTypeContentHandler;
+import org.jvnet.fastinfoset.sax.EncodingAlgorithmContentHandler;
+
+// Local imports
+import org.web3d.util.*;
+import org.web3d.vrml.sav.*;
+
+import org.web3d.vrml.lang.InvalidFieldException;
+import org.web3d.x3d.jaxp.X3DSAVAdapter;
+import org.web3d.vrml.export.compressors.NodeCompressor;
+//import org.web3d.vrml.export.compressors.TestCompressor;
+
+/**
+ * Handles the reading of elements from a FastInfoSet stream and converts
+ * it to an X3D world.
+ *
+ * This expects attributes of type TypeAttributes instead of just Attributes.
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.15 $
+ */
+class FastInfosetElementReader extends X3DSAVAdapter
+    implements PrimitiveTypeContentHandler, EncodingAlgorithmContentHandler {
+
+    private BooleanStack inCompressorStack;
+
+    private BooleanStack skipEEStack;
+
+    private NodeCompressor currentCompressor;
+
+    private String lastNodeName;
+
+    private boolean skipEndElement;
+
+    /** After the payload any metadata is ignored */
+    private boolean pastPayload;
+
+    /** Switch between methods, should go away */
+    private boolean compressedAttWay = false;
+
+    /**
+     * Initialise a new instance of the reader
+     */
+    FastInfosetElementReader() {
+
+        inCompressorStack = new BooleanStack();
+        inCompressorStack.push(false);
+
+        skipEEStack = new BooleanStack();
+    }
+
+    /**
+     * Start the processing of a new element with the given collection of
+     * attribute information.
+     *
+     * @param namespace The namespace for the element. Null if not used
+     * @param name The local name of the element to create
+     * @param qName The qualified name of the element including prefix
+     * @param attribs The collection of attributes to use
+     * @throws SAXException The element can't be found in the underlying
+     *     factory
+     */
+    @Override
+    public void startElement(String namespace,
+                             String localName,
+                             String qName,
+                             Attributes attribs)
+        throws SAXException {
+
+//System.out.println("SE: " + qName);
+        boolean inCompressor = inCompressorStack.peek();
+
+        if(useIsCurrent)
+            throw new SAXException(USE_WITH_KIDS_MSG);
+
+        // Remove X3D: namespace prefix.  Need to handle generically
+        if(qName.startsWith("X3D:"))
+            qName = qName.substring(4);
+
+        Integer el_type = elementMap.get(qName);
+
+        String value;
+        AttributesHolder atts = (AttributesHolder) attribs;
+        BinaryContentHandler bch = (BinaryContentHandler) contentHandler;
+
+        // TODO: Would a HashMap be faster here?
+        if (qName.equals("MetadataSet")) {
+            String name = attribs.getValue("name");
+
+            if (name.equals(".x3db")) {
+                // Pop Parents inCompressor and replace with true
+                inCompressorStack.pop();
+                inCompressorStack.push(true);
+                inCompressor = true;
+
+                inCompressorStack.push(inCompressor);
+                skipEEStack.push(true);
+                pastPayload = false;
+                return;
+            } else if (pastPayload) {
+                pastPayload = false;
+
+                inCompressorStack.push(inCompressor);
+                skipEEStack.push(true);
+
+                return;
+            }
+        }
+
+        if (inCompressor) {
+            String name = attribs.getValue("name");
+
+            if (name != null) {
+                switch (name) {
+                    case "encoding":
+                        //                    currentCompressor = new TestCompressor();
+
+                        inCompressorStack.push(inCompressor);
+                        skipEEStack.push(true);
+                        return;
+                    case "payload":
+                        int idx = attribs.getIndex("value");
+                        int algo = atts.getAlgorithmIndex(idx);
+
+                        switch (algo) {
+                            case EncodingAlgorithmIndexes.INT:
+                                int[] ival = (int[]) atts.getAlgorithmData(idx);
+                                currentCompressor.decompress(ival);
+                                currentCompressor.fillData(lastNodeName, bch);
+                                break;
+                            case X3DBinaryConstants.DELTA_ZLIB_INT_ARRAY_ALGORITHM_ID:
+                                int[] i4val = (int[]) atts.getAlgorithmData(idx);
+                                currentCompressor.decompress(i4val);
+                                currentCompressor.fillData(lastNodeName, bch);
+                                break;
+                            default:
+                                errorReporter.errorReport("Data in wrong format! " +
+                                        atts.getAlgorithmIndex(idx),
+                                        null);
+                                break;
+                        }
+
+                        pastPayload = true;
+                        inCompressorStack.push(inCompressor);
+                        skipEEStack.push(true);
+                    return;
+
+                }
+            }
+        } else {
+            lastNodeName = qName;
+        }
+
+        if(el_type == null) {
+            if(checkForSceneTag)
+                throw new SAXException(NO_SCENE_TAG_MSG);
+
+            // We're obviously in a new node, so go look for
+            // the container field attribute to do a "startField"
+            // call. However, no point doing anything if we don't have a
+            // content handler to call. Need to weed out the one case were
+            // we are the root node of a proto declaration body.
+
+            if(fieldDeclDepth != 0) {
+                String field_name = attribs.getValue(CONTAINER_ATTR);
+
+                // No container field name defined? Look one up. If that
+                // fails, guess and put in "children" since that is the
+                // most commonly used default.
+                if(field_name == null) {
+                    field_name = containerFields.getProperty(qName);
+
+                    if(field_name == null)
+                        field_name = "children";
+                }
+
+                if(contentHandler != null) {
+                    try {
+                        contentHandler.startField(field_name);
+                    } catch(InvalidFieldException ife) {
+                       errorReporter.errorReport("No field: " + field_name +
+                                                 " for: " + qName,
+                                                 null);
+                    }
+                }
+
+            }
+
+            value = attribs.getValue(USE_ATTR);
+            fieldDeclDepth++;
+
+            if(value != null) {
+                if(contentHandler != null)
+                    contentHandler.useDecl(value);
+                useIsCurrent = true;
+            } else {
+                value = attribs.getValue(DEF_ATTR);
+                if(contentHandler != null)
+                    contentHandler.startNode(qName, value);
+            }
+
+            Object type;
+            String att_name;
+            Integer id_int;
+
+/*
+            if (inCompressor) {
+                currentCompressor.fillData(qName, bch);
+            }
+*/
+            // now process all the attributes!
+            int num_attr = attribs.getLength();
+            for(int i = 0; !useIsCurrent && i < num_attr; i++) {
+                att_name = atts.getLocalName(i);
+//System.out.println("att_name: " + att_name);
+                switch (att_name) {
+                    case "encoder":
+                        // TODO: make hashmap
+                        if (atts.getValue(i).equals("1")) {
+                            inCompressor = true;
+
+//                        currentCompressor = new TestCompressor();
+                        }
+                        continue;
+                    case "data":
+                        type = atts.getAlgorithmData(i);
+
+                        if (atts.getAlgorithmIndex(i) == EncodingAlgorithmIndexes.INT) {
+                            // TODO: Assume all INT's are arrays
+                            int[] ival = (int[]) atts.getAlgorithmData(i);
+                            currentCompressor.decompress(ival);
+                            currentCompressor.fillData(qName, bch);
+
+                        } else {
+                            errorReporter.errorReport("Data in wrong format!", null);
+                        }
+
+                    continue;
+                }
+
+                // Check to see if the attribute is one of the reserved
+                // set. If so, treat separately from the normal field
+                // processing.
+                id_int = attributeMap.get(att_name);
+
+                if (id_int != null) {
+                    continue;
+                }
+
+                decodeField(atts,i,bch,att_name);
+            }
+
+            inCompressorStack.push(inCompressor);
+            skipEEStack.push(false);
+
+            return;
+        }
+
+        switch(el_type) {
+            case X3D_TAG:
+                loadContainerProperties(Float.parseFloat(versionString.substring(1)));
+
+                String version = attribs.getValue("version");
+
+                if (version == null) {
+                    version = "V3.0";
+                } else {
+                    version = "V" + version;
+                }
+
+                if(contentHandler != null) {
+                    contentHandler.startDocument(null,  // TODO: Not sure how to get filename
+                                                 worldURL,
+                                                 XML_ENCODING,
+                                                 "#X3D",
+                                                 version,
+                                                 null);
+                }
+
+                value = attribs.getValue("profile");
+
+                if(value == null)
+                    throw new SAXException(NO_PROFILE_MSG);
+
+                if(contentHandler != null)
+                    contentHandler.profileDecl(value);
+
+                // Setup cData
+                if(overrideLex)
+                    characterDataBuffer.append("\"");
+
+                useIsCurrent = false;
+                checkForSceneTag = true;
+                break;
+
+            case HEAD_TAG:
+                // do nothing
+                break;
+
+            case COMPONENT_TAG:
+                value = attribs.getValue(NAME_ATTR) + ':' +
+                        attribs.getValue("level");
+                if(contentHandler != null)
+                    contentHandler.componentDecl(value);
+                break;
+
+            case SCENE_TAG:
+                checkForSceneTag = false;
+                break;
+
+            case PROTO_DECL_TAG:
+                if(checkForSceneTag)
+                    throw new SAXException(NO_SCENE_TAG_MSG);
+
+                if(protoHandler != null)
+                    protoHandler.startProtoDecl(attribs.getValue(NAME_ATTR));
+
+                scriptFlagStack.push(false);
+                inScript = false;
+                break;
+
+            case PROTO_INTERFACE_TAG:
+                if(checkForSceneTag)
+                    throw new SAXException(NO_SCENE_TAG_MSG);
+
+                // Don't do anything from here. We've already started the
+                // proto decl handling in the PROTO_DECL_TAG.
+                break;
+
+            case PROTO_BODY_TAG:
+                if(checkForSceneTag)
+                    throw new SAXException(NO_SCENE_TAG_MSG);
+
+                if(protoHandler != null) {
+                    protoHandler.endProtoDecl();
+                    protoHandler.startProtoBody();
+                }
+
+                break;
+
+            case EXTERNPROTO_DECL_TAG:
+                if(checkForSceneTag)
+                    throw new SAXException(NO_SCENE_TAG_MSG);
+
+                if(protoHandler != null) {
+                    value = attribs.getValue(NAME_ATTR);
+                    protoHandler.startExternProtoDecl(value);
+
+                    epUrl = attribs.getValue("url");
+
+                }
+
+                scriptFlagStack.push(false);
+                inScript = false;
+
+                break;
+
+            case IS_TAG:
+                if(checkForSceneTag)
+                    throw new SAXException(NO_SCENE_TAG_MSG);
+
+                break;
+
+            case CONNECT_TAG:
+                if(checkForSceneTag)
+                    throw new SAXException(NO_SCENE_TAG_MSG);
+
+                if(contentHandler != null)
+                    contentHandler.startField(attribs.getValue("nodeField"));
+
+                if(protoHandler != null)
+                    protoHandler.protoIsDecl(attribs.getValue("protoField"));
+                break;
+
+            case FIELD_TAG:
+                if(checkForSceneTag)
+                    throw new SAXException(NO_SCENE_TAG_MSG);
+
+                int access_type =
+                    processFieldAccess(attribs.getValue("accessType"), attribs.getValue(NAME_ATTR));
+
+                // perhaps this should do some prior checking of the
+                // access type to make sure that the user don't do anything
+                // dumb like set a value for eventIn/Out.
+                boolean is_used = false;
+                depthCountStack.push(fieldDeclDepth);
+                fieldDeclDepth = 0;
+
+                if((value = attribs.getValue("USE")) != null)
+                    is_used = true;
+                else
+                    value = attribs.getValue(VALUE_ATTR);
+
+                if(inScript) {
+                    if(is_used) {
+                        if(scriptHandler != null) {
+                            scriptHandler.scriptFieldDecl(access_type,
+                                                          attribs.getValue("type"),
+                                                          attribs.getValue(NAME_ATTR),
+                                                          null);
+                        }
+
+                        if(contentHandler != null)
+                            contentHandler.useDecl(value);
+                    } else {
+                        if (value != null && value.length() == 0) {
+                            value = null;
+                        }
+
+                        if(scriptHandler != null)
+                            scriptHandler.scriptFieldDecl(access_type,
+                                                          attribs.getValue("type"),
+                                                          attribs.getValue(NAME_ATTR),
+                                                          value);
+                    }
+                } else {
+                    if(is_used) {
+                        if(protoHandler != null) {
+                            protoHandler.protoFieldDecl(access_type,
+                                                        attribs.getValue("type"),
+                                                        attribs.getValue(NAME_ATTR),
+                                                        null);
+                        }
+
+                        if(contentHandler != null)
+                            contentHandler.useDecl(value);
+                    } else {
+                        if (value != null && value.length() == 0) {
+                            value = null;
+                        }
+
+                        if(protoHandler != null)
+                            protoHandler.protoFieldDecl(access_type,
+                                                        attribs.getValue("type"),
+                                                        attribs.getValue(NAME_ATTR),
+                                                        value);
+                    }
+                }
+                break;
+
+            case META_TAG:
+                if(contentHandler != null) {
+                    contentHandler.metaDecl(attribs.getValue(NAME_ATTR),
+                                            attribs.getValue("type"));
+                }
+                break;
+
+            case PROTO_INSTANCE_TAG:
+                if(checkForSceneTag)
+                    throw new SAXException(NO_SCENE_TAG_MSG);
+
+                if(contentHandler != null) {
+                    String field_name = attribs.getValue(CONTAINER_ATTR);
+
+                    // No container field name defined? Look one up. If that
+                    // fails, guess and put in "children" since that is the
+                    // most commonly used default.
+                    if(field_name == null) {
+                        field_name = containerFields.getProperty(localName);
+
+                        if(field_name == null)
+                            field_name = "children";
+                    }
+
+                    if(fieldDeclDepth != 0) {
+                        contentHandler.startField(field_name);
+                    }
+
+                    fieldDeclDepth++;
+
+                    contentHandler.startNode(attribs.getValue(NAME_ATTR),
+                                             attribs.getValue(DEF_ATTR));
+                }
+
+/*
+                // All of the above was commented out, restored for now?
+                if (contentHandler != null)
+                    contentHandler.startNode(attribs.getValue(NAME_ATTR),
+                                             attribs.getValue(DEF_ATTR));
+*/
+                inScript = false;
+                break;
+
+            case IMPORT_TAG:
+                if(contentHandler != null)
+                    contentHandler.importDecl(attribs.getValue("inlineDEF"),
+                                              attribs.getValue("exportedDEF"),
+                                              attribs.getValue(AS_ATTR));
+                break;
+
+            case EXPORT_TAG:
+                if(checkForSceneTag)
+                    throw new SAXException(NO_SCENE_TAG_MSG);
+
+                if(contentHandler != null)
+                    contentHandler.exportDecl(attribs.getValue("localDEF"),
+                                              attribs.getValue(AS_ATTR));
+                break;
+
+            case ROUTE_TAG:
+                if(checkForSceneTag)
+                    throw new SAXException(NO_SCENE_TAG_MSG);
+
+                if(routeHandler != null)
+                    routeHandler.routeDecl(attribs.getValue("fromNode"),
+                                           attribs.getValue("fromField"),
+                                           attribs.getValue("toNode"),
+                                           attribs.getValue("toField"));
+                break;
+
+            case SCRIPT_TAG:
+                if(checkForSceneTag)
+                    throw new SAXException(NO_SCENE_TAG_MSG);
+
+                // Force an automatic startCDATA in parser doesn't
+                startScript();
+
+                scriptFlagStack.push(true);
+                inScript = true;
+
+                // Clear any CData garbage
+                characterDataBuffer.setLength(0);
+                characterDataBuffer.append('\"');
+
+                String field_name = attribs.getValue(CONTAINER_ATTR);
+
+                // No container field name defined? Look one up. If that
+                // fails, guess and put in "children" since that is the
+                // most commonly used default.
+                if(field_name == null) {
+                    field_name = containerFields.getProperty(localName);
+
+                    if(field_name == null)
+                        field_name = "children";
+                }
+
+                if(fieldDeclDepth != 0) {
+                    if(contentHandler != null)
+                        contentHandler.startField(field_name);
+                }
+
+                fieldDeclDepth++;
+                value = attribs.getValue(USE_ATTR);
+
+                if(value != null) {
+                    if(contentHandler != null)
+                        contentHandler.useDecl(value);
+                    is_used = true;
+                    useIsCurrent = true;
+                } else {
+                    value = attribs.getValue(DEF_ATTR);
+                    is_used = false;
+                    if(contentHandler != null)
+                        contentHandler.startNode(qName, value);
+                }
+
+                if(scriptHandler != null && !is_used)
+                    scriptHandler.startScriptDecl();
+
+                // The definite fields of a script need to be passed through.
+                // Only pass through if you're not in a USE though.
+                if(!is_used && contentHandler != null) {
+                    value = attribs.getValue("url");
+                    if(value != null) {
+                        scriptUrlStack.push(true);
+                        bch.startField("url");
+                        bch.fieldValue(value);
+                    } else {
+                        scriptUrlStack.push(false);
+                    }
+
+                    value = attribs.getValue("mustEvaluate");
+                    if(value != null) {
+                        bch.startField("mustEvaluate");
+                        bch.fieldValue(value);
+                    }
+
+                    value = attribs.getValue("directOutput");
+                    if(value != null) {
+                        bch.startField("directOutput");
+                        bch.fieldValue(value);
+                    }
+                }
+
+                break;
+
+            case FIELD_VALUE_TAG:
+                if(checkForSceneTag)
+                    throw new SAXException(NO_SCENE_TAG_MSG);
+
+                if(contentHandler != null) {
+
+                    String DEFName = attribs.getValue(USE_ATTR);
+                    if (DEFName != null) {
+                        contentHandler.startField(attribs.getValue(NAME_ATTR));
+                        contentHandler.useDecl(DEFName);
+                    } else {
+                        String att_name;
+
+                        int val_attr = attribs.getIndex(VALUE_ATTR);
+
+                        decodeField(atts,val_attr,bch,attribs.getValue(NAME_ATTR));
+                    }
+                }
+
+                declDepthStack.push(fieldDeclDepth);
+                fieldDeclDepth = 0;
+
+                break;
+
+            default:
+                errorReporter.errorReport("Unknown start element type " + qName, null);
+        }
+
+        inCompressorStack.push(inCompressor);
+        skipEEStack.push(false);
+//System.out.println("End SE");
+    }
+
+    /**
+     * End the element processing.
+     *
+     * @param namespace The namespace for the element. Null if not used
+     * @param name The local name of the element to create
+     * @param qName The qualified name of the element including prefix
+     * @throws SAXException Not thrown in this implementation
+     */
+    @Override
+    public void endElement(String namespace, String name, String qName)
+        throws SAXException {
+
+        boolean inCompressor = inCompressorStack.pop();
+        skipEndElement = skipEEStack.pop();
+
+        if (inCompressor && currentCompressor != null) {
+            BinaryContentHandler bch = (BinaryContentHandler) contentHandler;
+
+            currentCompressor.fillData(qName, bch);
+        }
+
+        if (!skipEndElement)
+            super.endElement(namespace, name, qName);
+    }
+
+    // Methods implementing PrimitiveTypeContentHandler
+
+    /**
+     * Receive notification of character data as an array of boolean.
+     *
+     * <p>The application must not attempt to read from the array
+     * outside of the specified range.</p>
+     *
+     * <p>Such notifications will occur for a Fast Infoset SAX parser
+     * when processing data encoded using the "boolean" encoding
+     * algorithm, see subclause 10.7<p>.
+     *
+     * @param b the array of boolean
+     * @param start the start position in the array
+     * @param length the number of boolean to read from the array
+     * @throws org.xml.sax.SAXException any SAX exception, possibly
+     *            wrapping another exception
+     */
+    @Override
+    public void booleans(boolean [] b, int start, int length) throws SAXException {
+    }
+
+    /**
+     * Receive notification of character data as an array of byte.
+     *
+     * <p>The application must not attempt to read from the array
+     * outside of the specified range.</p>
+     *
+     * <p>Such notifications will occur for a Fast Infoset SAX parser
+     * when processing data encoded using the "base64" encoding
+     * algorithm, see subclause 10.3.
+     *
+     * <p>Such a notification may occur for binary data that would
+     * normally require base 64 encoding and reported as character data
+     * using the {@link org.xml.sax.ContentHandler#characters characters}
+     * method <p>.
+     *
+     * @param b the array of byte
+     * @param start the start position in the array
+     * @param length the number of byte to read from the array
+     * @throws org.xml.sax.SAXException any SAX exception, possibly
+     *            wrapping another exception
+     */
+    @Override
+    public void bytes(byte[] b, int start, int length) throws SAXException {
+    }
+
+    /**
+     * Receive notification of character data as an array of short.
+     *
+     * <p>The application must not attempt to read from the array
+     * outside of the specified range.</p>
+     *
+     * <p>Such notifications will occur for a Fast Infoset SAX parser
+     * when processing data encoded using the "short" encoding
+     * algorithm, see subclause 10.4<p>.
+     *
+     * @param s the array of short
+     * @param start the start position in the array
+     * @param length the number of short to read from the array
+     * @throws org.xml.sax.SAXException any SAX exception, possibly
+     *            wrapping another exception
+     */
+    @Override
+    public void shorts(short[] s, int start, int length) throws SAXException {
+    }
+
+    /**
+     * Receive notification of character data as an array of int.
+     *
+     * <p>The application must not attempt to read from the array
+     * outside of the specified range.</p>
+     *
+     * <p>Such notifications will occur for a Fast Infoset SAX parser
+     * when processing data encoded using the "int" encoding
+     * algorithm, see subclause 10.5<p>.
+     *
+     * @param i the array of int
+     * @param start the start position in the array
+     * @param length the number of int to read from the array
+     * @throws org.xml.sax.SAXException any SAX exception, possibly
+     *            wrapping another exception
+     */
+    @Override
+    public void ints(int [] i, int start, int length) throws SAXException {
+    }
+
+    /**
+     * Receive notification of character data as an array of long.
+     *
+     * <p>The application must not attempt to read from the array
+     * outside of the specified range.</p>
+     *
+     * <p>Such notifications will occur for a Fast Infoset SAX parser
+     * when processing data encoded using the "long" encoding
+     * algorithm, see subclause 10.6<p>.
+     *
+     * @param l the array of long
+     * @param start the start position in the array
+     * @param length the number of long to read from the array
+     * @throws org.xml.sax.SAXException any SAX exception, possibly
+     *            wrapping another exception
+     */
+    @Override
+    public void longs(long [] l, int start, int length) throws SAXException {
+    }
+
+    /**
+     * Receive notification of character data as an array of float.
+     *
+     * <p>The application must not attempt to read from the array
+     * outside of the specified range.</p>
+     *
+     * <p>Such notifications will occur for a Fast Infoset SAX parser
+     * when processing data encoded using the "float" encoding
+     * algorithm, see subclause 10.8<p>.
+     *
+     * @param f the array of float
+     * @param start the start position in the array
+     * @param length the number of float to read from the array
+     * @throws org.xml.sax.SAXException any SAX exception, possibly
+     *            wrapping another exception
+     */
+    @Override
+    public void floats(float [] f, int start, int length) throws SAXException {
+    }
+
+    /**
+     * Receive notification of character data as an array of double.
+     *
+     * <p>The application must not attempt to read from the array
+     * outside of the specified range.</p>
+     *
+     * <p>Such notifications will occur for a Fast Infoset SAX parser
+     * when processing data encoded using the "double" encoding
+     * algorithm, see subclause 10.9<p>.
+     *
+     * @param d the array of double
+     * @param start the start position in the array
+     * @param length the number of double to read from the array
+     * @throws org.xml.sax.SAXException any SAX exception, possibly
+     *            wrapping another exception
+     */
+    @Override
+    public void doubles(double [] d, int start, int length) throws SAXException {
+    }
+
+    /**
+     * Receive notification of character data as an two array of UUID.
+     *
+     * <p>The application must not attempt to read from the array
+     * outside of the specified range.</p>
+     *
+     * <p>Such notifications will occur for a Fast Infoset SAX parser
+     * when processing data encoded using the "uuid" encoding
+     * algorithm, see subclause 10.10<p>.
+     *
+     * @param msblsb the array of long containing pairs of most signficant
+     * bits and least significant bits of the UUIDs
+     * @param start the start position in the array
+     * @param length the number of long to read from the array. This will
+     * be twice the number of UUIDs, which are pairs of two long values
+     * @throws org.xml.sax.SAXException any SAX exception, possibly
+     *            wrapping another exception
+     */
+    @Override
+    public void uuids(long[] msblsb, int start, int length) throws SAXException {
+    }
+
+    /**
+     * Receive notification of character data as an two array of UUID.
+     *
+     * <p>The application must not attempt to read from the array
+     * outside of the specified range.</p>
+     *
+     * <p>Such notifications will occur for a Fast Infoset SAX parser
+     * when processing data encoded using the "uuid" encoding
+     * algorithm, see subclause 10.10<p>.
+     *
+     * @param msb the array of long of the most sigificant bits of
+     * the UUIDs
+     * @param lsb the array of long of the least sigificant bits of
+     * the UUIDs
+     * @param start the start position in the array
+     * @param length the number of UUID to read from the array
+     * @throws org.xml.sax.SAXException any SAX exception, possibly
+     *            wrapping another exception
+     */
+    public void uuids(long[] msb, long[] lsb, int start, int length) throws SAXException {
+    }
+
+
+    // Methods from EncodingAlgorithmContentHandler
+
+    /**
+     * Receive notification of encoding algorithm data as an array
+     * of byte.
+     *
+     * <p>The application must not attempt to read from the array
+     * outside of the specified range.</p>
+     *
+     * <p>Such notifications will occur for a Fast Infoset SAX parser
+     * when processing encoding algorithm data.<p>
+     *
+     * <p>The Parser will call the method of this interface to report each
+     * encoding algorithm data. Parsers MUST return all contiguous
+     * characters in a single chunk</p>
+     *
+     * <p>Parsers may return all contiguous bytes in a single chunk, or
+     * they may split it into several chunks providing that the length of
+     * each chunk is of the required length to successfully apply the
+     * encoding algorithm to the chunk.</p>
+     *
+     * @param URI the URI of the encoding algorithm
+     * @param algorithm the encoding algorithm index
+     * @param b the array of byte
+     * @param start the start position in the array
+     * @param length the number of byte to read from the array
+     * @throws org.xml.sax.SAXException any SAX exception, possibly
+     *            wrapping another exception
+     * @see org.jvnet.fastinfoset.EncodingAlgorithmIndexes
+     */
+    @Override
+    public void octets(String URI, int algorithm, byte[] b, int start, int length)  throws SAXException {
+    }
+
+    /**
+     * Receive notification of encoding algorithm data as an object.
+     *
+     * <p>Such notifications will occur for a Fast Infoset SAX parser
+     * when processing encoding algorithm data that is converted from an
+     * array of byte to an object more suitable for processing.<p>
+     *
+     * @param URI the URI of the encoding algorithm
+     * @param algorithm the encoding algorithm index
+     * @param o the encoding algorithm object
+     * @throws org.xml.sax.SAXException any SAX exception, possibly
+     *            wrapping another exception
+     * @see org.jvnet.fastinfoset.EncodingAlgorithmIndexes
+     */
+    @Override
+    public void object(String URI, int algorithm, Object o)  throws SAXException {
+    }
+
+    /**
+     * Decode a field
+     */
+    private void decodeField(AttributesHolder atts,
+                             int i,
+                             BinaryContentHandler bch,
+                             String att_name) {
+        if (i < 0) {
+            bch.startField(att_name);
+            return;
+        }
+
+        Object type = atts.getAlgorithmData(i);
+
+        if (type == null) {
+            // No typed data, handle as a string
+
+            bch.startField(att_name);
+            bch.fieldValue(atts.getValue(i));
+
+        } else {
+            // TODO: DODGY!!!  algo != data type
+            // Handle most correctly now, not sure about byte
+            Object o = atts.getAlgorithmData(i);
+
+            if (o instanceof float[]) {
+                float[] f2val = (float[]) atts.getAlgorithmData(i);
+                bch.startField(att_name);
+                bch.fieldValue(f2val, f2val.length);
+                return;
+            } else if (o instanceof int[]) {
+                int[] ival = (int[]) atts.getAlgorithmData(i);
+                bch.startField(att_name);
+                bch.fieldValue(ival, ival.length);
+                return;
+            } else if(o instanceof double[]) {
+                double[] dval = (double[]) atts.getAlgorithmData(i);
+
+                bch.startField(att_name);
+                bch.fieldValue(dval, dval.length);
+                bch.endField();
+                return;
+            } else if (o instanceof short[]) {
+                short[] sval = (short[]) atts.getAlgorithmData(i);
+                int alen = sval.length;
+                int[] i2val = new int[alen];
+
+                for(int j=0; j < alen; j++) {
+                    i2val[j] = sval[j];
+                }
+                bch.startField(att_name);
+                bch.fieldValue(i2val, i2val.length);
+            }
+
+
+            switch(atts.getAlgorithmIndex(i)) {
+/*
+                // Still not sure how to tell single from double
+                case EncodingAlgorithmIndexes.BOOLEAN:
+                    boolean[] fval = (boolean[]) atts.getAlgorithmData(i);
+
+                    bch.startField(att_name);
+                    bch.fieldValue(fval, fval.length);
+                    break;
+*/
+                case EncodingAlgorithmIndexes.FLOAT:
+                    // TODO: Assume all FLOAT's are arrays
+                    float[] fval = (float[]) atts.getAlgorithmData(i);
+                    bch.startField(att_name);
+                    bch.fieldValue(fval, fval.length);
+                    break;
+                case EncodingAlgorithmIndexes.DOUBLE:
+                    // TODO: Assume all DOUBLES's are arrays
+                    double[] dval = (double[]) atts.getAlgorithmData(i);
+
+                    bch.startField(att_name);
+                    bch.fieldValue(dval, dval.length);
+                    bch.endField();
+                    break;
+                case EncodingAlgorithmIndexes.INT:
+                    // TODO: Assume all INT's are arrays
+                    int[] ival = (int[]) atts.getAlgorithmData(i);
+                    bch.startField(att_name);
+                    bch.fieldValue(ival, ival.length);
+                    break;
+
+                case EncodingAlgorithmIndexes.SHORT:
+                    // TODO: Assume all INT's are arrays
+                    short[] sval = (short[]) atts.getAlgorithmData(i);
+                    int alen = sval.length;
+                    int[] i2val = new int[alen];
+
+                    for(int j=0; j < alen; j++) {
+                        i2val[j] = sval[j];
+                    }
+                    bch.startField(att_name);
+                    bch.fieldValue(i2val, i2val.length);
+                    break;
+
+                case X3DBinaryConstants.BYTE_ALGORITHM_ID:
+                    // TODO: stop hardcoding number for BYTE, reference from tables
+                    byte[] bval = (byte[]) atts.getAlgorithmData(i);
+                    int blen = bval.length;
+                    int[] i3val = new int[blen];
+
+                    for(int j=0; j < blen; j++) {
+                        i3val[j] = bval[j];
+                    }
+
+                    bch.startField(att_name);
+                    bch.fieldValue(i3val, i3val.length);
+                    break;
+
+                case X3DBinaryConstants.DELTA_ZLIB_INT_ARRAY_ALGORITHM_ID:
+                    int[] i4val = (int[]) atts.getAlgorithmData(i);
+//System.out.println("FI Element reader " + att_name + " " +  java.util.Arrays.toString(i4val));
+
+                    bch.startField(att_name);
+                    bch.fieldValue(i4val, i4val.length);
+                    break;
+
+                case X3DBinaryConstants.QUANTIZED_ZLIB_FLOAT_ARRAY_ALGORITHM_ID:
+                case X3DBinaryConstants.QUANTIZED_ZLIB_FLOAT_ARRAY_ALGORITHM_ID2:
+                    float[] f2val = (float[]) atts.getAlgorithmData(i);
+                    bch.startField(att_name);
+                    bch.fieldValue(f2val, f2val.length);
+                    break;
+                default:
+                    errorReporter.warningReport("Unhandled algorithm: " +
+                                                atts.getAlgorithmIndex(i),
+                                                null);
+            }
+        }
+    }
+}
diff --git a/src/java/org/web3d/parser/x3d/X3DFieldReader.java b/src/java/org/web3d/parser/x3d/X3DFieldReader.java
index b28e8c82414947fe89aae39353880bf241f6f3ac..02cdd238b5b45f576fce24d6b9b9b27374d55a5f 100644
--- a/src/java/org/web3d/parser/x3d/X3DFieldReader.java
+++ b/src/java/org/web3d/parser/x3d/X3DFieldReader.java
@@ -25,6 +25,7 @@ import org.web3d.vrml.sav.Locator;
 /**
  * The field parser implementation class for X3D field values to turn
  * them into Java primitive types.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.16 $
diff --git a/src/java/org/web3d/util/BlockingQueue.java b/src/java/org/web3d/util/BlockingQueue.java
index beaf5ecde0e3a7bd3a1bb9fc0c1caf288f075083..aea135084ce638714690c1af45424929dddd1fae 100644
--- a/src/java/org/web3d/util/BlockingQueue.java
+++ b/src/java/org/web3d/util/BlockingQueue.java
@@ -20,15 +20,17 @@ package org.web3d.util;
 
 /**
  * Blocking 'First In First Out' (FIFO) queue.
+ *  <p>
  *
  * Based on the simple Queue but can be used concurrently by separate
  * threads. If there are not elements in the queue, getNext() will block until
  * it is not empty.
- * 
+ * <p>
  * Taken from the VLC common code library
  * <a href="http://www.vlc.com.au/common/">http://www.vlc.com.au/common/</a>
  * This software is released under the
  * <a href="http://www.gnu.org/copyleft/lgpl.html">GNU LGPL</a>
+ *  <p>
  *
  * @author Justin Couch.
  * @version $Revision: 1.7 $
diff --git a/src/java/org/web3d/util/BooleanArray.java b/src/java/org/web3d/util/BooleanArray.java
index ab890ac3a8e1cbb43554b25a5b1d9e84c9eb2c08..0fa7df6fbdd2bc25d56290fd6cc2a685eb0fa9ec 100644
--- a/src/java/org/web3d/util/BooleanArray.java
+++ b/src/java/org/web3d/util/BooleanArray.java
@@ -20,6 +20,7 @@ package org.web3d.util;
 
 /**
  * Simple dynamic array structure that holds boolean primitives.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/util/ColorUtils.java b/src/java/org/web3d/util/ColorUtils.java
index 191c111a20658d52f49e0a9e8c26d784b0657d9b..26af6a5d991676fccbbe9e5baf2a82855bf5d191 100644
--- a/src/java/org/web3d/util/ColorUtils.java
+++ b/src/java/org/web3d/util/ColorUtils.java
@@ -1,233 +1,233 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.util;
-
-// External imports
-// none
-
-// Local imports
-// none
-
-/**
- * An interpolator that works with color components.
- *  <p>
- *
- * The interpolation routine is just a simple linear interpolation between
- * each of the points. The interpolator may take arbitrarily spaced keyframes
- * and compute correct values.
- * <p>
- * Color interpolation can be done in the standard RGB space (LINEAR) or using
- * the additional type of HSV_LINEAR. This internally converts all color values
- * to HSV space and then interpolates over that instead.
- * <p>
- *
- * The RGB&lt;-&gt;HSV color space conversions have been taken from Foley &amp; van Dam
- * <i>Computer Graphics Principles and Practice, 2nd Edition</i>, Addison
- * Wesley, 1990.
- *
- * @author Justin Couch
- * @version $Revision: 1.3 $
- */
-public class ColorUtils
-{
-    /** The message string when s == 0 and h != NaN */
-    private static final String INVALID_H_MSG =
-        "Invalid h (it has a value) value when s is zero";
-
-    /**
-     * Change an RGB color to HSV color. The value is left in the sharedVector
-     * array for copying. We don't bother converting the alpha as that stays
-     * the same regardless of color space.
-     *
-     * @param rgb The array of RGB components to convert
-     * @param hsv An array to return the colour values with
-     */
-    public static void convertRGBtoHSV(float[] rgb, float[] hsv)
-    {
-        convertRGBtoHSV(rgb[0], rgb[1], rgb[2], hsv);
-    }
-
-    /**
-     * Change an RGB color to HSV color. The value is left in the sharedVector
-     * array for copying. We don't bother converting the alpha as that stays
-     * the same regardless of color space.
-     *
-     * @param r The r component of the color at this key
-     * @param g The g component of the color at this key
-     * @param b The b component of the color at this key
-     * @param hsv An array to return the HSV colour values in
-     */
-    public static void convertRGBtoHSV(float r, float g, float b, float[] hsv)
-    {
-        float h = 0;
-        float s;
-        float v = 0;
-
-        float max = (r > g) ? r : g;
-        max = (max > b) ? max : b;
-
-        float min = (r < g) ? r : g;
-        min = (min < b) ? max : b;
-
-        s = max;    // this is the value v
-
-        // Calculate the saturation s
-        if(max != 0)
-            s = (max - min) / max;
-        else
-            s = 0;
-
-        if(s == 0)
-        {
-            h = Float.NaN;  // h => UNDEFINED
-        }
-        else
-        {
-            // Chromatic case: Saturation is not 0, determine hue
-            float delta = max - min;
-
-            if(r == max)
-            {
-                // resulting color is between yellow and magenta
-                h = (g - b) / delta ;
-            }
-            else if(g == max)
-            {
-                // resulting color is between cyan and yellow
-                h = 2 + (b - r) / delta;
-            }
-            else if(b == max)
-            {
-                // resulting color is between magenta and cyan
-                h = 4 + (r - g) / delta;
-            }
-
-            // convert hue to degrees and make sure it is non-negative
-            h = h * 60;
-            if(h < 0)
-                h += 360;
-        }
-
-        // now assign everything....
-        hsv[0] = h;
-        hsv[1] = s;
-        hsv[2] = v;
-    }
-
-    /**
-     * Change an RGB color to HSV color. The value is left in the sharedVector
-     * array for copying. We don't bother converting the alpha as that stays
-     * the same regardless of color space.
-     *
-     * @param hsv The three components of the color at this key
-     * @param rgb An array to return the RGB colour values in
-     */
-    public static void convertHSVtoRGB(float[] hsv, float[] rgb)
-    {
-        convertHSVtoRGB(hsv[0], hsv[1], hsv[2], rgb);
-    }
-
-    /**
-     * Change an RGB color to HSV color. The value is left in the sharedVector
-     * array for copying. We don't bother converting the alpha as that stays
-     * the same regardless of color space.
-     *
-     * @param h The h component of the color at this key
-     * @param s The s component of the color at this key
-     * @param v The v component of the color at this key
-     * @param rgb An array to return the RGB colour values in
-     */
-    public static void convertHSVtoRGB(float h, float s, float v, float[] rgb)
-    {
-        float r = 0;
-        float g = 0;
-        float b = 0;
-
-        if(s == 0)
-        {
-            // this color in on the black white center line <=> h = UNDEFINED
-            if(h == Float.NaN)
-            {
-                // Achromatic color, there is no hue
-                r = v;
-                g = v;
-                b = v;
-            }
-            else
-            {
-                throw new IllegalArgumentException(INVALID_H_MSG);
-            }
-        }
-        else
-        {
-            if(h == 360)
-            {
-                // 360 is equiv to 0
-                h = 0;
-            }
-
-            // h is now in [0,6)
-            h = h /60;
-
-            int i = (int)Math.floor(h);
-            float f = h - i;             //f is fractional part of h
-            float p = v * (1 - s);
-            float q = v * (1 - (s * f));
-            float t = v * (1 - (s * (1 - f)));
-
-            switch(i)
-            {
-                case 0:
-                   r = v;
-                   g = t;
-                   b = p;
-                   break;
-
-                case 1:
-                   r = q;
-                   g = v;
-                   b = p;
-                   break;
-
-                case 2:
-                   r = p;
-                   g = v;
-                   b = t;
-                   break;
-
-                case 3:
-                   r = p;
-                   g = q;
-                   b = v;
-                   break;
-
-                case 4:
-                   r = t;
-                   g = p;
-                   b = v;
-                   break;
-
-                case 5:
-                   r = v;
-                   g = p;
-                   b = q;
-                   break;
-            }
-        }
-
-        // now assign everything....
-        rgb[0] = r;
-        rgb[1] = g;
-        rgb[2] = b;
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.util;
+
+// External imports
+// none
+
+// Local imports
+// none
+
+/**
+ * An interpolator that works with color components.
+ *  <p>
+ *
+ * The interpolation routine is just a simple linear interpolation between
+ * each of the points. The interpolator may take arbitrarily spaced keyframes
+ * and compute correct values.
+ * <p>
+ * Color interpolation can be done in the standard RGB space (LINEAR) or using
+ * the additional type of HSV_LINEAR. This internally converts all color values
+ * to HSV space and then interpolates over that instead.
+ * <p>
+ *
+ * The RGB&lt;-&gt;HSV color space conversions have been taken from Foley &amp; van Dam
+ * <i>Computer Graphics Principles and Practice, 2nd Edition</i>, Addison
+ * Wesley, 1990.
+ *
+ * @author Justin Couch
+ * @version $Revision: 1.3 $
+ */
+public class ColorUtils
+{
+    /** The message string when s == 0 and h != NaN */
+    private static final String INVALID_H_MSG =
+        "Invalid h (it has a value) value when s is zero";
+
+    /**
+     * Change an RGB color to HSV color. The value is left in the sharedVector
+     * array for copying. We don't bother converting the alpha as that stays
+     * the same regardless of color space.
+     *
+     * @param rgb The array of RGB components to convert
+     * @param hsv An array to return the colour values with
+     */
+    public static void convertRGBtoHSV(float[] rgb, float[] hsv)
+    {
+        convertRGBtoHSV(rgb[0], rgb[1], rgb[2], hsv);
+    }
+
+    /**
+     * Change an RGB color to HSV color. The value is left in the sharedVector
+     * array for copying. We don't bother converting the alpha as that stays
+     * the same regardless of color space.
+     *
+     * @param r The r component of the color at this key
+     * @param g The g component of the color at this key
+     * @param b The b component of the color at this key
+     * @param hsv An array to return the HSV colour values in
+     */
+    public static void convertRGBtoHSV(float r, float g, float b, float[] hsv)
+    {
+        float h = 0;
+        float s;
+        float v = 0;
+
+        float max = (r > g) ? r : g;
+        max = (max > b) ? max : b;
+
+        float min = (r < g) ? r : g;
+        min = (min < b) ? max : b;
+
+        s = max;    // this is the value v
+
+        // Calculate the saturation s
+        if(max != 0)
+            s = (max - min) / max;
+        else
+            s = 0;
+
+        if(s == 0)
+        {
+            h = Float.NaN;  // h => UNDEFINED
+        }
+        else
+        {
+            // Chromatic case: Saturation is not 0, determine hue
+            float delta = max - min;
+
+            if(r == max)
+            {
+                // resulting color is between yellow and magenta
+                h = (g - b) / delta ;
+            }
+            else if(g == max)
+            {
+                // resulting color is between cyan and yellow
+                h = 2 + (b - r) / delta;
+            }
+            else if(b == max)
+            {
+                // resulting color is between magenta and cyan
+                h = 4 + (r - g) / delta;
+            }
+
+            // convert hue to degrees and make sure it is non-negative
+            h = h * 60;
+            if(h < 0)
+                h += 360;
+        }
+
+        // now assign everything....
+        hsv[0] = h;
+        hsv[1] = s;
+        hsv[2] = v;
+    }
+
+    /**
+     * Change an RGB color to HSV color. The value is left in the sharedVector
+     * array for copying. We don't bother converting the alpha as that stays
+     * the same regardless of color space.
+     *
+     * @param hsv The three components of the color at this key
+     * @param rgb An array to return the RGB colour values in
+     */
+    public static void convertHSVtoRGB(float[] hsv, float[] rgb)
+    {
+        convertHSVtoRGB(hsv[0], hsv[1], hsv[2], rgb);
+    }
+
+    /**
+     * Change an RGB color to HSV color. The value is left in the sharedVector
+     * array for copying. We don't bother converting the alpha as that stays
+     * the same regardless of color space.
+     *
+     * @param h The h component of the color at this key
+     * @param s The s component of the color at this key
+     * @param v The v component of the color at this key
+     * @param rgb An array to return the RGB colour values in
+     */
+    public static void convertHSVtoRGB(float h, float s, float v, float[] rgb)
+    {
+        float r = 0;
+        float g = 0;
+        float b = 0;
+
+        if(s == 0)
+        {
+            // this color in on the black white center line <=> h = UNDEFINED
+            if(h == Float.NaN)
+            {
+                // Achromatic color, there is no hue
+                r = v;
+                g = v;
+                b = v;
+            }
+            else
+            {
+                throw new IllegalArgumentException(INVALID_H_MSG);
+            }
+        }
+        else
+        {
+            if(h == 360)
+            {
+                // 360 is equiv to 0
+                h = 0;
+            }
+
+            // h is now in [0,6)
+            h = h /60;
+
+            int i = (int)Math.floor(h);
+            float f = h - i;             //f is fractional part of h
+            float p = v * (1 - s);
+            float q = v * (1 - (s * f));
+            float t = v * (1 - (s * (1 - f)));
+
+            switch(i)
+            {
+                case 0:
+                   r = v;
+                   g = t;
+                   b = p;
+                   break;
+
+                case 1:
+                   r = q;
+                   g = v;
+                   b = p;
+                   break;
+
+                case 2:
+                   r = p;
+                   g = v;
+                   b = t;
+                   break;
+
+                case 3:
+                   r = p;
+                   g = q;
+                   b = v;
+                   break;
+
+                case 4:
+                   r = t;
+                   g = p;
+                   b = v;
+                   break;
+
+                case 5:
+                   r = v;
+                   g = p;
+                   b = q;
+                   break;
+            }
+        }
+
+        // now assign everything....
+        rgb[0] = r;
+        rgb[1] = g;
+        rgb[2] = b;
+    }
+}
diff --git a/src/java/org/web3d/util/DoubleArray.java b/src/java/org/web3d/util/DoubleArray.java
index 82f04abb283dbf5168c3e67fd14658eb40a330b5..36c9c006eb641aece5098661d062cc0f1b32b8c4 100644
--- a/src/java/org/web3d/util/DoubleArray.java
+++ b/src/java/org/web3d/util/DoubleArray.java
@@ -20,6 +20,7 @@ package org.web3d.util;
 
 /**
  * Simple dynamic array structure that holds double primitives.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/util/DoubleToString.java b/src/java/org/web3d/util/DoubleToString.java
index 9c3e827931579e8369b48d4e0c4ef7303a5b7b57..c8b63757d6f1b024b965f941b203e893a001f537 100755
--- a/src/java/org/web3d/util/DoubleToString.java
+++ b/src/java/org/web3d/util/DoubleToString.java
@@ -1,466 +1,466 @@
-/*****************************************************************************
- *                        Shapeways Copyright (c) 2012
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.0
- * Please read http://www.gnu.org/copyleft/gpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.util;
-
-/**
- * Convert doubles to string.  Prioritize speed over accuracy.  Generally
- * attempting to follow the results from NumberFormat.
- *
- * @author Alan Hudson
- */
-public class DoubleToString
-{
-    //Hardcode some byte arrays to make them quickly available
-    public static final char[] INFINITY = {'I','n','f','i','n','i','t','y'};
-    public static final char[] NaN = {'N','a','N'};
-    public static final char[][] ZEROS = {
-            {},
-            {'0'},
-            {'0','0'},
-            {'0','0','0'},
-            {'0','0','0','0'},
-            {'0','0','0','0','0'},
-            {'0','0','0','0','0','0'},
-            {'0','0','0','0','0','0','0'},
-            {'0','0','0','0','0','0','0','0'},
-            {'0','0','0','0','0','0','0','0','0'},
-            {'0','0','0','0','0','0','0','0','0','0'},
-            {'0','0','0','0','0','0','0','0','0','0','0'},
-            {'0','0','0','0','0','0','0','0','0','0','0','0'},
-            {'0','0','0','0','0','0','0','0','0','0','0','0','0'},
-            {'0','0','0','0','0','0','0','0','0','0','0','0','0','0'},
-            {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'},
-            {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'},
-            {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'},
-            {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'},
-            {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'},
-            {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'},
-    };
-
-    private static final char[] charForDigit = {
-            '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h',
-            'i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'
-    };
-
-    //And required double related constants.
-    private static final long  DoubleSignMask = 0x8000000000000000L;
-    private static final long  DoubleExpMask  = 0x7ff0000000000000L;
-    private static final int  DoubleExpShift = 52;
-    private static final int  DoubleExpBias = 1023;
-
-    private static final double[] d_tenthPowers = {
-            1e-323D, 1e-322D, 1e-321D, 1e-320D, 1e-319D, 1e-318D, 1e-317D, 1e-316D, 1e-315D, 1e-314D,
-            1e-313D, 1e-312D, 1e-311D, 1e-310D, 1e-309D, 1e-308D, 1e-307D, 1e-306D, 1e-305D, 1e-304D,
-            1e-303D, 1e-302D, 1e-301D, 1e-300D, 1e-299D, 1e-298D, 1e-297D, 1e-296D, 1e-295D, 1e-294D,
-            1e-293D, 1e-292D, 1e-291D, 1e-290D, 1e-289D, 1e-288D, 1e-287D, 1e-286D, 1e-285D, 1e-284D,
-            1e-283D, 1e-282D, 1e-281D, 1e-280D, 1e-279D, 1e-278D, 1e-277D, 1e-276D, 1e-275D, 1e-274D,
-            1e-273D, 1e-272D, 1e-271D, 1e-270D, 1e-269D, 1e-268D, 1e-267D, 1e-266D, 1e-265D, 1e-264D,
-            1e-263D, 1e-262D, 1e-261D, 1e-260D, 1e-259D, 1e-258D, 1e-257D, 1e-256D, 1e-255D, 1e-254D,
-            1e-253D, 1e-252D, 1e-251D, 1e-250D, 1e-249D, 1e-248D, 1e-247D, 1e-246D, 1e-245D, 1e-244D,
-            1e-243D, 1e-242D, 1e-241D, 1e-240D, 1e-239D, 1e-238D, 1e-237D, 1e-236D, 1e-235D, 1e-234D,
-            1e-233D, 1e-232D, 1e-231D, 1e-230D, 1e-229D, 1e-228D, 1e-227D, 1e-226D, 1e-225D, 1e-224D,
-            1e-223D, 1e-222D, 1e-221D, 1e-220D, 1e-219D, 1e-218D, 1e-217D, 1e-216D, 1e-215D, 1e-214D,
-            1e-213D, 1e-212D, 1e-211D, 1e-210D, 1e-209D, 1e-208D, 1e-207D, 1e-206D, 1e-205D, 1e-204D,
-            1e-203D, 1e-202D, 1e-201D, 1e-200D, 1e-199D, 1e-198D, 1e-197D, 1e-196D, 1e-195D, 1e-194D,
-            1e-193D, 1e-192D, 1e-191D, 1e-190D, 1e-189D, 1e-188D, 1e-187D, 1e-186D, 1e-185D, 1e-184D,
-            1e-183D, 1e-182D, 1e-181D, 1e-180D, 1e-179D, 1e-178D, 1e-177D, 1e-176D, 1e-175D, 1e-174D,
-            1e-173D, 1e-172D, 1e-171D, 1e-170D, 1e-169D, 1e-168D, 1e-167D, 1e-166D, 1e-165D, 1e-164D,
-            1e-163D, 1e-162D, 1e-161D, 1e-160D, 1e-159D, 1e-158D, 1e-157D, 1e-156D, 1e-155D, 1e-154D,
-            1e-153D, 1e-152D, 1e-151D, 1e-150D, 1e-149D, 1e-148D, 1e-147D, 1e-146D, 1e-145D, 1e-144D,
-            1e-143D, 1e-142D, 1e-141D, 1e-140D, 1e-139D, 1e-138D, 1e-137D, 1e-136D, 1e-135D, 1e-134D,
-            1e-133D, 1e-132D, 1e-131D, 1e-130D, 1e-129D, 1e-128D, 1e-127D, 1e-126D, 1e-125D, 1e-124D,
-            1e-123D, 1e-122D, 1e-121D, 1e-120D, 1e-119D, 1e-118D, 1e-117D, 1e-116D, 1e-115D, 1e-114D,
-            1e-113D, 1e-112D, 1e-111D, 1e-110D, 1e-109D, 1e-108D, 1e-107D, 1e-106D, 1e-105D, 1e-104D,
-            1e-103D, 1e-102D, 1e-101D, 1e-100D, 1e-99D, 1e-98D, 1e-97D, 1e-96D, 1e-95D, 1e-94D,
-            1e-93D, 1e-92D, 1e-91D, 1e-90D, 1e-89D, 1e-88D, 1e-87D, 1e-86D, 1e-85D, 1e-84D,
-            1e-83D, 1e-82D, 1e-81D, 1e-80D, 1e-79D, 1e-78D, 1e-77D, 1e-76D, 1e-75D, 1e-74D,
-            1e-73D, 1e-72D, 1e-71D, 1e-70D, 1e-69D, 1e-68D, 1e-67D, 1e-66D, 1e-65D, 1e-64D,
-            1e-63D, 1e-62D, 1e-61D, 1e-60D, 1e-59D, 1e-58D, 1e-57D, 1e-56D, 1e-55D, 1e-54D,
-            1e-53D, 1e-52D, 1e-51D, 1e-50D, 1e-49D, 1e-48D, 1e-47D, 1e-46D, 1e-45D, 1e-44D,
-            1e-43D, 1e-42D, 1e-41D, 1e-40D, 1e-39D, 1e-38D, 1e-37D, 1e-36D, 1e-35D, 1e-34D,
-            1e-33D, 1e-32D, 1e-31D, 1e-30D, 1e-29D, 1e-28D, 1e-27D, 1e-26D, 1e-25D, 1e-24D,
-            1e-23D, 1e-22D, 1e-21D, 1e-20D, 1e-19D, 1e-18D, 1e-17D, 1e-16D, 1e-15D, 1e-14D,
-            1e-13D, 1e-12D, 1e-11D, 1e-10D, 1e-9D, 1e-8D, 1e-7D, 1e-6D, 1e-5D, 1e-4D,
-            1e-3D, 1e-2D, 1e-1D, 1e0D, 1e1D, 1e2D, 1e3D, 1e4D,
-            1e5D, 1e6D, 1e7D, 1e8D, 1e9D, 1e10D, 1e11D, 1e12D, 1e13D, 1e14D,
-            1e15D, 1e16D, 1e17D, 1e18D, 1e19D, 1e20D, 1e21D, 1e22D, 1e23D, 1e24D,
-            1e25D, 1e26D, 1e27D, 1e28D, 1e29D, 1e30D, 1e31D, 1e32D, 1e33D, 1e34D,
-            1e35D, 1e36D, 1e37D, 1e38D, 1e39D, 1e40D, 1e41D, 1e42D, 1e43D, 1e44D,
-            1e45D, 1e46D, 1e47D, 1e48D, 1e49D, 1e50D, 1e51D, 1e52D, 1e53D, 1e54D,
-            1e55D, 1e56D, 1e57D, 1e58D, 1e59D, 1e60D, 1e61D, 1e62D, 1e63D, 1e64D,
-            1e65D, 1e66D, 1e67D, 1e68D, 1e69D, 1e70D, 1e71D, 1e72D, 1e73D, 1e74D,
-            1e75D, 1e76D, 1e77D, 1e78D, 1e79D, 1e80D, 1e81D, 1e82D, 1e83D, 1e84D,
-            1e85D, 1e86D, 1e87D, 1e88D, 1e89D, 1e90D, 1e91D, 1e92D, 1e93D, 1e94D,
-            1e95D, 1e96D, 1e97D, 1e98D, 1e99D, 1e100D, 1e101D, 1e102D, 1e103D, 1e104D,
-            1e105D, 1e106D, 1e107D, 1e108D, 1e109D, 1e110D, 1e111D, 1e112D, 1e113D, 1e114D,
-            1e115D, 1e116D, 1e117D, 1e118D, 1e119D, 1e120D, 1e121D, 1e122D, 1e123D, 1e124D,
-            1e125D, 1e126D, 1e127D, 1e128D, 1e129D, 1e130D, 1e131D, 1e132D, 1e133D, 1e134D,
-            1e135D, 1e136D, 1e137D, 1e138D, 1e139D, 1e140D, 1e141D, 1e142D, 1e143D, 1e144D,
-            1e145D, 1e146D, 1e147D, 1e148D, 1e149D, 1e150D, 1e151D, 1e152D, 1e153D, 1e154D,
-            1e155D, 1e156D, 1e157D, 1e158D, 1e159D, 1e160D, 1e161D, 1e162D, 1e163D, 1e164D,
-            1e165D, 1e166D, 1e167D, 1e168D, 1e169D, 1e170D, 1e171D, 1e172D, 1e173D, 1e174D,
-            1e175D, 1e176D, 1e177D, 1e178D, 1e179D, 1e180D, 1e181D, 1e182D, 1e183D, 1e184D,
-            1e185D, 1e186D, 1e187D, 1e188D, 1e189D, 1e190D, 1e191D, 1e192D, 1e193D, 1e194D,
-            1e195D, 1e196D, 1e197D, 1e198D, 1e199D, 1e200D, 1e201D, 1e202D, 1e203D, 1e204D,
-            1e205D, 1e206D, 1e207D, 1e208D, 1e209D, 1e210D, 1e211D, 1e212D, 1e213D, 1e214D,
-            1e215D, 1e216D, 1e217D, 1e218D, 1e219D, 1e220D, 1e221D, 1e222D, 1e223D, 1e224D,
-            1e225D, 1e226D, 1e227D, 1e228D, 1e229D, 1e230D, 1e231D, 1e232D, 1e233D, 1e234D,
-            1e235D, 1e236D, 1e237D, 1e238D, 1e239D, 1e240D, 1e241D, 1e242D, 1e243D, 1e244D,
-            1e245D, 1e246D, 1e247D, 1e248D, 1e249D, 1e250D, 1e251D, 1e252D, 1e253D, 1e254D,
-            1e255D, 1e256D, 1e257D, 1e258D, 1e259D, 1e260D, 1e261D, 1e262D, 1e263D, 1e264D,
-            1e265D, 1e266D, 1e267D, 1e268D, 1e269D, 1e270D, 1e271D, 1e272D, 1e273D, 1e274D,
-            1e275D, 1e276D, 1e277D, 1e278D, 1e279D, 1e280D, 1e281D, 1e282D, 1e283D, 1e284D,
-            1e285D, 1e286D, 1e287D, 1e288D, 1e289D, 1e290D, 1e291D, 1e292D, 1e293D, 1e294D,
-            1e295D, 1e296D, 1e297D, 1e298D, 1e299D, 1e300D, 1e301D, 1e302D, 1e303D, 1e304D,
-            1e305D, 1e306D, 1e307D, 1e308D
-    };
-
-
-    public static void appendFormatted(StringBuilder s, double d, int numFractDigits)
-    {
-        //First check for the special cases, +/-infinity, Not-a-number and -0.0
-        if (d == Double.NEGATIVE_INFINITY)
-        {
-            //d == -Infinity
-            s.append('-');
-            s.append(INFINITY);
-        }
-        else if (d == Double.POSITIVE_INFINITY)
-            //d == Infinity
-            s.append(INFINITY);
-        else if (d != d)
-            //d == NaN
-            s.append(NaN);
-        else if (d == 0.0)
-        {
-            if ( (Double.doubleToLongBits(d) & DoubleSignMask) != 0)
-            {
-                //d == -0
-                s.append("-0");
-            }
-            else
-                //d == 0
-                s.append('0');
-        }
-        else
-        {
-            //convert to a positive format, and record whether we have a negative
-            //number so that we know later whether to add the negativeSuffix
-            if (d < 0)
-            {
-                s.append('-');
-                d = -d;
-            }
-
-            //Find the magnitude. This is basically the exponent in normal form.
-            int magnitude = magnitude(d);
-
-            //First off, if the number is too small for the given format, we
-            //only print 0.0..., which makes this real quick
-            if ( (magnitude + numFractDigits) < 0)
-            {
-                appendNearlyZeroNumber(s, d, magnitude, numFractDigits);
-                return;
-            }
-
-            long l;
-            //Now scale the double to the biggest long value we need
-            //We need to handle the smallest magnitudes differently because of rounding errors
-
-            //This test is unlikely to ever be true. It would require numFractDigits
-            //to be 305 or more, which is pretty unlikely.
-            /*
-            if (magnitude < -305)
-                l = (long) ((d*1E18) / d_tenthPowers[magnitude + 324]);
-            else
-                l = (long) (d / d_tenthPowers[magnitude + 323 - 17]);
-            */
-            l = (long) ((d*1E18) / d_tenthPowers[magnitude + 324]);
-
-            //And round up if necessary. Add one to the numFractDigits digit if the
-            //numFractDigits+1 digit is 5 or greater. It is useful to know that
-            //given a long, l, the nth digit is obtained using the formula
-            //  nthDigit = (l/(tenthPower(l)/l_tenthPowers[n-1]))%10;
-
-            long l_tenthPower = tenthPower(l);
-            //The numFractDigits+1 digit of the double is the
-            //numFractDigits+1+magnitude digit of the long.
-            //We only need worry about digits within the long. Very large numbers are
-            //not rounded because all the digits after the decimal points are 0 anyway
-            if (numFractDigits+magnitude+1 < l_tenthPowers.length)
-            {
-                long dv1 = l_tenthPower / l_tenthPowers[numFractDigits+magnitude+1];
-
-                if (dv1 != 0) {
-                    long digit = (l / dv1) % 10;
-                    if (digit >= 5)
-                    {
-                        // TODO: This just broke things for -9.992718696594238E-5 because magnitude changed?
-                        l += l_tenthPower/l_tenthPowers[numFractDigits+magnitude];
-
-                        // Alan added this to fix case that outputted a
-                        long n_tenthPower = tenthPower(l);
-                        if (n_tenthPower >= l_tenthPower * 10) {
-                            // TODO: could it ever change more then 10, if so we must peel
-                            magnitude++;
-                        }
-                        l_tenthPower = n_tenthPower;
-                    }
-                }
-            }
-
-            //And now we just print out our long, with the decimal point character
-            //inserted in the right place, using as many places as we wanted.
-            appendAsDouble(s, l, l_tenthPower, magnitude, numFractDigits);
-
-        }
-    }
-
-    public static void appendAsDouble(StringBuilder s, long l, long l_mag, int d_magnitude,
-                               int numFractDigits)
-    {
-       //If the magnitude is negative, we have a 0.xxx number
-        if (d_magnitude < 0)
-        {
-//            s.append('0').append(decimalPoint).append(ZEROS[-d_magnitude-1]);
-            s.append('.').append(ZEROS[-d_magnitude-1]);
-            //And just print successive digits until we have reached numFractDigits
-            //First decrement numFractDigits by the number of digits already printed
-            numFractDigits += d_magnitude;
-
-            //get the magnitude of l
-            long c;
-            int zcount = 0;
-            while(numFractDigits-- >= 0)
-            {
-                //Get the leading character (e.g. '62345/10000 = 6' using integer-divide)
-                c = l/l_mag;
-                //Append the digit character for this digit (e.g. number is 6, so character is '6')
-                if (c == 0) {
-                    zcount++;
-                } else {
-                    if (zcount > 0) {
-                        for(int i=zcount; i > 0; i--) {
-                            s.append(charForDigit[0]);
-                        }
-                        zcount=0;
-                        s.append(charForDigit[(int) c]);
-                    } else {
-                        s.append(charForDigit[(int) c]);
-                    }
-                }
-                //Multiply by the leading digit by the magnitude so that we can eliminate the leading digit
-                //(e.g. 6 * 10000 = 60000)
-                c *= l_mag;
-                //and eliminate the leading digit (e.g. 62345-60000 = 2345)
-                if ( c <= l)
-                    l -= c;
-                //Decrease the magnitude by 10, and repeat the loop.
-                l_mag = l_mag/10;
-            }
-        }
-        else
-        {
-            //Just keep printing until magnitude is 0
-            long c;
-            while(d_magnitude-- >= 0)
-            {
-
-                if (l_mag == 0) {s.append('0');continue;}
-                //Get the leading character (e.g. '62345/10000 = 6' using integer-divide)
-                c = l/l_mag;
-                //Append the digit character for this digit (e.g. number is 6, so character is '6')
-                s.append(charForDigit[(int) c]);
-
-/*
-                //Don't forget about the thousands separator
-                if (d_magnitude % numDigitsSeparated == (numDigitsSeparated-1))
-                    s.append(thousandsSeparator);
-*/
-                //Multiply by the leading digit by the magnitude so that we can eliminate the leading digit
-                //(e.g. 6 * 10000 = 60000)
-                c *= l_mag;
-                //and eliminate the leading digit (e.g. 62345-60000 = 2345)
-                if ( c <= l)
-                    l -= c;
-                //Decrease the magnitude by 10, and repeat the loop.
-                l_mag = l_mag/10;
-            }
-
-            if (l_mag == 0){
-                // Alan: removed trailing zeros
-                //s.append(ZEROS[numFractDigits]);
-            } else
-            {
-                int zcount = 0;
-                boolean dp_added = false;
-                while(numFractDigits-- > 0)
-                {
-                    // ALAN: removed to avoid extra trailing
-                    if (l_mag == 0) {
-                        //s.append('0');
-                        continue;
-                    }
-                    //Get the leading character (e.g. '62345/10000 = 6' using integer-divide)
-                    c = l/l_mag;
-                    if (c == 0) {
-                        zcount++;
-                    } else {
-                        if (zcount > 0) {
-                            if (!dp_added) {
-                                s.append('.');
-                                dp_added = true;
-                            }
-
-                            for(int i=zcount; i > 0; i--) {
-                                s.append(charForDigit[0]);
-                            }
-                            zcount = 0;
-                        }
-
-                        if (!dp_added) {
-                            s.append('.');
-                            dp_added = true;
-                        }
-
-                        //Append the digit character for this digit (e.g. number is 6, so character is '6')
-                        s.append(charForDigit[(int) c]);
-                    }
-                    //Multiply by the leading digit by the magnitude so that we can eliminate the leading digit
-                    //(e.g. 6 * 10000 = 60000)
-                    c *= l_mag;
-                    //and eliminate the leading digit (e.g. 62345-60000 = 2345)
-                    if ( c <= l)
-                        l -= c;
-                    //Decrease the magnitude by 10, and repeat the loop.
-                    l_mag = l_mag/10;
-                }
-
-            }
-
-        }
-
-    }
-
-
-    private static void appendNearlyZeroNumber(StringBuilder s, double d, int d_magnitude,
-                                        int numFractDigits)
-    {
-        if (d_magnitude + numFractDigits == -1)
-        {
-            //Possibly too small, depends on whether the top digit is 5 or greater
-            //So we have to scale to get the leading digit
-            int i;
-            if (d_magnitude < -305)
-                //Probably not necessary. Who is going to print 305 places?
-                i = (int) ((d*1E19) / d_tenthPowers[d_magnitude + 324 + 18]);
-            else
-                i = (int) (d / d_tenthPowers[d_magnitude + 323]);
-
-            if (i >= 5)
-            {
-                //Not too small, we get to round up
-                s.append('.').append(ZEROS[numFractDigits-1]);
-                s.append('1');
-            }
-            else
-            {
-                //Definitely too small. Just print zeros
-//                s.append('0').append(decimalPoint).append(ZEROS[numFractDigits]);
-                s.append('0');
-            }
-        }
-        else
-        {
-            //Definitely too small
-//            s.append('0').append(decimalPoint).append(ZEROS[numFractDigits]);
-            s.append('0');
-        }
-    }
-
-    /**
-     * Assumes i is positive. Returns the magnitude of i in base 10.
-     */
-    private static long tenthPower(long i)
-    {
-        if (i < 10L) return 1;
-        else if (i < 100L) return 10L;
-        else if (i < 1000L) return 100L;
-        else if (i < 10000L) return 1000L;
-        else if (i < 100000L) return 10000L;
-        else if (i < 1000000L) return 100000L;
-        else if (i < 10000000L) return 1000000L;
-        else if (i < 100000000L) return 10000000L;
-        else if (i < 1000000000L) return 100000000L;
-        else if (i < 10000000000L) return 1000000000L;
-        else if (i < 100000000000L) return 10000000000L;
-        else if (i < 1000000000000L) return 100000000000L;
-        else if (i < 10000000000000L) return 1000000000000L;
-        else if (i < 100000000000000L) return 10000000000000L;
-        else if (i < 1000000000000000L) return 100000000000000L;
-        else if (i < 10000000000000000L) return 1000000000000000L;
-        else if (i < 100000000000000000L) return 10000000000000000L;
-        else if (i < 1000000000000000000L) return 100000000000000000L;
-        else return  1000000000000000000L;
-    }
-
-
-    private static int magnitude(double d)
-    {
-        //It works. What else can I say.
-        long doubleToLongBits = Double.doubleToLongBits(d);
-        int magnitude =
-                (int) ((((doubleToLongBits & DoubleExpMask) >> DoubleExpShift) - DoubleExpBias) * 0.301029995663981);
-
-        if (magnitude < -323)
-            magnitude = -323;
-        else if (magnitude > 308)
-            magnitude = 308;
-
-        if (d >= d_tenthPowers[magnitude+323])
-        {
-            while(magnitude < 309 && d >= d_tenthPowers[magnitude+323])
-                magnitude++;
-            magnitude--;
-            return magnitude;
-        }
-        else
-        {
-            while(magnitude > -324 && d < d_tenthPowers[magnitude+323])
-                magnitude--;
-            return magnitude;
-        }
-    }
-
-    static long[] l_tenthPowers = {
-            1,
-            10L,
-            100L,
-            1000L,
-            10000L,
-            100000L,
-            1000000L,
-            10000000L,
-            100000000L,
-            1000000000L,
-            10000000000L,
-            100000000000L,
-            1000000000000L,
-            10000000000000L,
-            100000000000000L,
-            1000000000000000L,
-            10000000000000000L,
-            100000000000000000L,
-            1000000000000000000L,
-    };
+/*****************************************************************************
+ *                        Shapeways Copyright (c) 2012
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.0
+ * Please read http://www.gnu.org/copyleft/gpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.util;
+
+/**
+ * Convert doubles to string.  Prioritize speed over accuracy.  Generally
+ * attempting to follow the results from NumberFormat.
+ *
+ * @author Alan Hudson
+ */
+public class DoubleToString
+{
+    //Hardcode some byte arrays to make them quickly available
+    public static final char[] INFINITY = {'I','n','f','i','n','i','t','y'};
+    public static final char[] NaN = {'N','a','N'};
+    public static final char[][] ZEROS = {
+            {},
+            {'0'},
+            {'0','0'},
+            {'0','0','0'},
+            {'0','0','0','0'},
+            {'0','0','0','0','0'},
+            {'0','0','0','0','0','0'},
+            {'0','0','0','0','0','0','0'},
+            {'0','0','0','0','0','0','0','0'},
+            {'0','0','0','0','0','0','0','0','0'},
+            {'0','0','0','0','0','0','0','0','0','0'},
+            {'0','0','0','0','0','0','0','0','0','0','0'},
+            {'0','0','0','0','0','0','0','0','0','0','0','0'},
+            {'0','0','0','0','0','0','0','0','0','0','0','0','0'},
+            {'0','0','0','0','0','0','0','0','0','0','0','0','0','0'},
+            {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'},
+            {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'},
+            {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'},
+            {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'},
+            {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'},
+            {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'},
+    };
+
+    private static final char[] charForDigit = {
+            '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h',
+            'i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'
+    };
+
+    //And required double related constants.
+    private static final long  DoubleSignMask = 0x8000000000000000L;
+    private static final long  DoubleExpMask  = 0x7ff0000000000000L;
+    private static final int  DoubleExpShift = 52;
+    private static final int  DoubleExpBias = 1023;
+
+    private static final double[] d_tenthPowers = {
+            1e-323D, 1e-322D, 1e-321D, 1e-320D, 1e-319D, 1e-318D, 1e-317D, 1e-316D, 1e-315D, 1e-314D,
+            1e-313D, 1e-312D, 1e-311D, 1e-310D, 1e-309D, 1e-308D, 1e-307D, 1e-306D, 1e-305D, 1e-304D,
+            1e-303D, 1e-302D, 1e-301D, 1e-300D, 1e-299D, 1e-298D, 1e-297D, 1e-296D, 1e-295D, 1e-294D,
+            1e-293D, 1e-292D, 1e-291D, 1e-290D, 1e-289D, 1e-288D, 1e-287D, 1e-286D, 1e-285D, 1e-284D,
+            1e-283D, 1e-282D, 1e-281D, 1e-280D, 1e-279D, 1e-278D, 1e-277D, 1e-276D, 1e-275D, 1e-274D,
+            1e-273D, 1e-272D, 1e-271D, 1e-270D, 1e-269D, 1e-268D, 1e-267D, 1e-266D, 1e-265D, 1e-264D,
+            1e-263D, 1e-262D, 1e-261D, 1e-260D, 1e-259D, 1e-258D, 1e-257D, 1e-256D, 1e-255D, 1e-254D,
+            1e-253D, 1e-252D, 1e-251D, 1e-250D, 1e-249D, 1e-248D, 1e-247D, 1e-246D, 1e-245D, 1e-244D,
+            1e-243D, 1e-242D, 1e-241D, 1e-240D, 1e-239D, 1e-238D, 1e-237D, 1e-236D, 1e-235D, 1e-234D,
+            1e-233D, 1e-232D, 1e-231D, 1e-230D, 1e-229D, 1e-228D, 1e-227D, 1e-226D, 1e-225D, 1e-224D,
+            1e-223D, 1e-222D, 1e-221D, 1e-220D, 1e-219D, 1e-218D, 1e-217D, 1e-216D, 1e-215D, 1e-214D,
+            1e-213D, 1e-212D, 1e-211D, 1e-210D, 1e-209D, 1e-208D, 1e-207D, 1e-206D, 1e-205D, 1e-204D,
+            1e-203D, 1e-202D, 1e-201D, 1e-200D, 1e-199D, 1e-198D, 1e-197D, 1e-196D, 1e-195D, 1e-194D,
+            1e-193D, 1e-192D, 1e-191D, 1e-190D, 1e-189D, 1e-188D, 1e-187D, 1e-186D, 1e-185D, 1e-184D,
+            1e-183D, 1e-182D, 1e-181D, 1e-180D, 1e-179D, 1e-178D, 1e-177D, 1e-176D, 1e-175D, 1e-174D,
+            1e-173D, 1e-172D, 1e-171D, 1e-170D, 1e-169D, 1e-168D, 1e-167D, 1e-166D, 1e-165D, 1e-164D,
+            1e-163D, 1e-162D, 1e-161D, 1e-160D, 1e-159D, 1e-158D, 1e-157D, 1e-156D, 1e-155D, 1e-154D,
+            1e-153D, 1e-152D, 1e-151D, 1e-150D, 1e-149D, 1e-148D, 1e-147D, 1e-146D, 1e-145D, 1e-144D,
+            1e-143D, 1e-142D, 1e-141D, 1e-140D, 1e-139D, 1e-138D, 1e-137D, 1e-136D, 1e-135D, 1e-134D,
+            1e-133D, 1e-132D, 1e-131D, 1e-130D, 1e-129D, 1e-128D, 1e-127D, 1e-126D, 1e-125D, 1e-124D,
+            1e-123D, 1e-122D, 1e-121D, 1e-120D, 1e-119D, 1e-118D, 1e-117D, 1e-116D, 1e-115D, 1e-114D,
+            1e-113D, 1e-112D, 1e-111D, 1e-110D, 1e-109D, 1e-108D, 1e-107D, 1e-106D, 1e-105D, 1e-104D,
+            1e-103D, 1e-102D, 1e-101D, 1e-100D, 1e-99D, 1e-98D, 1e-97D, 1e-96D, 1e-95D, 1e-94D,
+            1e-93D, 1e-92D, 1e-91D, 1e-90D, 1e-89D, 1e-88D, 1e-87D, 1e-86D, 1e-85D, 1e-84D,
+            1e-83D, 1e-82D, 1e-81D, 1e-80D, 1e-79D, 1e-78D, 1e-77D, 1e-76D, 1e-75D, 1e-74D,
+            1e-73D, 1e-72D, 1e-71D, 1e-70D, 1e-69D, 1e-68D, 1e-67D, 1e-66D, 1e-65D, 1e-64D,
+            1e-63D, 1e-62D, 1e-61D, 1e-60D, 1e-59D, 1e-58D, 1e-57D, 1e-56D, 1e-55D, 1e-54D,
+            1e-53D, 1e-52D, 1e-51D, 1e-50D, 1e-49D, 1e-48D, 1e-47D, 1e-46D, 1e-45D, 1e-44D,
+            1e-43D, 1e-42D, 1e-41D, 1e-40D, 1e-39D, 1e-38D, 1e-37D, 1e-36D, 1e-35D, 1e-34D,
+            1e-33D, 1e-32D, 1e-31D, 1e-30D, 1e-29D, 1e-28D, 1e-27D, 1e-26D, 1e-25D, 1e-24D,
+            1e-23D, 1e-22D, 1e-21D, 1e-20D, 1e-19D, 1e-18D, 1e-17D, 1e-16D, 1e-15D, 1e-14D,
+            1e-13D, 1e-12D, 1e-11D, 1e-10D, 1e-9D, 1e-8D, 1e-7D, 1e-6D, 1e-5D, 1e-4D,
+            1e-3D, 1e-2D, 1e-1D, 1e0D, 1e1D, 1e2D, 1e3D, 1e4D,
+            1e5D, 1e6D, 1e7D, 1e8D, 1e9D, 1e10D, 1e11D, 1e12D, 1e13D, 1e14D,
+            1e15D, 1e16D, 1e17D, 1e18D, 1e19D, 1e20D, 1e21D, 1e22D, 1e23D, 1e24D,
+            1e25D, 1e26D, 1e27D, 1e28D, 1e29D, 1e30D, 1e31D, 1e32D, 1e33D, 1e34D,
+            1e35D, 1e36D, 1e37D, 1e38D, 1e39D, 1e40D, 1e41D, 1e42D, 1e43D, 1e44D,
+            1e45D, 1e46D, 1e47D, 1e48D, 1e49D, 1e50D, 1e51D, 1e52D, 1e53D, 1e54D,
+            1e55D, 1e56D, 1e57D, 1e58D, 1e59D, 1e60D, 1e61D, 1e62D, 1e63D, 1e64D,
+            1e65D, 1e66D, 1e67D, 1e68D, 1e69D, 1e70D, 1e71D, 1e72D, 1e73D, 1e74D,
+            1e75D, 1e76D, 1e77D, 1e78D, 1e79D, 1e80D, 1e81D, 1e82D, 1e83D, 1e84D,
+            1e85D, 1e86D, 1e87D, 1e88D, 1e89D, 1e90D, 1e91D, 1e92D, 1e93D, 1e94D,
+            1e95D, 1e96D, 1e97D, 1e98D, 1e99D, 1e100D, 1e101D, 1e102D, 1e103D, 1e104D,
+            1e105D, 1e106D, 1e107D, 1e108D, 1e109D, 1e110D, 1e111D, 1e112D, 1e113D, 1e114D,
+            1e115D, 1e116D, 1e117D, 1e118D, 1e119D, 1e120D, 1e121D, 1e122D, 1e123D, 1e124D,
+            1e125D, 1e126D, 1e127D, 1e128D, 1e129D, 1e130D, 1e131D, 1e132D, 1e133D, 1e134D,
+            1e135D, 1e136D, 1e137D, 1e138D, 1e139D, 1e140D, 1e141D, 1e142D, 1e143D, 1e144D,
+            1e145D, 1e146D, 1e147D, 1e148D, 1e149D, 1e150D, 1e151D, 1e152D, 1e153D, 1e154D,
+            1e155D, 1e156D, 1e157D, 1e158D, 1e159D, 1e160D, 1e161D, 1e162D, 1e163D, 1e164D,
+            1e165D, 1e166D, 1e167D, 1e168D, 1e169D, 1e170D, 1e171D, 1e172D, 1e173D, 1e174D,
+            1e175D, 1e176D, 1e177D, 1e178D, 1e179D, 1e180D, 1e181D, 1e182D, 1e183D, 1e184D,
+            1e185D, 1e186D, 1e187D, 1e188D, 1e189D, 1e190D, 1e191D, 1e192D, 1e193D, 1e194D,
+            1e195D, 1e196D, 1e197D, 1e198D, 1e199D, 1e200D, 1e201D, 1e202D, 1e203D, 1e204D,
+            1e205D, 1e206D, 1e207D, 1e208D, 1e209D, 1e210D, 1e211D, 1e212D, 1e213D, 1e214D,
+            1e215D, 1e216D, 1e217D, 1e218D, 1e219D, 1e220D, 1e221D, 1e222D, 1e223D, 1e224D,
+            1e225D, 1e226D, 1e227D, 1e228D, 1e229D, 1e230D, 1e231D, 1e232D, 1e233D, 1e234D,
+            1e235D, 1e236D, 1e237D, 1e238D, 1e239D, 1e240D, 1e241D, 1e242D, 1e243D, 1e244D,
+            1e245D, 1e246D, 1e247D, 1e248D, 1e249D, 1e250D, 1e251D, 1e252D, 1e253D, 1e254D,
+            1e255D, 1e256D, 1e257D, 1e258D, 1e259D, 1e260D, 1e261D, 1e262D, 1e263D, 1e264D,
+            1e265D, 1e266D, 1e267D, 1e268D, 1e269D, 1e270D, 1e271D, 1e272D, 1e273D, 1e274D,
+            1e275D, 1e276D, 1e277D, 1e278D, 1e279D, 1e280D, 1e281D, 1e282D, 1e283D, 1e284D,
+            1e285D, 1e286D, 1e287D, 1e288D, 1e289D, 1e290D, 1e291D, 1e292D, 1e293D, 1e294D,
+            1e295D, 1e296D, 1e297D, 1e298D, 1e299D, 1e300D, 1e301D, 1e302D, 1e303D, 1e304D,
+            1e305D, 1e306D, 1e307D, 1e308D
+    };
+
+
+    public static void appendFormatted(StringBuilder s, double d, int numFractDigits)
+    {
+        //First check for the special cases, +/-infinity, Not-a-number and -0.0
+        if (d == Double.NEGATIVE_INFINITY)
+        {
+            //d == -Infinity
+            s.append('-');
+            s.append(INFINITY);
+        }
+        else if (d == Double.POSITIVE_INFINITY)
+            //d == Infinity
+            s.append(INFINITY);
+        else if (d != d)
+            //d == NaN
+            s.append(NaN);
+        else if (d == 0.0)
+        {
+            if ( (Double.doubleToLongBits(d) & DoubleSignMask) != 0)
+            {
+                //d == -0
+                s.append("-0");
+            }
+            else
+                //d == 0
+                s.append('0');
+        }
+        else
+        {
+            //convert to a positive format, and record whether we have a negative
+            //number so that we know later whether to add the negativeSuffix
+            if (d < 0)
+            {
+                s.append('-');
+                d = -d;
+            }
+
+            //Find the magnitude. This is basically the exponent in normal form.
+            int magnitude = magnitude(d);
+
+            //First off, if the number is too small for the given format, we
+            //only print 0.0..., which makes this real quick
+            if ( (magnitude + numFractDigits) < 0)
+            {
+                appendNearlyZeroNumber(s, d, magnitude, numFractDigits);
+                return;
+            }
+
+            long l;
+            //Now scale the double to the biggest long value we need
+            //We need to handle the smallest magnitudes differently because of rounding errors
+
+            //This test is unlikely to ever be true. It would require numFractDigits
+            //to be 305 or more, which is pretty unlikely.
+            /*
+            if (magnitude < -305)
+                l = (long) ((d*1E18) / d_tenthPowers[magnitude + 324]);
+            else
+                l = (long) (d / d_tenthPowers[magnitude + 323 - 17]);
+            */
+            l = (long) ((d*1E18) / d_tenthPowers[magnitude + 324]);
+
+            //And round up if necessary. Add one to the numFractDigits digit if the
+            //numFractDigits+1 digit is 5 or greater. It is useful to know that
+            //given a long, l, the nth digit is obtained using the formula
+            //  nthDigit = (l/(tenthPower(l)/l_tenthPowers[n-1]))%10;
+
+            long l_tenthPower = tenthPower(l);
+            //The numFractDigits+1 digit of the double is the
+            //numFractDigits+1+magnitude digit of the long.
+            //We only need worry about digits within the long. Very large numbers are
+            //not rounded because all the digits after the decimal points are 0 anyway
+            if (numFractDigits+magnitude+1 < l_tenthPowers.length)
+            {
+                long dv1 = l_tenthPower / l_tenthPowers[numFractDigits+magnitude+1];
+
+                if (dv1 != 0) {
+                    long digit = (l / dv1) % 10;
+                    if (digit >= 5)
+                    {
+                        // TODO: This just broke things for -9.992718696594238E-5 because magnitude changed?
+                        l += l_tenthPower/l_tenthPowers[numFractDigits+magnitude];
+
+                        // Alan added this to fix case that outputted a
+                        long n_tenthPower = tenthPower(l);
+                        if (n_tenthPower >= l_tenthPower * 10) {
+                            // TODO: could it ever change more then 10, if so we must peel
+                            magnitude++;
+                        }
+                        l_tenthPower = n_tenthPower;
+                    }
+                }
+            }
+
+            //And now we just print out our long, with the decimal point character
+            //inserted in the right place, using as many places as we wanted.
+            appendAsDouble(s, l, l_tenthPower, magnitude, numFractDigits);
+
+        }
+    }
+
+    public static void appendAsDouble(StringBuilder s, long l, long l_mag, int d_magnitude,
+                               int numFractDigits)
+    {
+       //If the magnitude is negative, we have a 0.xxx number
+        if (d_magnitude < 0)
+        {
+//            s.append('0').append(decimalPoint).append(ZEROS[-d_magnitude-1]);
+            s.append('.').append(ZEROS[-d_magnitude-1]);
+            //And just print successive digits until we have reached numFractDigits
+            //First decrement numFractDigits by the number of digits already printed
+            numFractDigits += d_magnitude;
+
+            //get the magnitude of l
+            long c;
+            int zcount = 0;
+            while(numFractDigits-- >= 0)
+            {
+                //Get the leading character (e.g. '62345/10000 = 6' using integer-divide)
+                c = l/l_mag;
+                //Append the digit character for this digit (e.g. number is 6, so character is '6')
+                if (c == 0) {
+                    zcount++;
+                } else {
+                    if (zcount > 0) {
+                        for(int i=zcount; i > 0; i--) {
+                            s.append(charForDigit[0]);
+                        }
+                        zcount=0;
+                        s.append(charForDigit[(int) c]);
+                    } else {
+                        s.append(charForDigit[(int) c]);
+                    }
+                }
+                //Multiply by the leading digit by the magnitude so that we can eliminate the leading digit
+                //(e.g. 6 * 10000 = 60000)
+                c *= l_mag;
+                //and eliminate the leading digit (e.g. 62345-60000 = 2345)
+                if ( c <= l)
+                    l -= c;
+                //Decrease the magnitude by 10, and repeat the loop.
+                l_mag = l_mag/10;
+            }
+        }
+        else
+        {
+            //Just keep printing until magnitude is 0
+            long c;
+            while(d_magnitude-- >= 0)
+            {
+
+                if (l_mag == 0) {s.append('0');continue;}
+                //Get the leading character (e.g. '62345/10000 = 6' using integer-divide)
+                c = l/l_mag;
+                //Append the digit character for this digit (e.g. number is 6, so character is '6')
+                s.append(charForDigit[(int) c]);
+
+/*
+                //Don't forget about the thousands separator
+                if (d_magnitude % numDigitsSeparated == (numDigitsSeparated-1))
+                    s.append(thousandsSeparator);
+*/
+                //Multiply by the leading digit by the magnitude so that we can eliminate the leading digit
+                //(e.g. 6 * 10000 = 60000)
+                c *= l_mag;
+                //and eliminate the leading digit (e.g. 62345-60000 = 2345)
+                if ( c <= l)
+                    l -= c;
+                //Decrease the magnitude by 10, and repeat the loop.
+                l_mag = l_mag/10;
+            }
+
+            if (l_mag == 0){
+                // Alan: removed trailing zeros
+                //s.append(ZEROS[numFractDigits]);
+            } else
+            {
+                int zcount = 0;
+                boolean dp_added = false;
+                while(numFractDigits-- > 0)
+                {
+                    // ALAN: removed to avoid extra trailing
+                    if (l_mag == 0) {
+                        //s.append('0');
+                        continue;
+                    }
+                    //Get the leading character (e.g. '62345/10000 = 6' using integer-divide)
+                    c = l/l_mag;
+                    if (c == 0) {
+                        zcount++;
+                    } else {
+                        if (zcount > 0) {
+                            if (!dp_added) {
+                                s.append('.');
+                                dp_added = true;
+                            }
+
+                            for(int i=zcount; i > 0; i--) {
+                                s.append(charForDigit[0]);
+                            }
+                            zcount = 0;
+                        }
+
+                        if (!dp_added) {
+                            s.append('.');
+                            dp_added = true;
+                        }
+
+                        //Append the digit character for this digit (e.g. number is 6, so character is '6')
+                        s.append(charForDigit[(int) c]);
+                    }
+                    //Multiply by the leading digit by the magnitude so that we can eliminate the leading digit
+                    //(e.g. 6 * 10000 = 60000)
+                    c *= l_mag;
+                    //and eliminate the leading digit (e.g. 62345-60000 = 2345)
+                    if ( c <= l)
+                        l -= c;
+                    //Decrease the magnitude by 10, and repeat the loop.
+                    l_mag = l_mag/10;
+                }
+
+            }
+
+        }
+
+    }
+
+
+    private static void appendNearlyZeroNumber(StringBuilder s, double d, int d_magnitude,
+                                        int numFractDigits)
+    {
+        if (d_magnitude + numFractDigits == -1)
+        {
+            //Possibly too small, depends on whether the top digit is 5 or greater
+            //So we have to scale to get the leading digit
+            int i;
+            if (d_magnitude < -305)
+                //Probably not necessary. Who is going to print 305 places?
+                i = (int) ((d*1E19) / d_tenthPowers[d_magnitude + 324 + 18]);
+            else
+                i = (int) (d / d_tenthPowers[d_magnitude + 323]);
+
+            if (i >= 5)
+            {
+                //Not too small, we get to round up
+                s.append('.').append(ZEROS[numFractDigits-1]);
+                s.append('1');
+            }
+            else
+            {
+                //Definitely too small. Just print zeros
+//                s.append('0').append(decimalPoint).append(ZEROS[numFractDigits]);
+                s.append('0');
+            }
+        }
+        else
+        {
+            //Definitely too small
+//            s.append('0').append(decimalPoint).append(ZEROS[numFractDigits]);
+            s.append('0');
+        }
+    }
+
+    /**
+     * Assumes i is positive. Returns the magnitude of i in base 10.
+     */
+    private static long tenthPower(long i)
+    {
+        if (i < 10L) return 1;
+        else if (i < 100L) return 10L;
+        else if (i < 1000L) return 100L;
+        else if (i < 10000L) return 1000L;
+        else if (i < 100000L) return 10000L;
+        else if (i < 1000000L) return 100000L;
+        else if (i < 10000000L) return 1000000L;
+        else if (i < 100000000L) return 10000000L;
+        else if (i < 1000000000L) return 100000000L;
+        else if (i < 10000000000L) return 1000000000L;
+        else if (i < 100000000000L) return 10000000000L;
+        else if (i < 1000000000000L) return 100000000000L;
+        else if (i < 10000000000000L) return 1000000000000L;
+        else if (i < 100000000000000L) return 10000000000000L;
+        else if (i < 1000000000000000L) return 100000000000000L;
+        else if (i < 10000000000000000L) return 1000000000000000L;
+        else if (i < 100000000000000000L) return 10000000000000000L;
+        else if (i < 1000000000000000000L) return 100000000000000000L;
+        else return  1000000000000000000L;
+    }
+
+
+    private static int magnitude(double d)
+    {
+        //It works. What else can I say.
+        long doubleToLongBits = Double.doubleToLongBits(d);
+        int magnitude =
+                (int) ((((doubleToLongBits & DoubleExpMask) >> DoubleExpShift) - DoubleExpBias) * 0.301029995663981);
+
+        if (magnitude < -323)
+            magnitude = -323;
+        else if (magnitude > 308)
+            magnitude = 308;
+
+        if (d >= d_tenthPowers[magnitude+323])
+        {
+            while(magnitude < 309 && d >= d_tenthPowers[magnitude+323])
+                magnitude++;
+            magnitude--;
+            return magnitude;
+        }
+        else
+        {
+            while(magnitude > -324 && d < d_tenthPowers[magnitude+323])
+                magnitude--;
+            return magnitude;
+        }
+    }
+
+    static long[] l_tenthPowers = {
+            1,
+            10L,
+            100L,
+            1000L,
+            10000L,
+            100000L,
+            1000000L,
+            10000000L,
+            100000000L,
+            1000000000L,
+            10000000000L,
+            100000000000L,
+            1000000000000L,
+            10000000000000L,
+            100000000000000L,
+            1000000000000000L,
+            10000000000000000L,
+            100000000000000000L,
+            1000000000000000000L,
+    };
 }
\ No newline at end of file
diff --git a/src/java/org/web3d/util/FileHandler.java b/src/java/org/web3d/util/FileHandler.java
index 014ac6f9deaf27fd8df684eed3da9118af0fce93..b9c350924d799c83833524f99d5bc57b7515d16a 100644
--- a/src/java/org/web3d/util/FileHandler.java
+++ b/src/java/org/web3d/util/FileHandler.java
@@ -20,6 +20,7 @@ import org.j3d.util.ErrorReporter;
 
 /**
  * Interface representing code that can open a file or URL in the browser.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/util/FloatArray.java b/src/java/org/web3d/util/FloatArray.java
index 663ca635cb0e9b2137e2e1f24ec6aa91af53e366..d91b4c8b461348bbac2630c6e9e0dbef7096b72e 100644
--- a/src/java/org/web3d/util/FloatArray.java
+++ b/src/java/org/web3d/util/FloatArray.java
@@ -20,6 +20,7 @@ package org.web3d.util;
 
 /**
  * Simple dynamic array structure that holds float primitives.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/util/I18nUtils.java b/src/java/org/web3d/util/I18nUtils.java
index b5b364739f45860f547ae14a70d897c903b9b031..7c7c7f18156f65fef32aa46d8abcccc4ae3e695d 100644
--- a/src/java/org/web3d/util/I18nUtils.java
+++ b/src/java/org/web3d/util/I18nUtils.java
@@ -1,86 +1,86 @@
-package org.web3d.util;
-
-import org.j3d.util.I18nManager;
-
-import java.text.Format;
-import java.text.MessageFormat;
-import java.util.Locale;
-
-/**
- * Internationalization utilities
- *
- * @author Alan Hudson
- */
-public class I18nUtils {
-
-    public static final String EXT_MSG = "EXTMSG:";
-    public static final String CRIT_MSG = "CRITMSG:";
-
-    /**
-     * Set the manager to use the given application's set of localization
-     * settings.
-     *
-     * @param appName A name string describing the end user application
-     * @param resourceFiles If not null, use this as the resource bundle
-     *    base name to be fetched, rather than the default file name
-     */
-    public static void setApplication(String appName, String[] resourceFiles) {
-        I18nManagerMultiResource intl_mgr = I18nManagerMultiResource.getManager();
-        intl_mgr.setApplication(appName, resourceFiles);
-    }
-
-    /**
-     * Print the message.
-     *
-     * @param msgName The name of the message
-     * @param msgMarker The marker or label to add to the beginning of the message
-     * @param msgArgs Additional arguments to the message
-     */
-    public static void printMsg(String msgName, String msgMarker, String[] msgArgs) {
-        I18nManagerMultiResource intl_multi_mgr = I18nManagerMultiResource.getManager();
-        String msg;
-        Locale locale;
-
-        try {
-            msg = intl_multi_mgr.getString(msgName);
-            locale = intl_multi_mgr.getFoundLocale();
-        } catch (Exception e) {
-            System.err.println("Resource for I18nManagerMultiResource not set. Falling back to I18nManager.");
-
-            I18nManager intl_mgr = I18nManager.getManager();
-            msg = intl_mgr.getString(msgName);
-            locale = intl_mgr.getFoundLocale();
-        }
-
-
-        if (msgArgs != null && msgArgs.length > 0) {
-            Format[] fmts = { null };
-            MessageFormat msg_fmt = new MessageFormat(msg, locale);
-            msg_fmt.setFormats(fmts);
-            msg = msg_fmt.format(msgArgs);
-        }
-
-        System.err.println(msgMarker + msg);
-    }
-
-    /**
-     * Get the message corresponding to the message name.
-     *
-     * @param msgName The name of the message
-     * @param msgArgs Additional arguments to the message
-     * @return The message
-     */
-    public static String getMsg(String msgName, String[] msgArgs) {
-    	I18nManagerMultiResource intl_mgr = I18nManagerMultiResource.getManager();
-    	String msg = intl_mgr.getString(msgName);
-
-        if (msgArgs != null && msgArgs.length > 0) {
-            Format[] fmts = { null };
-            MessageFormat msg_fmt = new MessageFormat(msg, intl_mgr.getFoundLocale());
-            msg_fmt.setFormats(fmts);
-            msg = msg_fmt.format(msgArgs);
-        }
-
-        return msg;
-    }
-}
+package org.web3d.util;
+
+import org.j3d.util.I18nManager;
+
+import java.text.Format;
+import java.text.MessageFormat;
+import java.util.Locale;
+
+/**
+ * Internationalization utilities
+ *
+ * @author Alan Hudson
+ */
+public class I18nUtils {
+
+    public static final String EXT_MSG = "EXTMSG:";
+    public static final String CRIT_MSG = "CRITMSG:";
+
+    /**
+     * Set the manager to use the given application's set of localization
+     * settings.
+     *
+     * @param appName A name string describing the end user application
+     * @param resourceFiles If not null, use this as the resource bundle
+     *    base name to be fetched, rather than the default file name
+     */
+    public static void setApplication(String appName, String[] resourceFiles) {
+        I18nManagerMultiResource intl_mgr = I18nManagerMultiResource.getManager();
+        intl_mgr.setApplication(appName, resourceFiles);
+    }
+
+    /**
+     * Print the message.
+     *
+     * @param msgName The name of the message
+     * @param msgMarker The marker or label to add to the beginning of the message
+     * @param msgArgs Additional arguments to the message
+     */
+    public static void printMsg(String msgName, String msgMarker, String[] msgArgs) {
+        I18nManagerMultiResource intl_multi_mgr = I18nManagerMultiResource.getManager();
+        String msg;
+        Locale locale;
+
+        try {
+            msg = intl_multi_mgr.getString(msgName);
+            locale = intl_multi_mgr.getFoundLocale();
+        } catch (Exception e) {
+            System.err.println("Resource for I18nManagerMultiResource not set. Falling back to I18nManager.");
+
+            I18nManager intl_mgr = I18nManager.getManager();
+            msg = intl_mgr.getString(msgName);
+            locale = intl_mgr.getFoundLocale();
+        }
+
+
+        if (msgArgs != null && msgArgs.length > 0) {
+            Format[] fmts = { null };
+            MessageFormat msg_fmt = new MessageFormat(msg, locale);
+            msg_fmt.setFormats(fmts);
+            msg = msg_fmt.format(msgArgs);
+        }
+
+        System.err.println(msgMarker + msg);
+    }
+
+    /**
+     * Get the message corresponding to the message name.
+     *
+     * @param msgName The name of the message
+     * @param msgArgs Additional arguments to the message
+     * @return The message
+     */
+    public static String getMsg(String msgName, String[] msgArgs) {
+    	I18nManagerMultiResource intl_mgr = I18nManagerMultiResource.getManager();
+    	String msg = intl_mgr.getString(msgName);
+
+        if (msgArgs != null && msgArgs.length > 0) {
+            Format[] fmts = { null };
+            MessageFormat msg_fmt = new MessageFormat(msg, intl_mgr.getFoundLocale());
+            msg_fmt.setFormats(fmts);
+            msg = msg_fmt.format(msgArgs);
+        }
+
+        return msg;
+    }
+}
diff --git a/src/java/org/web3d/util/IntArray.java b/src/java/org/web3d/util/IntArray.java
index 64674e219ff223160a12543aa934f70d54d50dc7..65ea5674e6aba5df975c7942dba3673f252abd33 100644
--- a/src/java/org/web3d/util/IntArray.java
+++ b/src/java/org/web3d/util/IntArray.java
@@ -20,6 +20,7 @@ package org.web3d.util;
 
 /**
  * Simple dynamic array structure that holds int primitives.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/util/LongArray.java b/src/java/org/web3d/util/LongArray.java
index a1f62aea9bf9d790cdd5352bf8ed52001c9a0de1..f36136b470a5bc940f4af7099643fe395ec64b44 100644
--- a/src/java/org/web3d/util/LongArray.java
+++ b/src/java/org/web3d/util/LongArray.java
@@ -20,6 +20,7 @@ package org.web3d.util;
 
 /**
  * Simple dynamic array structure that holds long primitives.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.4 $
diff --git a/src/java/org/web3d/util/MathUtils.java b/src/java/org/web3d/util/MathUtils.java
index 2fb6e603ba0a9dd57311d8f2603450eb07e0d75b..4462159602a70cf59fce9ebc81a72c21b0956414 100644
--- a/src/java/org/web3d/util/MathUtils.java
+++ b/src/java/org/web3d/util/MathUtils.java
@@ -1,69 +1,69 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2006 - 2007
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.util;
-
-// External imports
-// none
-
-// Local imports
-// none
-
-/**
- * Utility class for miscellaneous calculations,
- * primarily used in pre-processing images.
- *
- * @author Rex Melton
- * @version $Revision: 1.2 $
- */
-public abstract class MathUtils {
-
-    /**
-     * Determine the nearest power of two value for a given argument.
-     * This function uses the formal ln(x) / ln(2) = log2(x)
-     *
-     * @param val
-     * @param imageScaleUp
-     * @return The power-of-two-ized value
-     */
-    public static int nearestPowerTwo(int val, boolean imageScaleUp) {
-        int log;
-
-        if (imageScaleUp) {
-            log = (int) Math.ceil(Math.log(val) / Math.log(2));
-        } else {
-            log = (int) Math.floor(Math.log(val) / Math.log(2));
-        }
-
-        return (int) Math.pow(2,log);
-    }
-
-    /**
-     * Compute the n where 2^n = value.
-     *
-     * @param value The value to compute.
-     * @return
-     */
-    public static int computeLog(int value) {
-        int i = 0;
-
-        if (value == 0)
-            return -1;
-
-        for (;;) {
-            if (value == 1)
-                return i;
-            value >>= 1;
-            i++;
-        }
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2006 - 2007
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.util;
+
+// External imports
+// none
+
+// Local imports
+// none
+
+/**
+ * Utility class for miscellaneous calculations,
+ * primarily used in pre-processing images.
+ *
+ * @author Rex Melton
+ * @version $Revision: 1.2 $
+ */
+public abstract class MathUtils {
+
+    /**
+     * Determine the nearest power of two value for a given argument.
+     * This function uses the formal ln(x) / ln(2) = log2(x)
+     *
+     * @param val
+     * @param imageScaleUp
+     * @return The power-of-two-ized value
+     */
+    public static int nearestPowerTwo(int val, boolean imageScaleUp) {
+        int log;
+
+        if (imageScaleUp) {
+            log = (int) Math.ceil(Math.log(val) / Math.log(2));
+        } else {
+            log = (int) Math.floor(Math.log(val) / Math.log(2));
+        }
+
+        return (int) Math.pow(2,log);
+    }
+
+    /**
+     * Compute the n where 2^n = value.
+     *
+     * @param value The value to compute.
+     * @return
+     */
+    public static int computeLog(int value) {
+        int i = 0;
+
+        if (value == 0)
+            return -1;
+
+        for (;;) {
+            if (value == 1)
+                return i;
+            value >>= 1;
+            i++;
+        }
+    }
+}
diff --git a/src/java/org/web3d/util/PropertyTools.java b/src/java/org/web3d/util/PropertyTools.java
index 04363c3133f48901e27ef35b719831780610f288..1f4e65031d474ad46fe3f8890917f39db6f3936b 100644
--- a/src/java/org/web3d/util/PropertyTools.java
+++ b/src/java/org/web3d/util/PropertyTools.java
@@ -1,117 +1,117 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.util;
-
-// External Imports
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Map;
-
-// Local imports
-// None
-
-/**
- * A set of tools for locating property values.
- *
- * @author Alan Hudson
- * @version $Revision: 1.3 $
- */
-public class PropertyTools {
-    /**
-     * Go looking for the named system property.
-     *
-     * @param propName The name of the property to read
-     * @param def The default value if not found
-     * @return
-     */
-    public static String fetchSystemProperty(final String propName,
-                                           String def) {
-
-        String prop = (String)AccessController.doPrivileged((PrivilegedAction<Object>) () -> System.getProperty(propName));
-
-        if (prop == null) {
-            return def;
-        } else {
-            System.out.println(propName + " set to: " + prop);
-            return prop;
-        }
-    }
-
-    /**
-     * Go looking for the named system property.
-     *
-     * @param propName The name of the property to read
-     * @param def The default value if not found
-     * @return
-     */
-    public static boolean fetchSystemProperty(final String propName,
-                                           boolean def) {
-        boolean b;
-        String prop = (String)AccessController.doPrivileged((PrivilegedAction<Object>) () -> System.getProperty(propName));
-
-        if (prop == null)
-            return def;
-        else {
-            b = Boolean.valueOf(prop);
-            System.out.println(propName + " set to: " + b);
-            return b;
-        }
-    }
-
-    /**
-     * Go looking for the named system property.
-     *
-     * @param propName The name of the property to read
-     * @param def The default value if not found
-     * @param map Mapping of the property string to values
-     * @return
-     */
-    public static int fetchSystemProperty(final String propName,
-                                           int def,
-                                           Map<String, Integer> map) {
-
-        Integer i;
-        String prop = (String)AccessController.doPrivileged((PrivilegedAction<Object>) () -> System.getProperty(propName));
-
-        if (prop == null)
-            return def;
-        else {
-            i = map.get(prop);
-            if (i == null) {
-                System.out.println(propName + " invalid Property: " + prop);
-                return def;
-            }
-            else {
-                System.out.println(propName + " set to: " + i);
-                return i;
-            }
-        }
-    }
-
-    /**
-     * Go looking for the named system property.
-     *
-     * @param propName The name of the property to read
-     * @param def The default value if not found
-     * @return
-     */
-    public static int fetchSystemProperty(final String propName,
-                                           final int def) {
-        Integer prop = (Integer)AccessController.doPrivileged((PrivilegedAction<Object>) () -> Integer.getInteger(propName, def));
-
-        int i = prop;
-        if (i != def)
-            System.out.println(propName + " set to: " + i);
-        return i;
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.util;
+
+// External Imports
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Map;
+
+// Local imports
+// None
+
+/**
+ * A set of tools for locating property values.
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.3 $
+ */
+public class PropertyTools {
+    /**
+     * Go looking for the named system property.
+     *
+     * @param propName The name of the property to read
+     * @param def The default value if not found
+     * @return
+     */
+    public static String fetchSystemProperty(final String propName,
+                                           String def) {
+
+        String prop = (String)AccessController.doPrivileged((PrivilegedAction<Object>) () -> System.getProperty(propName));
+
+        if (prop == null) {
+            return def;
+        } else {
+            System.out.println(propName + " set to: " + prop);
+            return prop;
+        }
+    }
+
+    /**
+     * Go looking for the named system property.
+     *
+     * @param propName The name of the property to read
+     * @param def The default value if not found
+     * @return
+     */
+    public static boolean fetchSystemProperty(final String propName,
+                                           boolean def) {
+        boolean b;
+        String prop = (String)AccessController.doPrivileged((PrivilegedAction<Object>) () -> System.getProperty(propName));
+
+        if (prop == null)
+            return def;
+        else {
+            b = Boolean.valueOf(prop);
+            System.out.println(propName + " set to: " + b);
+            return b;
+        }
+    }
+
+    /**
+     * Go looking for the named system property.
+     *
+     * @param propName The name of the property to read
+     * @param def The default value if not found
+     * @param map Mapping of the property string to values
+     * @return
+     */
+    public static int fetchSystemProperty(final String propName,
+                                           int def,
+                                           Map<String, Integer> map) {
+
+        Integer i;
+        String prop = (String)AccessController.doPrivileged((PrivilegedAction<Object>) () -> System.getProperty(propName));
+
+        if (prop == null)
+            return def;
+        else {
+            i = map.get(prop);
+            if (i == null) {
+                System.out.println(propName + " invalid Property: " + prop);
+                return def;
+            }
+            else {
+                System.out.println(propName + " set to: " + i);
+                return i;
+            }
+        }
+    }
+
+    /**
+     * Go looking for the named system property.
+     *
+     * @param propName The name of the property to read
+     * @param def The default value if not found
+     * @return
+     */
+    public static int fetchSystemProperty(final String propName,
+                                           final int def) {
+        Integer prop = (Integer)AccessController.doPrivileged((PrivilegedAction<Object>) () -> Integer.getInteger(propName, def));
+
+        int i = prop;
+        if (i != def)
+            System.out.println(propName + " set to: " + i);
+        return i;
+    }
+}
diff --git a/src/java/org/web3d/util/ShortHashMap.java b/src/java/org/web3d/util/ShortHashMap.java
index dcea58d8b3de2929e10d55525a6a53b8c11b4f79..880f3e36589b3ad940b0682cf351681bc8130137 100644
--- a/src/java/org/web3d/util/ShortHashMap.java
+++ b/src/java/org/web3d/util/ShortHashMap.java
@@ -20,6 +20,8 @@ import java.util.Arrays;
 
 /**
  * A hash map that uses primitive shorts for the key rather than objects.
+ *  <p>
+ *
  *
  * @author Justin Couch
  * @version $Revision: 1.6 $
diff --git a/src/java/org/web3d/util/SimpleStackInterface.java b/src/java/org/web3d/util/SimpleStackInterface.java
index 6e0d9475dc387dab643dbe28da499db11c2f6900..19464030ac84e5e010aabe2c125ac934061cef99 100755
--- a/src/java/org/web3d/util/SimpleStackInterface.java
+++ b/src/java/org/web3d/util/SimpleStackInterface.java
@@ -20,6 +20,7 @@ import java.util.EmptyStackException;
 
 /**
  * A stack that has a minimal implementation.
+ *  <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.10 $
diff --git a/src/java/org/web3d/util/StringArray.java b/src/java/org/web3d/util/StringArray.java
index f8e2301211612d88ff66630d72546f7ca96bed07..10395f2b76938eb3a5a36c089e8747150fffc19c 100644
--- a/src/java/org/web3d/util/StringArray.java
+++ b/src/java/org/web3d/util/StringArray.java
@@ -20,6 +20,7 @@ package org.web3d.util;
 
 /**
  * Simple dynamic array structure that holds String primitives.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.6 $
diff --git a/src/java/org/web3d/util/Version.java b/src/java/org/web3d/util/Version.java
new file mode 100644
index 0000000000000000000000000000000000000000..28f6c18c19cad3ab89c2b6b5ed7c5c0493e1772d
--- /dev/null
+++ b/src/java/org/web3d/util/Version.java
@@ -0,0 +1,100 @@
+/*
+Copyright (c) 1995-2015 held by the author(s).  All rights reserved.
+
+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 names of the Naval Postgraduate School (NPS)
+      Modeling Virtual Environments and Simulation (MOVES) Institute
+      (http://www.nps.edu and http://www.movesinstitute.org)
+      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 org.web3d.util;
+
+import java.util.PropertyResourceBundle;
+import java.util.ResourceBundle;
+
+/**
+ * Creates the version stamp information when built via regex updates from Ant
+ * @version $Id: Version.java 12564M 2019-12-13 20:12:38Z (local) $
+ * @author <a href="mailto:tdnorbra@nps.edu?subject=org.web3d.util.Version">Terry Norbraten</a>
+ */
+public class Version {
+
+    /** These must be programmatically changed by the developer */
+    public static final String BUILD_MAJOR_VERSION = getProjectProperties().getString("product.version.major");
+    public static final String BUILD_MINOR_VERSION = getProjectProperties().getString("product.version.level") + "-nps";
+    public static final String JAVA_VERSION = System.getProperty("java.version");
+
+    /** These strings are set by the timestamp task in the build file
+     * so need not be modified here
+     */
+    public static final String BUILD_DSTAMP = "20090227";
+    public static final String BUILD_TSTAMP = "1407";
+    public static final String BUILD_TODAY  = "February 27 2009";
+
+    public static final String SP = " ";
+    public static final String PERIOD = ".";
+
+    private static final String DIS_VER = getProjectProperties().getString("open.dis.ver");
+    public static final String OPEN_DIS_VERSION = "NPS Open DIS v" + DIS_VER;
+
+    /** Customizable message to be displayed */
+    public static final String DEVELOPER_CUSTOM_MESSAGE = "\nutilizing " +
+            OPEN_DIS_VERSION + "\nwith 3D rendering by\n" +
+            org.j3d.aviatrix3d.Aviatrix3dVersion.getInstance() + "\non top of\n" + 
+            com.jogamp.opengl.JoglVersion.getInstance();
+	
+    // https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html
+    public static final String OS_JAVA_VERSION_MESSAGE  = "Operating system: " + System.getProperty("os.name") + SP + System.getProperty("os.version") + "\n" +
+                                                          "Java environment: " + System.getProperty("java.vendor") + SP + JAVA_VERSION + "\n";
+    /**
+     * The release version. Milestone format will be
+     * <code>M<i>MainVersion</i>_<i>DevRelease#</i></code>
+     */
+    public static final String XJ3D_VERSION = "v" + BUILD_MAJOR_VERSION + PERIOD +
+            BUILD_MINOR_VERSION + SP + DEVELOPER_CUSTOM_MESSAGE + SP + "\n" +
+			OS_JAVA_VERSION_MESSAGE + 
+            "\nBuildStamp time and date:" + SP + BUILD_TSTAMP + SP + "on" + SP + BUILD_TODAY;
+
+    /**
+     * <p>Project specific Project properties resourced from
+     * configuration/project.properties.  These are not expected to dynamically
+     * change during runtime.</p>
+     * @return specific Project properties resourced from config/xj3d.properties
+     */
+    public static ResourceBundle getProjectProperties() {
+        return PropertyResourceBundle.getBundle("config.xj3d");
+    }
+
+    /**
+     * Command line entry point for this class
+     * @param args command line arguments if any
+     */
+    public static void main(String args[]) {
+        System.out.println("Xj3D" + SP + XJ3D_VERSION);
+    }
+
+} // end class file Version.java
diff --git a/src/java/org/web3d/util/spatial/SpatialPartition.java b/src/java/org/web3d/util/spatial/SpatialPartition.java
index 03bf437f079571668d187dd39d3e246734102d88..97f8b6d570bee31ebccd5890bba07c20d6a8b4ca 100755
--- a/src/java/org/web3d/util/spatial/SpatialPartition.java
+++ b/src/java/org/web3d/util/spatial/SpatialPartition.java
@@ -1,40 +1,40 @@
-/*****************************************************************************
- *                        Yumetech Copyright (c) 2011
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.util.spatial;
-
-// External Imports
-// None
-
-// Internal Imports
-
-/**
- * A structure which can spatial partition items.
- *
- * @author Alan Hudson.
- */
-public interface SpatialPartition {
-    /**
-     * Clear the structure of all data.
-     */
-    void clear();
-
-    /**
-     * Gets the objects in the specified region. Any object which is contained
-     * or overlaps the region will be returned.  Objects exactly on a voxel
-     * boundary shall be returned in all touching regions.
-     *
-     * @param region The region of interest.
-     * @return objs The list of object ids
-     */
-    int[] getObjects(Region region);
-}
+/*****************************************************************************
+ *                        Yumetech Copyright (c) 2011
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.util.spatial;
+
+// External Imports
+// None
+
+// Internal Imports
+
+/**
+ * A structure which can spatial partition items.
+ *
+ * @author Alan Hudson.
+ */
+public interface SpatialPartition {
+    /**
+     * Clear the structure of all data.
+     */
+    void clear();
+
+    /**
+     * Gets the objects in the specified region. Any object which is contained
+     * or overlaps the region will be returned.  Objects exactly on a voxel
+     * boundary shall be returned in all touching regions.
+     *
+     * @param region The region of interest.
+     * @return objs The list of object ids
+     */
+    int[] getObjects(Region region);
+}
diff --git a/src/java/org/web3d/util/spatial/Vec3DDouble.java b/src/java/org/web3d/util/spatial/Vec3DDouble.java
index 153fb54a7b243375dc1414bb14bd23cbb99dd3a0..418a415b3ea3eb00ec7b888ef1dce7c5fef5cf47 100755
--- a/src/java/org/web3d/util/spatial/Vec3DDouble.java
+++ b/src/java/org/web3d/util/spatial/Vec3DDouble.java
@@ -1,1594 +1,1594 @@
-/*
- *   __               .__       .__  ._____.
- * _/  |_  _______  __|__| ____ |  | |__\_ |__   ______
- * \   __\/  _ \  \/  /  |/ ___\|  | |  || __ \ /  ___/
- *  |  | (  <_> >    <|  \  \___|  |_|  || \_\ \\___ \
- *  |__|  \____/__/\_ \__|\___  >____/__||___  /____  >
- *                   \/       \/             \/     \/
- *
- * Copyright (c) 2006-2011 Karsten Schmidt
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * http://creativecommons.org/licenses/LGPL/2.1/
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-package org.web3d.util.spatial;
-
-import toxi.geom.*;
-
-import java.util.Random;
-
-import javax.xml.bind.annotation.XmlAttribute;
-
-import toxi.math.InterpolateStrategy;
-import toxi.math.MathUtils;
-import toxi.math.ScaleMap;
-
-/**
- * Comprehensive 3D vector class with additional basic intersection and
- * collision detection features.
- */
-public class Vec3DDouble implements Comparable<ReadonlyVec3DDouble>, ReadonlyVec3DDouble {
-
-    public static enum Axis {
-
-        X(Vec3DDouble.X_AXIS), Y(Vec3DDouble.Y_AXIS), Z(Vec3DDouble.Z_AXIS);
-
-        private final ReadonlyVec3DDouble vector;
-
-        private Axis(ReadonlyVec3DDouble v) {
-            this.vector = v;
-        }
-
-        public ReadonlyVec3DDouble getVector() {
-            return vector;
-        }
-    }
-
-    /** Defines positive X axis. */
-    public static final ReadonlyVec3DDouble X_AXIS = new Vec3DDouble(1, 0, 0);
-
-    /** Defines positive Y axis. */
-    public static final ReadonlyVec3DDouble Y_AXIS = new Vec3DDouble(0, 1, 0);
-
-    /** Defines positive Z axis. */
-    public static final ReadonlyVec3DDouble Z_AXIS = new Vec3DDouble(0, 0, 1);
-
-    /** Defines the zero vector. */
-    public static final ReadonlyVec3DDouble ZERO = new Vec3DDouble();
-
-    /**
-     * Defines vector with all coords set to Double.MIN_VALUE. Useful for
-     * bounding box operations.
-     */
-    public static final ReadonlyVec3DDouble MIN_VALUE = new Vec3DDouble(Double.MIN_VALUE,
-            Double.MIN_VALUE, Double.MIN_VALUE);
-
-    /**
-     * Defines vector with all coords set to Double.MAX_VALUE. Useful for
-     * bounding box operations.
-     */
-    public static final ReadonlyVec3DDouble MAX_VALUE = new Vec3DDouble(Double.MAX_VALUE,
-            Double.MAX_VALUE, Double.MAX_VALUE);
-
-    /**
-     * Creates a new vector from the given angle in the XY plane. The Z
-     * component of the vector will be zero.
-     *
-     * The resulting vector for theta=0 is equal to the positive X axis.
-     *
-     * @param theta
-     *            the theta
-     *
-     * @return new vector in the XY plane
-     */
-    public static Vec3DDouble fromXYTheta(double theta) {
-        return new Vec3DDouble(Math.cos(theta), Math.sin(theta), 0);
-    }
-
-    /**
-     * Creates a new vector from the given angle in the XZ plane. The Y
-     * component of the vector will be zero.
-     *
-     * The resulting vector for theta=0 is equal to the positive X axis.
-     *
-     * @param theta
-     *            the theta
-     *
-     * @return new vector in the XZ plane
-     */
-    public static Vec3DDouble fromXZTheta(double theta) {
-        return new Vec3DDouble(Math.cos(theta), 0, Math.sin(theta));
-    }
-
-    /**
-     * Creates a new vector from the given angle in the YZ plane. The X
-     * component of the vector will be zero.
-     *
-     * The resulting vector for theta=0 is equal to the positive Y axis.
-     *
-     * @param theta
-     *            the theta
-     *
-     * @return new vector in the YZ plane
-     */
-    public static Vec3DDouble fromYZTheta(double theta) {
-        return new Vec3DDouble(0, Math.cos(theta), Math.sin(theta));
-    }
-
-    /**
-     * Constructs a new vector consisting of the largest components of both
-     * vectors.
-     *
-     * @param b
-     *            the b
-     * @param a
-     *            the a
-     *
-     * @return result as new vector
-     */
-    public static Vec3DDouble max(ReadonlyVec3DDouble a, ReadonlyVec3DDouble b) {
-        return new Vec3DDouble(MathUtils.max(a.x(), b.x()), MathUtils.max(a.y(),
-                b.y()), MathUtils.max(a.z(), b.z()));
-    }
-
-    /**
-     * Constructs a new vector consisting of the smallest components of both
-     * vectors.
-     *
-     * @param b
-     *            comparing vector
-     * @param a
-     *            the a
-     *
-     * @return result as new vector
-     */
-    public static Vec3DDouble min(ReadonlyVec3DDouble a, ReadonlyVec3DDouble b) {
-        return new Vec3DDouble(MathUtils.min(a.x(), b.x()), MathUtils.min(a.y(),
-                b.y()), MathUtils.min(a.z(), b.z()));
-    }
-
-    /**
-     * Static factory method. Creates a new random unit vector using the Random
-     * implementation set as default for the {@link MathUtils} class.
-     *
-     * @return a new random normalized unit vector.
-     */
-    public static Vec3DDouble randomVector() {
-        return randomVector(MathUtils.RND);
-    }
-
-    /**
-     * Static factory method. Creates a new random unit vector using the given
-     * Random generator instance. I recommend to have a look at the
-     * https://uncommons-maths.dev.java.net library for a good choice of
-     * reliable and high quality random number generators.
-     *
-     * @param rnd
-     *            the rnd
-     *
-     * @return a new random normalized unit vector.
-     */
-    public static Vec3DDouble randomVector(Random rnd) {
-        Vec3DDouble v = new Vec3DDouble(rnd.nextDouble() * 2 - 1, rnd.nextDouble() * 2 - 1,
-                rnd.nextDouble() * 2 - 1);
-        return v.normalize();
-    }
-
-    /** X coordinate. */
-    @XmlAttribute(required = true)
-    public double x;
-
-    /** Y coordinate. */
-    @XmlAttribute(required = true)
-    public double y;
-
-    /** Z coordinate. */
-    @XmlAttribute(required = true)
-    public double z;
-
-    /**
-     * Creates a new zero vector.
-     */
-    public Vec3DDouble() {
-    }
-
-    /**
-     * Creates a new vector with the given coordinates.
-     *
-     * @param x
-     *            the x
-     * @param y
-     *            the y
-     * @param z
-     *            the z
-     */
-    public Vec3DDouble(double x, double y, double z) {
-        this.x = x;
-        this.y = y;
-        this.z = z;
-    }
-
-    public Vec3DDouble(double[] v) {
-        this.x = v[0];
-        this.y = v[1];
-        this.z = v[2];
-    }
-
-    /**
-     * Creates a new vector with the coordinates of the given vector.
-     *
-     * @param v
-     *            vector to be copied
-     */
-    public Vec3DDouble(ReadonlyVec3DDouble v) {
-        this.x = v.x();
-        this.y = v.y();
-        this.z = v.z();
-    }
-
-    /**
-     * Abs.
-     *
-     * @return the vec3 d
-     */
-    public final Vec3DDouble abs() {
-        x = MathUtils.abs(x);
-        y = MathUtils.abs(y);
-        z = MathUtils.abs(z);
-        return this;
-    }
-
-    @Override
-    public final Vec3DDouble add(double a, double b, double c) {
-        return new Vec3DDouble(x + a, y + b, z + c);
-    }
-
-    @Override
-    public Vec3DDouble add(ReadonlyVec3DDouble v) {
-        return new Vec3DDouble(x + v.x(), y + v.y(), z + v.z());
-    }
-
-    @Override
-    public final Vec3DDouble add(Vec3DDouble v) {
-        return new Vec3DDouble(x + v.x, y + v.y, z + v.z);
-    }
-
-    /**
-     * Adds vector {a,b,c} and overrides coordinates with result.
-     *
-     * @param a
-     *            X coordinate
-     * @param b
-     *            Y coordinate
-     * @param c
-     *            Z coordinate
-     *
-     * @return itself
-     */
-    public final Vec3DDouble addSelf(double a, double b, double c) {
-        x += a;
-        y += b;
-        z += c;
-        return this;
-    }
-
-    public final Vec3DDouble addSelf(ReadonlyVec3DDouble v) {
-        x += v.x();
-        y += v.y();
-        z += v.z();
-        return this;
-    }
-
-    /**
-     * Adds vector v and overrides coordinates with result.
-     *
-     * @param v
-     *            vector to add
-     *
-     * @return itself
-     */
-    public final Vec3DDouble addSelf(Vec3DDouble v) {
-        x += v.x;
-        y += v.y;
-        z += v.z;
-        return this;
-    }
-
-    @Override
-    public final double angleBetween(ReadonlyVec3DDouble v) {
-        return Math.acos(dot(v));
-    }
-
-    @Override
-    public final double angleBetween(ReadonlyVec3DDouble v, boolean forceNormalize) {
-        double theta;
-        if (forceNormalize) {
-            theta = getNormalized().dot(v.getNormalized());
-        } else {
-            theta = dot(v);
-        }
-        return Math.acos(theta);
-    }
-
-    /**
-     * Sets all vector components to 0.
-     *
-     * @return itself
-     */
-    public final ReadonlyVec3DDouble clear() {
-        x = y = z = 0;
-        return this;
-    }
-
-    @Override
-    public int compareTo(ReadonlyVec3DDouble v) {
-        if (x == v.x() && y == v.y() && z == v.z()) {
-            return 0;
-        }
-        double a = magSquared();
-        double b = v.magSquared();
-        if (a < b) {
-            return -1;
-        }
-        return +1;
-    }
-
-    /**
-     * Forcefully fits the vector in the given AABB.
-     *
-     * @param box
-     *            the box
-     *
-     * @return itself
-     */
-    public final Vec3DDouble constrain(AABB box) {
-        return constrain(box.getMin(), box.getMax());
-    }
-
-    /**
-     * Forcefully fits the vector in the given AABB specified by the 2 given
-     * points.
-     *
-     * @param min
-     * @param max
-     * @return itself
-     */
-    public final Vec3DDouble constrain(Vec3D min, Vec3D max) {
-        x = MathUtils.clip(x, min.x, max.x);
-        y = MathUtils.clip(y, min.y, max.y);
-        z = MathUtils.clip(z, min.z, max.z);
-        return this;
-    }
-
-    @Override
-    public Vec3DDouble copy() {
-        return new Vec3DDouble(this);
-    }
-
-    @Override
-    public final Vec3DDouble cross(ReadonlyVec3DDouble v) {
-        return new Vec3DDouble(y * v.z() - v.y() * z, z * v.x() - v.z() * x, x
-                * v.y() - v.x() * y);
-    }
-
-    public final Vec3DDouble cross(Vec3DDouble v) {
-        return new Vec3DDouble(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x
-                * y);
-    }
-
-    @Override
-    public final Vec3DDouble crossInto(ReadonlyVec3DDouble v, Vec3DDouble result) {
-        final double vx = v.x();
-        final double vy = v.y();
-        final double vz = v.z();
-        result.x = y * vz - vy * z;
-        result.y = z * vx - vz * x;
-        result.z = x * vy - vx * y;
-        return result;
-    }
-
-    /**
-     * Calculates cross-product with vector v. The resulting vector is
-     * perpendicular to both the current and supplied vector and overrides the
-     * current.
-     *
-     * @param v
-     *            the v
-     *
-     * @return itself
-     */
-    public final Vec3DDouble crossSelf(Vec3DDouble v) {
-        final double cx = y * v.z - v.y * z;
-        final double cy = z * v.x - v.z * x;
-        z = x * v.y - v.x * y;
-        y = cy;
-        x = cx;
-        return this;
-    }
-
-    @Override
-    public final double distanceTo(ReadonlyVec3DDouble v) {
-        if (v != null) {
-            final double dx = x - v.x();
-            final double dy = y - v.y();
-            final double dz = z - v.z();
-            return Math.sqrt(dx * dx + dy * dy + dz * dz);
-        } else {
-            return Double.NaN;
-        }
-    }
-
-    @Override
-    public final double distanceToSquared(ReadonlyVec3DDouble v) {
-        if (v != null) {
-            final double dx = x - v.x();
-            final double dy = y - v.y();
-            final double dz = z - v.z();
-            return dx * dx + dy * dy + dz * dz;
-        } else {
-            return Double.NaN;
-        }
-    }
-
-    @Override
-    public final double dot(ReadonlyVec3DDouble v) {
-        return x * v.x() + y * v.y() + z * v.z();
-    }
-
-    public final double dot(Vec3DDouble v) {
-        return x * v.x + y * v.y + z * v.z;
-    }
-
-    /**
-     * Returns true if the Object v is of type ReadonlyVec3DDouble and all of the data
-     * members of v are equal to the corresponding data members in this vector.
-     *
-     * @param v
-     *            the Object with which the comparison is made
-     * @return true or false
-     */
-    @Override
-    public boolean equals(Object v) {
-        boolean retVal = false;
-        if (v instanceof ReadonlyVec3DDouble)
-            try {
-                ReadonlyVec3DDouble vv = (ReadonlyVec3DDouble) v;
-                retVal = (x == vv.x() && y == vv.y() && z == vv.z());
-            } catch (NullPointerException | ClassCastException e) {
-                System.err.println(e);
-            }
-        return retVal;
-    }
-
-    /**
-     * Returns true if the Object v is of type ReadonlyVec3DDouble and all of the data
-     * members of v are equal to the corresponding data members in this vector.
-     *
-     * @param v
-     *            the vector with which the comparison is made
-     * @return true or false
-     */
-    public boolean equals(ReadonlyVec3DDouble v) {
-        try {
-            return (x == v.x() && y == v.y() && z == v.z());
-        } catch (NullPointerException e) {
-            return false;
-        }
-    }
-
-    @Override
-    public boolean equalsWithTolerance(ReadonlyVec3DDouble v, double tolerance) {
-        try {
-            double diff = x - v.x();
-            if (Double.isNaN(diff)) {
-                return false;
-            }
-            if ((diff < 0 ? -diff : diff) > tolerance) {
-                return false;
-            }
-            diff = y - v.y();
-            if (Double.isNaN(diff)) {
-                return false;
-            }
-            if ((diff < 0 ? -diff : diff) > tolerance) {
-                return false;
-            }
-            diff = z - v.z();
-            if (Double.isNaN(diff)) {
-                return false;
-            }
-            return (diff < 0 ? -diff : diff) <= tolerance;
-        } catch (NullPointerException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Replaces the vector components with integer values of their current
-     * values.
-     *
-     * @return itself
-     */
-    public final Vec3DDouble floor() {
-        x = MathUtils.floor(x);
-        y = MathUtils.floor(y);
-        z = MathUtils.floor(z);
-        return this;
-    }
-
-    /**
-     * Replaces the vector components with the fractional part of their current
-     * values.
-     *
-     * @return itself
-     */
-    public final Vec3DDouble frac() {
-        x -= MathUtils.floor(x);
-        y -= MathUtils.floor(y);
-        z -= MathUtils.floor(z);
-        return this;
-    }
-
-    @Override
-    public final Vec3DDouble getAbs() {
-        return new Vec3DDouble(this).abs();
-    }
-
-    @Override
-    public Vec3DDouble getCartesian() {
-        return copy().toCartesian();
-    }
-
-    @Override
-    public final double getComponent(Axis id) {
-        switch (id) {
-            case X:
-                return x;
-            case Y:
-                return y;
-            case Z:
-                return z;
-        }
-        throw new IllegalArgumentException();
-    }
-
-    @Override
-    public final double getComponent(int id) {
-        switch (id) {
-            case 0:
-                return x;
-            case 1:
-                return y;
-            case 2:
-                return z;
-        }
-        throw new IllegalArgumentException("index must be 0, 1 or 2");
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see toxi.geom.ReadonlyVec3DDouble#getConstrained(toxi.geom.AABB)
-     */
-    @Override
-    public final Vec3DDouble getConstrained(AABB box) {
-        return new Vec3DDouble(this).constrain(box);
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see toxi.geom.ReadonlyVec3DDouble#getFloored()
-     */
-    @Override
-    public final Vec3DDouble getFloored() {
-        return new Vec3DDouble(this).floor();
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see toxi.geom.ReadonlyVec3DDouble#getFrac()
-     */
-    @Override
-    public final Vec3DDouble getFrac() {
-        return new Vec3DDouble(this).frac();
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see toxi.geom.ReadonlyVec3DDouble#getInverted()
-     */
-    @Override
-    public final Vec3DDouble getInverted() {
-        return new Vec3DDouble(-x, -y, -z);
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see toxi.geom.ReadonlyVec3DDouble#getLimited(double)
-     */
-    @Override
-    public final Vec3DDouble getLimited(double lim) {
-        if (magSquared() > lim * lim) {
-            return getNormalizedTo(lim);
-        }
-        return new Vec3DDouble(this);
-    }
-
-    @Override
-    public Vec3DDouble getMapped(ScaleMap map) {
-        return new Vec3DDouble(map.getClippedValueFor(x),
-                map.getClippedValueFor(y),
-                map.getClippedValueFor(z));
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see toxi.geom.ReadonlyVec3DDouble#getNormalized()
-     */
-    @Override
-    public final Vec3DDouble getNormalized() {
-        return new Vec3DDouble(this).normalize();
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see toxi.geom.ReadonlyVec3DDouble#getNormalizedTo(double)
-     */
-    @Override
-    public final Vec3DDouble getNormalizedTo(double len) {
-        return new Vec3DDouble(this).normalizeTo(len);
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see toxi.geom.ReadonlyVec3DDouble#getReciprocal()
-     */
-    @Override
-    public final Vec3DDouble getReciprocal() {
-        return copy().reciprocal();
-    }
-
-    @Override
-    public final Vec3DDouble getReflected(ReadonlyVec3DDouble normal) {
-        return copy().reflect(normal);
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see toxi.geom.ReadonlyVec3DDouble#getRotatedAroundAxis(toxi.geom.Vec3DDouble, double)
-     */
-    @Override
-    public final Vec3DDouble getRotatedAroundAxis(ReadonlyVec3DDouble axis, double theta) {
-        return new Vec3DDouble(this).rotateAroundAxis(axis, theta);
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see toxi.geom.ReadonlyVec3DDouble#getRotatedX(double)
-     */
-    @Override
-    public final Vec3DDouble getRotatedX(double theta) {
-        return new Vec3DDouble(this).rotateX(theta);
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see toxi.geom.ReadonlyVec3DDouble#getRotatedY(double)
-     */
-    @Override
-    public final Vec3DDouble getRotatedY(double theta) {
-        return new Vec3DDouble(this).rotateY(theta);
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see toxi.geom.ReadonlyVec3DDouble#getRotatedZ(double)
-     */
-    @Override
-    public final Vec3DDouble getRotatedZ(double theta) {
-        return new Vec3DDouble(this).rotateZ(theta);
-    }
-
-/*
-    public Vec3DDouble getRoundedTo(double prec) {
-        return copy().roundTo(prec);
-    }
-*/
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see toxi.geom.ReadonlyVec3DDouble#getSignum()
-     */
-    @Override
-    public final Vec3DDouble getSignum() {
-        return new Vec3DDouble(this).signum();
-    }
-
-    @Override
-    public Vec3DDouble getSpherical() {
-        return copy().toSpherical();
-    }
-
-    /**
-     * Returns a hash code value based on the data values in this object. Two
-     * different Vec3DDouble objects with identical data values (i.e., Vec3DDouble.equals
-     * returns true) will return the same hash code value. Two objects with
-     * different data members may return the same hash value, although this is
-     * not likely.
-     *
-     * @return the integer hash code value
-     */
-    @Override
-    public int hashCode() {
-        long bits = 1L;
-        bits = 31L * bits + Double.doubleToLongBits(x);
-        bits = 31L * bits + Double.doubleToLongBits(y);
-        bits = 31L * bits + Double.doubleToLongBits(z);
-        return (int) (bits ^ (bits >> 32));
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see toxi.geom.ReadonlyVec3DDouble#headingXY()
-     */
-    @Override
-    public final double headingXY() {
-        return Math.atan2(y, x);
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see toxi.geom.ReadonlyVec3DDouble#headingXZ()
-     */
-    @Override
-    public final double headingXZ() {
-        return Math.atan2(z, x);
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see toxi.geom.ReadonlyVec3DDouble#headingYZ()
-     */
-    @Override
-    public final double headingYZ() {
-        return Math.atan2(y, z);
-    }
-
-    public ReadonlyVec3DDouble immutable() {
-        return this;
-    }
-
-    @Override
-    public final Vec3DDouble interpolateTo(ReadonlyVec3DDouble v, double f) {
-        return new Vec3DDouble(x + (v.x() - x) * f, y + (v.y() - y) * f, z
-                + (v.z() - z) * f);
-    }
-
-    @Override
-    public final Vec3DDouble interpolateTo(ReadonlyVec3DDouble v, double f,
-            InterpolateStrategy s) {
-        return new Vec3DDouble(s.interpolate((float)x, (float)v.x(), (float)f), s.interpolate((float)y, (float)v.y(), (float)f), s.interpolate((float)z, (float)v.z(), (float)f));
-    }
-
-    public final Vec3DDouble interpolateTo(Vec3DDouble v, double f) {
-        return new Vec3DDouble(x + (v.x - x) * f, y + (v.y - y) * f, z + (v.z - z)
-                * f);
-    }
-
-    public final Vec3DDouble interpolateTo(Vec3DDouble v, double f, InterpolateStrategy s) {
-        return new Vec3DDouble(s.interpolate((float)x, (float)v.x, (float)f), s.interpolate((float)y, (float)v.y, (float)f), s.interpolate((float)z, (float)v.z, (float)f));
-    }
-
-    /**
-     * Interpolates the vector towards the given target vector, using linear
-     * interpolation.
-     *
-     * @param v
-     *            target vector
-     * @param f
-     *            interpolation factor (should be in the range 0..1)
-     *
-     * @return itself, result overrides current vector
-     */
-    public final Vec3DDouble interpolateToSelf(ReadonlyVec3DDouble v, double f) {
-        x += (v.x() - x) * f;
-        y += (v.y() - y) * f;
-        z += (v.z() - z) * f;
-        return this;
-    }
-
-    /**
-     * Interpolates the vector towards the given target vector, using the given
-     * {@link InterpolateStrategy}.
-     *
-     * @param v
-     *            target vector
-     * @param f
-     *            interpolation factor (should be in the range 0..1)
-     * @param s
-     *            InterpolateStrategy instance
-     *
-     * @return itself, result overrides current vector
-     */
-    public final Vec3DDouble interpolateToSelf(ReadonlyVec3DDouble v, double f,
-            InterpolateStrategy s) {
-        x = s.interpolate((float)x, (float)v.x(), (float)f);
-        y = s.interpolate((float)y, (float)v.y(), (float)f);
-        z = s.interpolate((float)z, (float)v.z(), (float)f);
-        return this;
-    }
-
-    /**
-     * Scales vector uniformly by factor -1 ( v = -v ), overrides coordinates
-     * with result.
-     *
-     * @return itself
-     */
-    public final Vec3DDouble invert() {
-        x *= -1;
-        y *= -1;
-        z *= -1;
-        return this;
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see toxi.geom.ReadonlyVec3DDouble#isInAABB(toxi.geom.AABB)
-     */
-    @Override
-    public boolean isInAABB(AABB box) {
-        final Vec3D min = box.getMin();
-        final Vec3D max = box.getMax();
-        if (x < min.x || x > max.x) {
-            return false;
-        }
-        if (y < min.y || y > max.y) {
-            return false;
-        }
-        return !(z < min.z || z > max.z);
-    }
-
-    @Override
-    public boolean isInAABB(Vec3DDouble boxOrigin, Vec3DDouble boxExtent) {
-        double w = boxExtent.x;
-        if (x < boxOrigin.x - w || x > boxOrigin.x + w) {
-            return false;
-        }
-        w = boxExtent.y;
-        if (y < boxOrigin.y - w || y > boxOrigin.y + w) {
-            return false;
-        }
-        w = boxExtent.z;
-        return !(z < boxOrigin.z - w || z > boxOrigin.z + w);
-    }
-
-    @Override
-    public final boolean isMajorAxis(double tol) {
-        double ax = MathUtils.abs(x);
-        double ay = MathUtils.abs(y);
-        double az = MathUtils.abs(z);
-        double itol = 1 - tol;
-        if (ax > itol) {
-            if (ay < tol) {
-                return (az < tol);
-            }
-        } else if (ay > itol) {
-            if (ax < tol) {
-                return (az < tol);
-            }
-        } else if (az > itol) {
-            if (ax < tol) {
-                return (ay < tol);
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public final boolean isZeroVector() {
-        return MathUtils.abs(x) < MathUtils.EPS
-                && MathUtils.abs(y) < MathUtils.EPS
-                && MathUtils.abs(z) < MathUtils.EPS;
-    }
-
-    /**
-     * Add random jitter to the vector in the range -j ... +j using the default
-     * {@link Random} generator of {@link MathUtils}.
-     *
-     * @param j
-     *            the j
-     *
-     * @return the vec3 d
-     */
-    public final Vec3DDouble jitter(double j) {
-        return jitter(j, j, j);
-    }
-
-    /**
-     * Adds random jitter to the vector in the range -j ... +j using the default
-     * {@link Random} generator of {@link MathUtils}.
-     *
-     * @param jx
-     *            maximum x jitter
-     * @param jy
-     *            maximum y jitter
-     * @param jz
-     *            maximum z jitter
-     *
-     * @return itself
-     */
-    public final Vec3DDouble jitter(double jx, double jy, double jz) {
-        x += MathUtils.normalizedRandom() * jx;
-        y += MathUtils.normalizedRandom() * jy;
-        z += MathUtils.normalizedRandom() * jz;
-        return this;
-    }
-
-    public final Vec3DDouble jitter(Random rnd, double j) {
-        return jitter(rnd, j, j, j);
-    }
-
-    public final Vec3DDouble jitter(Random rnd, double jx, double jy, double jz) {
-        x += MathUtils.normalizedRandom(rnd) * jx;
-        y += MathUtils.normalizedRandom(rnd) * jy;
-        z += MathUtils.normalizedRandom(rnd) * jz;
-        return this;
-    }
-
-    public final Vec3DDouble jitter(Random rnd, Vec3DDouble jitterVec) {
-        return jitter(rnd, jitterVec.x, jitterVec.y, jitterVec.z);
-    }
-
-    /**
-     * Adds random jitter to the vector in the range defined by the given vector
-     * components and using the default {@link Random} generator of
-     * {@link MathUtils}.
-     *
-     * @param jitterVec
-     *            the jitter vec
-     *
-     * @return itself
-     */
-    public final Vec3DDouble jitter(Vec3DDouble jitterVec) {
-        return jitter(jitterVec.x, jitterVec.y, jitterVec.z);
-    }
-
-    /**
-     * Limits the vector's magnitude to the length given.
-     *
-     * @param lim
-     *            new maximum magnitude
-     *
-     * @return itself
-     */
-    public final Vec3DDouble limit(double lim) {
-        if (magSquared() > lim * lim) {
-            return normalize().scaleSelf(lim);
-        }
-        return this;
-    }
-
-    @Override
-    public final double magnitude() {
-        return Math.sqrt(x * x + y * y + z * z);
-    }
-
-    @Override
-    public final double magSquared() {
-        return x * x + y * y + z * z;
-    }
-
-    /**
-     * Max self.
-     *
-     * @param b
-     *            the b
-     *
-     * @return the vec3 d
-     */
-    public final Vec3DDouble maxSelf(ReadonlyVec3DDouble b) {
-        x = MathUtils.max(x, b.x());
-        y = MathUtils.max(y, b.y());
-        z = MathUtils.max(z, b.z());
-        return this;
-    }
-
-    /**
-     * Min self.
-     *
-     * @param b
-     *            the b
-     *
-     * @return the vec3 d
-     */
-    public final Vec3DDouble minSelf(ReadonlyVec3DDouble b) {
-        x = MathUtils.min(x, b.x());
-        y = MathUtils.min(y, b.y());
-        z = MathUtils.min(z, b.z());
-        return this;
-    }
-
-    /**
-     * Applies a uniform modulo operation to the vector, using the same base for
-     * all components.
-     *
-     * @param base
-     *            the base
-     *
-     * @return itself
-     */
-    public final Vec3DDouble modSelf(double base) {
-        x %= base;
-        y %= base;
-        z %= base;
-        return this;
-    }
-
-    /**
-     * Calculates modulo operation for each vector component separately.
-     *
-     * @param bx
-     *            the bx
-     * @param by
-     *            the by
-     * @param bz
-     *            the bz
-     *
-     * @return itself
-     */
-
-    public final Vec3DDouble modSelf(double bx, double by, double bz) {
-        x %= bx;
-        y %= by;
-        z %= bz;
-        return this;
-    }
-
-    /**
-     * Normalizes the vector so that its magnitude = 1.
-     *
-     * @return itself
-     */
-    public final Vec3DDouble normalize() {
-        double mag = Math.sqrt(x * x + y * y + z * z);
-        if (mag > 0) {
-            mag = 1f / mag;
-            x *= mag;
-            y *= mag;
-            z *= mag;
-        }
-        return this;
-    }
-
-    /**
-     * Normalizes the vector to the given length.
-     *
-     * @param len
-     *            desired length
-     * @return itself
-     */
-    public final Vec3DDouble normalizeTo(double len) {
-        double mag = Math.sqrt(x * x + y * y + z * z);
-        if (mag > 0) {
-            mag = len / mag;
-            x *= mag;
-            y *= mag;
-            z *= mag;
-        }
-        return this;
-    }
-
-    /**
-     * Replaces the vector components with their multiplicative inverse.
-     *
-     * @return itself
-     */
-    public final Vec3DDouble reciprocal() {
-        x = 1f / x;
-        y = 1f / y;
-        z = 1f / z;
-        return this;
-    }
-
-    public final Vec3DDouble reflect(ReadonlyVec3DDouble normal) {
-        return set(normal.scale(this.dot(normal) * 2).subSelf(this));
-    }
-
-    /**
-     * Rotates the vector around the giving axis.
-     *
-     * @param axis
-     *            rotation axis vector
-     * @param theta
-     *            rotation angle (in radians)
-     *
-     * @return itself
-     */
-    public final Vec3DDouble rotateAroundAxis(ReadonlyVec3DDouble axis, double theta) {
-        final double ax = axis.x();
-        final double ay = axis.y();
-        final double az = axis.z();
-        final double ux = ax * x;
-        final double uy = ax * y;
-        final double uz = ax * z;
-        final double vx = ay * x;
-        final double vy = ay * y;
-        final double vz = ay * z;
-        final double wx = az * x;
-        final double wy = az * y;
-        final double wz = az * z;
-        final double si = Math.sin(theta);
-        final double co = Math.cos(theta);
-        double xx = ax * (ux + vy + wz)
-                + (x * (ay * ay + az * az) - ax * (vy + wz)) * co + (-wy + vz)
-                * si;
-        double yy = ay * (ux + vy + wz)
-                + (y * (ax * ax + az * az) - ay * (ux + wz)) * co + (wx - uz)
-                * si;
-        double zz = az * (ux + vy + wz)
-                + (z * (ax * ax + ay * ay) - az * (ux + vy)) * co + (-vx + uy)
-                * si;
-        x = xx;
-        y = yy;
-        z = zz;
-        return this;
-    }
-
-    /**
-     * Rotates the vector by the given angle around the X axis.
-     *
-     * @param theta
-     *            the theta
-     *
-     * @return itself
-     */
-    public final Vec3DDouble rotateX(double theta) {
-        final double co = Math.cos(theta);
-        final double si = Math.sin(theta);
-        final double zz = co * z - si * y;
-        y = si * z + co * y;
-        z = zz;
-        return this;
-    }
-
-    /**
-     * Rotates the vector by the given angle around the Y axis.
-     *
-     * @param theta
-     *            the theta
-     *
-     * @return itself
-     */
-    public final Vec3DDouble rotateY(double theta) {
-        final double co = Math.cos(theta);
-        final double si = Math.sin(theta);
-        final double xx = co * x - si * z;
-        z = si * x + co * z;
-        x = xx;
-        return this;
-    }
-
-    /**
-     * Rotates the vector by the given angle around the Z axis.
-     *
-     * @param theta
-     *            the theta
-     *
-     * @return itself
-     */
-    public final Vec3DDouble rotateZ(double theta) {
-        final double co = Math.cos(theta);
-        final double si = Math.sin(theta);
-        final double xx = co * x - si * y;
-        y = si * x + co * y;
-        x = xx;
-        return this;
-    }
-
-/*
-    public Vec3DDouble roundTo(double prec) {
-        x = MathUtils.roundTo(x, prec);
-        y = MathUtils.roundTo(y, prec);
-        z = MathUtils.roundTo(z, prec);
-        return this;
-    }
-*/
-
-    @Override
-    public Vec3DDouble scale(double s) {
-        return new Vec3DDouble(x * s, y * s, z * s);
-    }
-
-    @Override
-    public Vec3DDouble scale(double a, double b, double c) {
-        return new Vec3DDouble(x * a, y * b, z * c);
-    }
-
-    @Override
-    public Vec3DDouble scale(ReadonlyVec3DDouble s) {
-        return new Vec3DDouble(x * s.x(), y * s.y(), z * s.z());
-    }
-
-    public Vec3DDouble scale(Vec3DDouble s) {
-        return new Vec3DDouble(x * s.x, y * s.y, z * s.z);
-    }
-
-    /**
-     * Scales vector uniformly and overrides coordinates with result.
-     *
-     * @param s
-     *            scale factor
-     *
-     * @return itself
-     */
-    public Vec3DDouble scaleSelf(double s) {
-        x *= s;
-        y *= s;
-        z *= s;
-        return this;
-    }
-
-    /**
-     * Scales vector non-uniformly by vector {a,b,c} and overrides coordinates
-     * with result.
-     *
-     * @param a
-     *            scale factor for X coordinate
-     * @param b
-     *            scale factor for Y coordinate
-     * @param c
-     *            scale factor for Z coordinate
-     *
-     * @return itself
-     */
-    public Vec3DDouble scaleSelf(double a, double b, double c) {
-        x *= a;
-        y *= b;
-        z *= c;
-        return this;
-    }
-
-    public Vec3DDouble scaleSelf(ReadonlyVec3DDouble s) {
-        x *= s.x();
-        y *= s.y();
-        z *= s.z();
-        return this;
-    }
-
-    /**
-     * Scales vector non-uniformly by vector v and overrides coordinates with
-     * result.
-     *
-     * @param s
-     *            scale vector
-     *
-     * @return itself
-     */
-
-    public Vec3DDouble scaleSelf(Vec3DDouble s) {
-        x *= s.x;
-        y *= s.y;
-        z *= s.z;
-        return this;
-    }
-
-    /**
-     * Overrides coordinates with the given values.
-     *
-     * @param x
-     *            the x
-     * @param y
-     *            the y
-     * @param z
-     *            the z
-     *
-     * @return itself
-     */
-    public Vec3DDouble set(double x, double y, double z) {
-        this.x = x;
-        this.y = y;
-        this.z = z;
-        return this;
-    }
-
-    public Vec3DDouble set(ReadonlyVec3DDouble v) {
-        x = v.x();
-        y = v.y();
-        z = v.z();
-        return this;
-    }
-
-    /**
-     * Overrides coordinates with the ones of the given vector.
-     *
-     * @param v
-     *            vector to be copied
-     *
-     * @return itself
-     */
-    public Vec3DDouble set(Vec3DDouble v) {
-        x = v.x;
-        y = v.y;
-        z = v.z;
-        return this;
-    }
-
-    public final Vec3DDouble setComponent(Axis id, double val) {
-        switch (id) {
-            case X:
-                x = val;
-                break;
-            case Y:
-                y = val;
-                break;
-            case Z:
-                z = val;
-                break;
-        }
-        return this;
-    }
-
-    public final Vec3DDouble setComponent(int id, double val) {
-        switch (id) {
-            case 0:
-                x = val;
-                break;
-            case 1:
-                y = val;
-                break;
-            case 2:
-                z = val;
-                break;
-        }
-        return this;
-    }
-
-    public Vec3DDouble setX(double x) {
-        this.x = x;
-        return this;
-    }
-
-    /**
-     * Overrides XY coordinates with the ones of the given 2D vector.
-     *
-     * @param v
-     *            2D vector
-     *
-     * @return itself
-     */
-    public Vec3DDouble setXY(Vec2D v) {
-        x = v.x;
-        y = v.y;
-        return this;
-    }
-
-    public Vec3DDouble setY(double y) {
-        this.y = y;
-        return this;
-    }
-
-    public Vec3DDouble setZ(double z) {
-        this.z = z;
-        return this;
-    }
-
-    public Vec3DDouble shuffle(int iterations) {
-        double t;
-        for (int i = 0; i < iterations; i++) {
-            switch (MathUtils.random(3)) {
-                case 0:
-                    t = x;
-                    x = y;
-                    y = t;
-                    break;
-                case 1:
-                    t = x;
-                    x = z;
-                    z = t;
-                    break;
-                case 2:
-                    t = y;
-                    y = z;
-                    z = t;
-                    break;
-            }
-        }
-        return this;
-    }
-
-    /**
-     * Replaces all vector components with the signum of their original values.
-     * In other words if a components value was negative its new value will be
-     * -1, if zero =&gt; 0, if positive =&gt; +1
-     *
-     * @return itself
-     */
-    public Vec3DDouble signum() {
-        x = (x < 0 ? -1 : x == 0 ? 0 : 1);
-        y = (y < 0 ? -1 : y == 0 ? 0 : 1);
-        z = (z < 0 ? -1 : z == 0 ? 0 : 1);
-        return this;
-    }
-
-    /**
-     * Rounds the vector to the closest major axis. Assumes the vector is
-     * normalized.
-     *
-     * @return itself
-     */
-    public final Vec3DDouble snapToAxis() {
-        if (MathUtils.abs(x) < 0.5f) {
-            x = 0;
-        } else {
-            x = x < 0 ? -1 : 1;
-            y = z = 0;
-        }
-        if (MathUtils.abs(y) < 0.5f) {
-            y = 0;
-        } else {
-            y = y < 0 ? -1 : 1;
-            x = z = 0;
-        }
-        if (MathUtils.abs(z) < 0.5f) {
-            z = 0;
-        } else {
-            z = z < 0 ? -1 : 1;
-            x = y = 0;
-        }
-        return this;
-    }
-
-    @Override
-    public final Vec3DDouble sub(double a, double b, double c) {
-        return new Vec3DDouble(x - a, y - b, z - c);
-    }
-
-    @Override
-    public final Vec3DDouble sub(ReadonlyVec3DDouble v) {
-        return new Vec3DDouble(x - v.x(), y - v.y(), z - v.z());
-    }
-
-    public final Vec3DDouble sub(Vec3DDouble v) {
-        return new Vec3DDouble(x - v.x, y - v.y, z - v.z);
-    }
-
-    /**
-     * Subtracts vector {a,b,c} and overrides coordinates with result.
-     *
-     * @param a
-     *            X coordinate
-     * @param b
-     *            Y coordinate
-     * @param c
-     *            Z coordinate
-     *
-     * @return itself
-     */
-    public final Vec3DDouble subSelf(double a, double b, double c) {
-        x -= a;
-        y -= b;
-        z -= c;
-        return this;
-    }
-
-    public final Vec3DDouble subSelf(ReadonlyVec3DDouble v) {
-        x -= v.x();
-        y -= v.y();
-        z -= v.z();
-        return this;
-    }
-
-    /**
-     * Subtracts vector v and overrides coordinates with result.
-     *
-     * @param v
-     *            vector to be subtracted
-     *
-     * @return itself
-     */
-    public final Vec3DDouble subSelf(Vec3DDouble v) {
-        x -= v.x;
-        y -= v.y;
-        z -= v.z;
-        return this;
-    }
-
-    @Override
-    public final Vec2D to2DXY() {
-        return new Vec2D((float)x, (float)y);
-    }
-
-    @Override
-    public final Vec2D to2DXZ() {
-        return new Vec2D((float)x, (float)z);
-    }
-
-    @Override
-    public final Vec2D to2DYZ() {
-        return new Vec2D((float)y, (float)z);
-    }
-
-    @Override
-    public double[] toArray() {
-        return new double[] { x, y, z };
-    }
-
-    @Override
-    public double[] toArray4(double w) {
-        return new double[] { x, y, z, w };
-    }
-
-    public final Vec3DDouble toCartesian() {
-        final double a = x * Math.cos(z);
-        final double xx = a * Math.cos(y);
-        final double yy = x * Math.sin(z);
-        final double zz = a * Math.sin(y);
-        x = xx;
-        y = yy;
-        z = zz;
-        return this;
-    }
-
-    public final Vec3DDouble toSpherical() {
-        final double xx = Math.abs(x) <= MathUtils.EPS ? MathUtils.EPS : x;
-        final double zz = z;
-
-        final double radius = Math.sqrt((xx * xx) + (y * y) + (zz * zz));
-        z = Math.asin(y / radius);
-        y = Math.atan(zz / xx) + (xx < 0.0 ? MathUtils.PI : 0);
-        x = radius;
-        return this;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuffer sb = new StringBuffer(48);
-        sb.append("{x:").append(x).append(", y:").append(y).append(", z:")
-                .append(z).append("}");
-        return sb.toString();
-    }
-
-    @Override
-    public final double x() {
-        return x;
-    }
-
-    @Override
-    public final double y() {
-        return y;
-    }
-
-    @Override
-    public final double z() {
-        return z;
-    }
-}
+/*
+ *   __               .__       .__  ._____.
+ * _/  |_  _______  __|__| ____ |  | |__\_ |__   ______
+ * \   __\/  _ \  \/  /  |/ ___\|  | |  || __ \ /  ___/
+ *  |  | (  <_> >    <|  \  \___|  |_|  || \_\ \\___ \
+ *  |__|  \____/__/\_ \__|\___  >____/__||___  /____  >
+ *                   \/       \/             \/     \/
+ *
+ * Copyright (c) 2006-2011 Karsten Schmidt
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * http://creativecommons.org/licenses/LGPL/2.1/
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+package org.web3d.util.spatial;
+
+import toxi.geom.*;
+
+import java.util.Random;
+
+import javax.xml.bind.annotation.XmlAttribute;
+
+import toxi.math.InterpolateStrategy;
+import toxi.math.MathUtils;
+import toxi.math.ScaleMap;
+
+/**
+ * Comprehensive 3D vector class with additional basic intersection and
+ * collision detection features.
+ */
+public class Vec3DDouble implements Comparable<ReadonlyVec3DDouble>, ReadonlyVec3DDouble {
+
+    public static enum Axis {
+
+        X(Vec3DDouble.X_AXIS), Y(Vec3DDouble.Y_AXIS), Z(Vec3DDouble.Z_AXIS);
+
+        private final ReadonlyVec3DDouble vector;
+
+        private Axis(ReadonlyVec3DDouble v) {
+            this.vector = v;
+        }
+
+        public ReadonlyVec3DDouble getVector() {
+            return vector;
+        }
+    }
+
+    /** Defines positive X axis. */
+    public static final ReadonlyVec3DDouble X_AXIS = new Vec3DDouble(1, 0, 0);
+
+    /** Defines positive Y axis. */
+    public static final ReadonlyVec3DDouble Y_AXIS = new Vec3DDouble(0, 1, 0);
+
+    /** Defines positive Z axis. */
+    public static final ReadonlyVec3DDouble Z_AXIS = new Vec3DDouble(0, 0, 1);
+
+    /** Defines the zero vector. */
+    public static final ReadonlyVec3DDouble ZERO = new Vec3DDouble();
+
+    /**
+     * Defines vector with all coords set to Double.MIN_VALUE. Useful for
+     * bounding box operations.
+     */
+    public static final ReadonlyVec3DDouble MIN_VALUE = new Vec3DDouble(Double.MIN_VALUE,
+            Double.MIN_VALUE, Double.MIN_VALUE);
+
+    /**
+     * Defines vector with all coords set to Double.MAX_VALUE. Useful for
+     * bounding box operations.
+     */
+    public static final ReadonlyVec3DDouble MAX_VALUE = new Vec3DDouble(Double.MAX_VALUE,
+            Double.MAX_VALUE, Double.MAX_VALUE);
+
+    /**
+     * Creates a new vector from the given angle in the XY plane. The Z
+     * component of the vector will be zero.
+     *
+     * The resulting vector for theta=0 is equal to the positive X axis.
+     *
+     * @param theta
+     *            the theta
+     *
+     * @return new vector in the XY plane
+     */
+    public static Vec3DDouble fromXYTheta(double theta) {
+        return new Vec3DDouble(Math.cos(theta), Math.sin(theta), 0);
+    }
+
+    /**
+     * Creates a new vector from the given angle in the XZ plane. The Y
+     * component of the vector will be zero.
+     *
+     * The resulting vector for theta=0 is equal to the positive X axis.
+     *
+     * @param theta
+     *            the theta
+     *
+     * @return new vector in the XZ plane
+     */
+    public static Vec3DDouble fromXZTheta(double theta) {
+        return new Vec3DDouble(Math.cos(theta), 0, Math.sin(theta));
+    }
+
+    /**
+     * Creates a new vector from the given angle in the YZ plane. The X
+     * component of the vector will be zero.
+     *
+     * The resulting vector for theta=0 is equal to the positive Y axis.
+     *
+     * @param theta
+     *            the theta
+     *
+     * @return new vector in the YZ plane
+     */
+    public static Vec3DDouble fromYZTheta(double theta) {
+        return new Vec3DDouble(0, Math.cos(theta), Math.sin(theta));
+    }
+
+    /**
+     * Constructs a new vector consisting of the largest components of both
+     * vectors.
+     *
+     * @param b
+     *            the b
+     * @param a
+     *            the a
+     *
+     * @return result as new vector
+     */
+    public static Vec3DDouble max(ReadonlyVec3DDouble a, ReadonlyVec3DDouble b) {
+        return new Vec3DDouble(MathUtils.max(a.x(), b.x()), MathUtils.max(a.y(),
+                b.y()), MathUtils.max(a.z(), b.z()));
+    }
+
+    /**
+     * Constructs a new vector consisting of the smallest components of both
+     * vectors.
+     *
+     * @param b
+     *            comparing vector
+     * @param a
+     *            the a
+     *
+     * @return result as new vector
+     */
+    public static Vec3DDouble min(ReadonlyVec3DDouble a, ReadonlyVec3DDouble b) {
+        return new Vec3DDouble(MathUtils.min(a.x(), b.x()), MathUtils.min(a.y(),
+                b.y()), MathUtils.min(a.z(), b.z()));
+    }
+
+    /**
+     * Static factory method. Creates a new random unit vector using the Random
+     * implementation set as default for the {@link MathUtils} class.
+     *
+     * @return a new random normalized unit vector.
+     */
+    public static Vec3DDouble randomVector() {
+        return randomVector(MathUtils.RND);
+    }
+
+    /**
+     * Static factory method. Creates a new random unit vector using the given
+     * Random generator instance. I recommend to have a look at the
+     * https://uncommons-maths.dev.java.net library for a good choice of
+     * reliable and high quality random number generators.
+     *
+     * @param rnd
+     *            the rnd
+     *
+     * @return a new random normalized unit vector.
+     */
+    public static Vec3DDouble randomVector(Random rnd) {
+        Vec3DDouble v = new Vec3DDouble(rnd.nextDouble() * 2 - 1, rnd.nextDouble() * 2 - 1,
+                rnd.nextDouble() * 2 - 1);
+        return v.normalize();
+    }
+
+    /** X coordinate. */
+    @XmlAttribute(required = true)
+    public double x;
+
+    /** Y coordinate. */
+    @XmlAttribute(required = true)
+    public double y;
+
+    /** Z coordinate. */
+    @XmlAttribute(required = true)
+    public double z;
+
+    /**
+     * Creates a new zero vector.
+     */
+    public Vec3DDouble() {
+    }
+
+    /**
+     * Creates a new vector with the given coordinates.
+     *
+     * @param x
+     *            the x
+     * @param y
+     *            the y
+     * @param z
+     *            the z
+     */
+    public Vec3DDouble(double x, double y, double z) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    }
+
+    public Vec3DDouble(double[] v) {
+        this.x = v[0];
+        this.y = v[1];
+        this.z = v[2];
+    }
+
+    /**
+     * Creates a new vector with the coordinates of the given vector.
+     *
+     * @param v
+     *            vector to be copied
+     */
+    public Vec3DDouble(ReadonlyVec3DDouble v) {
+        this.x = v.x();
+        this.y = v.y();
+        this.z = v.z();
+    }
+
+    /**
+     * Abs.
+     *
+     * @return the vec3 d
+     */
+    public final Vec3DDouble abs() {
+        x = MathUtils.abs(x);
+        y = MathUtils.abs(y);
+        z = MathUtils.abs(z);
+        return this;
+    }
+
+    @Override
+    public final Vec3DDouble add(double a, double b, double c) {
+        return new Vec3DDouble(x + a, y + b, z + c);
+    }
+
+    @Override
+    public Vec3DDouble add(ReadonlyVec3DDouble v) {
+        return new Vec3DDouble(x + v.x(), y + v.y(), z + v.z());
+    }
+
+    @Override
+    public final Vec3DDouble add(Vec3DDouble v) {
+        return new Vec3DDouble(x + v.x, y + v.y, z + v.z);
+    }
+
+    /**
+     * Adds vector {a,b,c} and overrides coordinates with result.
+     *
+     * @param a
+     *            X coordinate
+     * @param b
+     *            Y coordinate
+     * @param c
+     *            Z coordinate
+     *
+     * @return itself
+     */
+    public final Vec3DDouble addSelf(double a, double b, double c) {
+        x += a;
+        y += b;
+        z += c;
+        return this;
+    }
+
+    public final Vec3DDouble addSelf(ReadonlyVec3DDouble v) {
+        x += v.x();
+        y += v.y();
+        z += v.z();
+        return this;
+    }
+
+    /**
+     * Adds vector v and overrides coordinates with result.
+     *
+     * @param v
+     *            vector to add
+     *
+     * @return itself
+     */
+    public final Vec3DDouble addSelf(Vec3DDouble v) {
+        x += v.x;
+        y += v.y;
+        z += v.z;
+        return this;
+    }
+
+    @Override
+    public final double angleBetween(ReadonlyVec3DDouble v) {
+        return Math.acos(dot(v));
+    }
+
+    @Override
+    public final double angleBetween(ReadonlyVec3DDouble v, boolean forceNormalize) {
+        double theta;
+        if (forceNormalize) {
+            theta = getNormalized().dot(v.getNormalized());
+        } else {
+            theta = dot(v);
+        }
+        return Math.acos(theta);
+    }
+
+    /**
+     * Sets all vector components to 0.
+     *
+     * @return itself
+     */
+    public final ReadonlyVec3DDouble clear() {
+        x = y = z = 0;
+        return this;
+    }
+
+    @Override
+    public int compareTo(ReadonlyVec3DDouble v) {
+        if (x == v.x() && y == v.y() && z == v.z()) {
+            return 0;
+        }
+        double a = magSquared();
+        double b = v.magSquared();
+        if (a < b) {
+            return -1;
+        }
+        return +1;
+    }
+
+    /**
+     * Forcefully fits the vector in the given AABB.
+     *
+     * @param box
+     *            the box
+     *
+     * @return itself
+     */
+    public final Vec3DDouble constrain(AABB box) {
+        return constrain(box.getMin(), box.getMax());
+    }
+
+    /**
+     * Forcefully fits the vector in the given AABB specified by the 2 given
+     * points.
+     *
+     * @param min
+     * @param max
+     * @return itself
+     */
+    public final Vec3DDouble constrain(Vec3D min, Vec3D max) {
+        x = MathUtils.clip(x, min.x, max.x);
+        y = MathUtils.clip(y, min.y, max.y);
+        z = MathUtils.clip(z, min.z, max.z);
+        return this;
+    }
+
+    @Override
+    public Vec3DDouble copy() {
+        return new Vec3DDouble(this);
+    }
+
+    @Override
+    public final Vec3DDouble cross(ReadonlyVec3DDouble v) {
+        return new Vec3DDouble(y * v.z() - v.y() * z, z * v.x() - v.z() * x, x
+                * v.y() - v.x() * y);
+    }
+
+    public final Vec3DDouble cross(Vec3DDouble v) {
+        return new Vec3DDouble(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x
+                * y);
+    }
+
+    @Override
+    public final Vec3DDouble crossInto(ReadonlyVec3DDouble v, Vec3DDouble result) {
+        final double vx = v.x();
+        final double vy = v.y();
+        final double vz = v.z();
+        result.x = y * vz - vy * z;
+        result.y = z * vx - vz * x;
+        result.z = x * vy - vx * y;
+        return result;
+    }
+
+    /**
+     * Calculates cross-product with vector v. The resulting vector is
+     * perpendicular to both the current and supplied vector and overrides the
+     * current.
+     *
+     * @param v
+     *            the v
+     *
+     * @return itself
+     */
+    public final Vec3DDouble crossSelf(Vec3DDouble v) {
+        final double cx = y * v.z - v.y * z;
+        final double cy = z * v.x - v.z * x;
+        z = x * v.y - v.x * y;
+        y = cy;
+        x = cx;
+        return this;
+    }
+
+    @Override
+    public final double distanceTo(ReadonlyVec3DDouble v) {
+        if (v != null) {
+            final double dx = x - v.x();
+            final double dy = y - v.y();
+            final double dz = z - v.z();
+            return Math.sqrt(dx * dx + dy * dy + dz * dz);
+        } else {
+            return Double.NaN;
+        }
+    }
+
+    @Override
+    public final double distanceToSquared(ReadonlyVec3DDouble v) {
+        if (v != null) {
+            final double dx = x - v.x();
+            final double dy = y - v.y();
+            final double dz = z - v.z();
+            return dx * dx + dy * dy + dz * dz;
+        } else {
+            return Double.NaN;
+        }
+    }
+
+    @Override
+    public final double dot(ReadonlyVec3DDouble v) {
+        return x * v.x() + y * v.y() + z * v.z();
+    }
+
+    public final double dot(Vec3DDouble v) {
+        return x * v.x + y * v.y + z * v.z;
+    }
+
+    /**
+     * Returns true if the Object v is of type ReadonlyVec3DDouble and all of the data
+     * members of v are equal to the corresponding data members in this vector.
+     *
+     * @param v
+     *            the Object with which the comparison is made
+     * @return true or false
+     */
+    @Override
+    public boolean equals(Object v) {
+        boolean retVal = false;
+        if (v instanceof ReadonlyVec3DDouble)
+            try {
+                ReadonlyVec3DDouble vv = (ReadonlyVec3DDouble) v;
+                retVal = (x == vv.x() && y == vv.y() && z == vv.z());
+            } catch (NullPointerException | ClassCastException e) {
+                System.err.println(e);
+            }
+        return retVal;
+    }
+
+    /**
+     * Returns true if the Object v is of type ReadonlyVec3DDouble and all of the data
+     * members of v are equal to the corresponding data members in this vector.
+     *
+     * @param v
+     *            the vector with which the comparison is made
+     * @return true or false
+     */
+    public boolean equals(ReadonlyVec3DDouble v) {
+        try {
+            return (x == v.x() && y == v.y() && z == v.z());
+        } catch (NullPointerException e) {
+            return false;
+        }
+    }
+
+    @Override
+    public boolean equalsWithTolerance(ReadonlyVec3DDouble v, double tolerance) {
+        try {
+            double diff = x - v.x();
+            if (Double.isNaN(diff)) {
+                return false;
+            }
+            if ((diff < 0 ? -diff : diff) > tolerance) {
+                return false;
+            }
+            diff = y - v.y();
+            if (Double.isNaN(diff)) {
+                return false;
+            }
+            if ((diff < 0 ? -diff : diff) > tolerance) {
+                return false;
+            }
+            diff = z - v.z();
+            if (Double.isNaN(diff)) {
+                return false;
+            }
+            return (diff < 0 ? -diff : diff) <= tolerance;
+        } catch (NullPointerException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Replaces the vector components with integer values of their current
+     * values.
+     *
+     * @return itself
+     */
+    public final Vec3DDouble floor() {
+        x = MathUtils.floor(x);
+        y = MathUtils.floor(y);
+        z = MathUtils.floor(z);
+        return this;
+    }
+
+    /**
+     * Replaces the vector components with the fractional part of their current
+     * values.
+     *
+     * @return itself
+     */
+    public final Vec3DDouble frac() {
+        x -= MathUtils.floor(x);
+        y -= MathUtils.floor(y);
+        z -= MathUtils.floor(z);
+        return this;
+    }
+
+    @Override
+    public final Vec3DDouble getAbs() {
+        return new Vec3DDouble(this).abs();
+    }
+
+    @Override
+    public Vec3DDouble getCartesian() {
+        return copy().toCartesian();
+    }
+
+    @Override
+    public final double getComponent(Axis id) {
+        switch (id) {
+            case X:
+                return x;
+            case Y:
+                return y;
+            case Z:
+                return z;
+        }
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public final double getComponent(int id) {
+        switch (id) {
+            case 0:
+                return x;
+            case 1:
+                return y;
+            case 2:
+                return z;
+        }
+        throw new IllegalArgumentException("index must be 0, 1 or 2");
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see toxi.geom.ReadonlyVec3DDouble#getConstrained(toxi.geom.AABB)
+     */
+    @Override
+    public final Vec3DDouble getConstrained(AABB box) {
+        return new Vec3DDouble(this).constrain(box);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see toxi.geom.ReadonlyVec3DDouble#getFloored()
+     */
+    @Override
+    public final Vec3DDouble getFloored() {
+        return new Vec3DDouble(this).floor();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see toxi.geom.ReadonlyVec3DDouble#getFrac()
+     */
+    @Override
+    public final Vec3DDouble getFrac() {
+        return new Vec3DDouble(this).frac();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see toxi.geom.ReadonlyVec3DDouble#getInverted()
+     */
+    @Override
+    public final Vec3DDouble getInverted() {
+        return new Vec3DDouble(-x, -y, -z);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see toxi.geom.ReadonlyVec3DDouble#getLimited(double)
+     */
+    @Override
+    public final Vec3DDouble getLimited(double lim) {
+        if (magSquared() > lim * lim) {
+            return getNormalizedTo(lim);
+        }
+        return new Vec3DDouble(this);
+    }
+
+    @Override
+    public Vec3DDouble getMapped(ScaleMap map) {
+        return new Vec3DDouble(map.getClippedValueFor(x),
+                map.getClippedValueFor(y),
+                map.getClippedValueFor(z));
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see toxi.geom.ReadonlyVec3DDouble#getNormalized()
+     */
+    @Override
+    public final Vec3DDouble getNormalized() {
+        return new Vec3DDouble(this).normalize();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see toxi.geom.ReadonlyVec3DDouble#getNormalizedTo(double)
+     */
+    @Override
+    public final Vec3DDouble getNormalizedTo(double len) {
+        return new Vec3DDouble(this).normalizeTo(len);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see toxi.geom.ReadonlyVec3DDouble#getReciprocal()
+     */
+    @Override
+    public final Vec3DDouble getReciprocal() {
+        return copy().reciprocal();
+    }
+
+    @Override
+    public final Vec3DDouble getReflected(ReadonlyVec3DDouble normal) {
+        return copy().reflect(normal);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see toxi.geom.ReadonlyVec3DDouble#getRotatedAroundAxis(toxi.geom.Vec3DDouble, double)
+     */
+    @Override
+    public final Vec3DDouble getRotatedAroundAxis(ReadonlyVec3DDouble axis, double theta) {
+        return new Vec3DDouble(this).rotateAroundAxis(axis, theta);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see toxi.geom.ReadonlyVec3DDouble#getRotatedX(double)
+     */
+    @Override
+    public final Vec3DDouble getRotatedX(double theta) {
+        return new Vec3DDouble(this).rotateX(theta);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see toxi.geom.ReadonlyVec3DDouble#getRotatedY(double)
+     */
+    @Override
+    public final Vec3DDouble getRotatedY(double theta) {
+        return new Vec3DDouble(this).rotateY(theta);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see toxi.geom.ReadonlyVec3DDouble#getRotatedZ(double)
+     */
+    @Override
+    public final Vec3DDouble getRotatedZ(double theta) {
+        return new Vec3DDouble(this).rotateZ(theta);
+    }
+
+/*
+    public Vec3DDouble getRoundedTo(double prec) {
+        return copy().roundTo(prec);
+    }
+*/
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see toxi.geom.ReadonlyVec3DDouble#getSignum()
+     */
+    @Override
+    public final Vec3DDouble getSignum() {
+        return new Vec3DDouble(this).signum();
+    }
+
+    @Override
+    public Vec3DDouble getSpherical() {
+        return copy().toSpherical();
+    }
+
+    /**
+     * Returns a hash code value based on the data values in this object. Two
+     * different Vec3DDouble objects with identical data values (i.e., Vec3DDouble.equals
+     * returns true) will return the same hash code value. Two objects with
+     * different data members may return the same hash value, although this is
+     * not likely.
+     *
+     * @return the integer hash code value
+     */
+    @Override
+    public int hashCode() {
+        long bits = 1L;
+        bits = 31L * bits + Double.doubleToLongBits(x);
+        bits = 31L * bits + Double.doubleToLongBits(y);
+        bits = 31L * bits + Double.doubleToLongBits(z);
+        return (int) (bits ^ (bits >> 32));
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see toxi.geom.ReadonlyVec3DDouble#headingXY()
+     */
+    @Override
+    public final double headingXY() {
+        return Math.atan2(y, x);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see toxi.geom.ReadonlyVec3DDouble#headingXZ()
+     */
+    @Override
+    public final double headingXZ() {
+        return Math.atan2(z, x);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see toxi.geom.ReadonlyVec3DDouble#headingYZ()
+     */
+    @Override
+    public final double headingYZ() {
+        return Math.atan2(y, z);
+    }
+
+    public ReadonlyVec3DDouble immutable() {
+        return this;
+    }
+
+    @Override
+    public final Vec3DDouble interpolateTo(ReadonlyVec3DDouble v, double f) {
+        return new Vec3DDouble(x + (v.x() - x) * f, y + (v.y() - y) * f, z
+                + (v.z() - z) * f);
+    }
+
+    @Override
+    public final Vec3DDouble interpolateTo(ReadonlyVec3DDouble v, double f,
+            InterpolateStrategy s) {
+        return new Vec3DDouble(s.interpolate((float)x, (float)v.x(), (float)f), s.interpolate((float)y, (float)v.y(), (float)f), s.interpolate((float)z, (float)v.z(), (float)f));
+    }
+
+    public final Vec3DDouble interpolateTo(Vec3DDouble v, double f) {
+        return new Vec3DDouble(x + (v.x - x) * f, y + (v.y - y) * f, z + (v.z - z)
+                * f);
+    }
+
+    public final Vec3DDouble interpolateTo(Vec3DDouble v, double f, InterpolateStrategy s) {
+        return new Vec3DDouble(s.interpolate((float)x, (float)v.x, (float)f), s.interpolate((float)y, (float)v.y, (float)f), s.interpolate((float)z, (float)v.z, (float)f));
+    }
+
+    /**
+     * Interpolates the vector towards the given target vector, using linear
+     * interpolation.
+     *
+     * @param v
+     *            target vector
+     * @param f
+     *            interpolation factor (should be in the range 0..1)
+     *
+     * @return itself, result overrides current vector
+     */
+    public final Vec3DDouble interpolateToSelf(ReadonlyVec3DDouble v, double f) {
+        x += (v.x() - x) * f;
+        y += (v.y() - y) * f;
+        z += (v.z() - z) * f;
+        return this;
+    }
+
+    /**
+     * Interpolates the vector towards the given target vector, using the given
+     * {@link InterpolateStrategy}.
+     *
+     * @param v
+     *            target vector
+     * @param f
+     *            interpolation factor (should be in the range 0..1)
+     * @param s
+     *            InterpolateStrategy instance
+     *
+     * @return itself, result overrides current vector
+     */
+    public final Vec3DDouble interpolateToSelf(ReadonlyVec3DDouble v, double f,
+            InterpolateStrategy s) {
+        x = s.interpolate((float)x, (float)v.x(), (float)f);
+        y = s.interpolate((float)y, (float)v.y(), (float)f);
+        z = s.interpolate((float)z, (float)v.z(), (float)f);
+        return this;
+    }
+
+    /**
+     * Scales vector uniformly by factor -1 ( v = -v ), overrides coordinates
+     * with result.
+     *
+     * @return itself
+     */
+    public final Vec3DDouble invert() {
+        x *= -1;
+        y *= -1;
+        z *= -1;
+        return this;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see toxi.geom.ReadonlyVec3DDouble#isInAABB(toxi.geom.AABB)
+     */
+    @Override
+    public boolean isInAABB(AABB box) {
+        final Vec3D min = box.getMin();
+        final Vec3D max = box.getMax();
+        if (x < min.x || x > max.x) {
+            return false;
+        }
+        if (y < min.y || y > max.y) {
+            return false;
+        }
+        return !(z < min.z || z > max.z);
+    }
+
+    @Override
+    public boolean isInAABB(Vec3DDouble boxOrigin, Vec3DDouble boxExtent) {
+        double w = boxExtent.x;
+        if (x < boxOrigin.x - w || x > boxOrigin.x + w) {
+            return false;
+        }
+        w = boxExtent.y;
+        if (y < boxOrigin.y - w || y > boxOrigin.y + w) {
+            return false;
+        }
+        w = boxExtent.z;
+        return !(z < boxOrigin.z - w || z > boxOrigin.z + w);
+    }
+
+    @Override
+    public final boolean isMajorAxis(double tol) {
+        double ax = MathUtils.abs(x);
+        double ay = MathUtils.abs(y);
+        double az = MathUtils.abs(z);
+        double itol = 1 - tol;
+        if (ax > itol) {
+            if (ay < tol) {
+                return (az < tol);
+            }
+        } else if (ay > itol) {
+            if (ax < tol) {
+                return (az < tol);
+            }
+        } else if (az > itol) {
+            if (ax < tol) {
+                return (ay < tol);
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public final boolean isZeroVector() {
+        return MathUtils.abs(x) < MathUtils.EPS
+                && MathUtils.abs(y) < MathUtils.EPS
+                && MathUtils.abs(z) < MathUtils.EPS;
+    }
+
+    /**
+     * Add random jitter to the vector in the range -j ... +j using the default
+     * {@link Random} generator of {@link MathUtils}.
+     *
+     * @param j
+     *            the j
+     *
+     * @return the vec3 d
+     */
+    public final Vec3DDouble jitter(double j) {
+        return jitter(j, j, j);
+    }
+
+    /**
+     * Adds random jitter to the vector in the range -j ... +j using the default
+     * {@link Random} generator of {@link MathUtils}.
+     *
+     * @param jx
+     *            maximum x jitter
+     * @param jy
+     *            maximum y jitter
+     * @param jz
+     *            maximum z jitter
+     *
+     * @return itself
+     */
+    public final Vec3DDouble jitter(double jx, double jy, double jz) {
+        x += MathUtils.normalizedRandom() * jx;
+        y += MathUtils.normalizedRandom() * jy;
+        z += MathUtils.normalizedRandom() * jz;
+        return this;
+    }
+
+    public final Vec3DDouble jitter(Random rnd, double j) {
+        return jitter(rnd, j, j, j);
+    }
+
+    public final Vec3DDouble jitter(Random rnd, double jx, double jy, double jz) {
+        x += MathUtils.normalizedRandom(rnd) * jx;
+        y += MathUtils.normalizedRandom(rnd) * jy;
+        z += MathUtils.normalizedRandom(rnd) * jz;
+        return this;
+    }
+
+    public final Vec3DDouble jitter(Random rnd, Vec3DDouble jitterVec) {
+        return jitter(rnd, jitterVec.x, jitterVec.y, jitterVec.z);
+    }
+
+    /**
+     * Adds random jitter to the vector in the range defined by the given vector
+     * components and using the default {@link Random} generator of
+     * {@link MathUtils}.
+     *
+     * @param jitterVec
+     *            the jitter vec
+     *
+     * @return itself
+     */
+    public final Vec3DDouble jitter(Vec3DDouble jitterVec) {
+        return jitter(jitterVec.x, jitterVec.y, jitterVec.z);
+    }
+
+    /**
+     * Limits the vector's magnitude to the length given.
+     *
+     * @param lim
+     *            new maximum magnitude
+     *
+     * @return itself
+     */
+    public final Vec3DDouble limit(double lim) {
+        if (magSquared() > lim * lim) {
+            return normalize().scaleSelf(lim);
+        }
+        return this;
+    }
+
+    @Override
+    public final double magnitude() {
+        return Math.sqrt(x * x + y * y + z * z);
+    }
+
+    @Override
+    public final double magSquared() {
+        return x * x + y * y + z * z;
+    }
+
+    /**
+     * Max self.
+     *
+     * @param b
+     *            the b
+     *
+     * @return the vec3 d
+     */
+    public final Vec3DDouble maxSelf(ReadonlyVec3DDouble b) {
+        x = MathUtils.max(x, b.x());
+        y = MathUtils.max(y, b.y());
+        z = MathUtils.max(z, b.z());
+        return this;
+    }
+
+    /**
+     * Min self.
+     *
+     * @param b
+     *            the b
+     *
+     * @return the vec3 d
+     */
+    public final Vec3DDouble minSelf(ReadonlyVec3DDouble b) {
+        x = MathUtils.min(x, b.x());
+        y = MathUtils.min(y, b.y());
+        z = MathUtils.min(z, b.z());
+        return this;
+    }
+
+    /**
+     * Applies a uniform modulo operation to the vector, using the same base for
+     * all components.
+     *
+     * @param base
+     *            the base
+     *
+     * @return itself
+     */
+    public final Vec3DDouble modSelf(double base) {
+        x %= base;
+        y %= base;
+        z %= base;
+        return this;
+    }
+
+    /**
+     * Calculates modulo operation for each vector component separately.
+     *
+     * @param bx
+     *            the bx
+     * @param by
+     *            the by
+     * @param bz
+     *            the bz
+     *
+     * @return itself
+     */
+
+    public final Vec3DDouble modSelf(double bx, double by, double bz) {
+        x %= bx;
+        y %= by;
+        z %= bz;
+        return this;
+    }
+
+    /**
+     * Normalizes the vector so that its magnitude = 1.
+     *
+     * @return itself
+     */
+    public final Vec3DDouble normalize() {
+        double mag = Math.sqrt(x * x + y * y + z * z);
+        if (mag > 0) {
+            mag = 1f / mag;
+            x *= mag;
+            y *= mag;
+            z *= mag;
+        }
+        return this;
+    }
+
+    /**
+     * Normalizes the vector to the given length.
+     *
+     * @param len
+     *            desired length
+     * @return itself
+     */
+    public final Vec3DDouble normalizeTo(double len) {
+        double mag = Math.sqrt(x * x + y * y + z * z);
+        if (mag > 0) {
+            mag = len / mag;
+            x *= mag;
+            y *= mag;
+            z *= mag;
+        }
+        return this;
+    }
+
+    /**
+     * Replaces the vector components with their multiplicative inverse.
+     *
+     * @return itself
+     */
+    public final Vec3DDouble reciprocal() {
+        x = 1f / x;
+        y = 1f / y;
+        z = 1f / z;
+        return this;
+    }
+
+    public final Vec3DDouble reflect(ReadonlyVec3DDouble normal) {
+        return set(normal.scale(this.dot(normal) * 2).subSelf(this));
+    }
+
+    /**
+     * Rotates the vector around the giving axis.
+     *
+     * @param axis
+     *            rotation axis vector
+     * @param theta
+     *            rotation angle (in radians)
+     *
+     * @return itself
+     */
+    public final Vec3DDouble rotateAroundAxis(ReadonlyVec3DDouble axis, double theta) {
+        final double ax = axis.x();
+        final double ay = axis.y();
+        final double az = axis.z();
+        final double ux = ax * x;
+        final double uy = ax * y;
+        final double uz = ax * z;
+        final double vx = ay * x;
+        final double vy = ay * y;
+        final double vz = ay * z;
+        final double wx = az * x;
+        final double wy = az * y;
+        final double wz = az * z;
+        final double si = Math.sin(theta);
+        final double co = Math.cos(theta);
+        double xx = ax * (ux + vy + wz)
+                + (x * (ay * ay + az * az) - ax * (vy + wz)) * co + (-wy + vz)
+                * si;
+        double yy = ay * (ux + vy + wz)
+                + (y * (ax * ax + az * az) - ay * (ux + wz)) * co + (wx - uz)
+                * si;
+        double zz = az * (ux + vy + wz)
+                + (z * (ax * ax + ay * ay) - az * (ux + vy)) * co + (-vx + uy)
+                * si;
+        x = xx;
+        y = yy;
+        z = zz;
+        return this;
+    }
+
+    /**
+     * Rotates the vector by the given angle around the X axis.
+     *
+     * @param theta
+     *            the theta
+     *
+     * @return itself
+     */
+    public final Vec3DDouble rotateX(double theta) {
+        final double co = Math.cos(theta);
+        final double si = Math.sin(theta);
+        final double zz = co * z - si * y;
+        y = si * z + co * y;
+        z = zz;
+        return this;
+    }
+
+    /**
+     * Rotates the vector by the given angle around the Y axis.
+     *
+     * @param theta
+     *            the theta
+     *
+     * @return itself
+     */
+    public final Vec3DDouble rotateY(double theta) {
+        final double co = Math.cos(theta);
+        final double si = Math.sin(theta);
+        final double xx = co * x - si * z;
+        z = si * x + co * z;
+        x = xx;
+        return this;
+    }
+
+    /**
+     * Rotates the vector by the given angle around the Z axis.
+     *
+     * @param theta
+     *            the theta
+     *
+     * @return itself
+     */
+    public final Vec3DDouble rotateZ(double theta) {
+        final double co = Math.cos(theta);
+        final double si = Math.sin(theta);
+        final double xx = co * x - si * y;
+        y = si * x + co * y;
+        x = xx;
+        return this;
+    }
+
+/*
+    public Vec3DDouble roundTo(double prec) {
+        x = MathUtils.roundTo(x, prec);
+        y = MathUtils.roundTo(y, prec);
+        z = MathUtils.roundTo(z, prec);
+        return this;
+    }
+*/
+
+    @Override
+    public Vec3DDouble scale(double s) {
+        return new Vec3DDouble(x * s, y * s, z * s);
+    }
+
+    @Override
+    public Vec3DDouble scale(double a, double b, double c) {
+        return new Vec3DDouble(x * a, y * b, z * c);
+    }
+
+    @Override
+    public Vec3DDouble scale(ReadonlyVec3DDouble s) {
+        return new Vec3DDouble(x * s.x(), y * s.y(), z * s.z());
+    }
+
+    public Vec3DDouble scale(Vec3DDouble s) {
+        return new Vec3DDouble(x * s.x, y * s.y, z * s.z);
+    }
+
+    /**
+     * Scales vector uniformly and overrides coordinates with result.
+     *
+     * @param s
+     *            scale factor
+     *
+     * @return itself
+     */
+    public Vec3DDouble scaleSelf(double s) {
+        x *= s;
+        y *= s;
+        z *= s;
+        return this;
+    }
+
+    /**
+     * Scales vector non-uniformly by vector {a,b,c} and overrides coordinates
+     * with result.
+     *
+     * @param a
+     *            scale factor for X coordinate
+     * @param b
+     *            scale factor for Y coordinate
+     * @param c
+     *            scale factor for Z coordinate
+     *
+     * @return itself
+     */
+    public Vec3DDouble scaleSelf(double a, double b, double c) {
+        x *= a;
+        y *= b;
+        z *= c;
+        return this;
+    }
+
+    public Vec3DDouble scaleSelf(ReadonlyVec3DDouble s) {
+        x *= s.x();
+        y *= s.y();
+        z *= s.z();
+        return this;
+    }
+
+    /**
+     * Scales vector non-uniformly by vector v and overrides coordinates with
+     * result.
+     *
+     * @param s
+     *            scale vector
+     *
+     * @return itself
+     */
+
+    public Vec3DDouble scaleSelf(Vec3DDouble s) {
+        x *= s.x;
+        y *= s.y;
+        z *= s.z;
+        return this;
+    }
+
+    /**
+     * Overrides coordinates with the given values.
+     *
+     * @param x
+     *            the x
+     * @param y
+     *            the y
+     * @param z
+     *            the z
+     *
+     * @return itself
+     */
+    public Vec3DDouble set(double x, double y, double z) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+        return this;
+    }
+
+    public Vec3DDouble set(ReadonlyVec3DDouble v) {
+        x = v.x();
+        y = v.y();
+        z = v.z();
+        return this;
+    }
+
+    /**
+     * Overrides coordinates with the ones of the given vector.
+     *
+     * @param v
+     *            vector to be copied
+     *
+     * @return itself
+     */
+    public Vec3DDouble set(Vec3DDouble v) {
+        x = v.x;
+        y = v.y;
+        z = v.z;
+        return this;
+    }
+
+    public final Vec3DDouble setComponent(Axis id, double val) {
+        switch (id) {
+            case X:
+                x = val;
+                break;
+            case Y:
+                y = val;
+                break;
+            case Z:
+                z = val;
+                break;
+        }
+        return this;
+    }
+
+    public final Vec3DDouble setComponent(int id, double val) {
+        switch (id) {
+            case 0:
+                x = val;
+                break;
+            case 1:
+                y = val;
+                break;
+            case 2:
+                z = val;
+                break;
+        }
+        return this;
+    }
+
+    public Vec3DDouble setX(double x) {
+        this.x = x;
+        return this;
+    }
+
+    /**
+     * Overrides XY coordinates with the ones of the given 2D vector.
+     *
+     * @param v
+     *            2D vector
+     *
+     * @return itself
+     */
+    public Vec3DDouble setXY(Vec2D v) {
+        x = v.x;
+        y = v.y;
+        return this;
+    }
+
+    public Vec3DDouble setY(double y) {
+        this.y = y;
+        return this;
+    }
+
+    public Vec3DDouble setZ(double z) {
+        this.z = z;
+        return this;
+    }
+
+    public Vec3DDouble shuffle(int iterations) {
+        double t;
+        for (int i = 0; i < iterations; i++) {
+            switch (MathUtils.random(3)) {
+                case 0:
+                    t = x;
+                    x = y;
+                    y = t;
+                    break;
+                case 1:
+                    t = x;
+                    x = z;
+                    z = t;
+                    break;
+                case 2:
+                    t = y;
+                    y = z;
+                    z = t;
+                    break;
+            }
+        }
+        return this;
+    }
+
+    /**
+     * Replaces all vector components with the signum of their original values.
+     * In other words if a components value was negative its new value will be
+     * -1, if zero =&gt; 0, if positive =&gt; +1
+     *
+     * @return itself
+     */
+    public Vec3DDouble signum() {
+        x = (x < 0 ? -1 : x == 0 ? 0 : 1);
+        y = (y < 0 ? -1 : y == 0 ? 0 : 1);
+        z = (z < 0 ? -1 : z == 0 ? 0 : 1);
+        return this;
+    }
+
+    /**
+     * Rounds the vector to the closest major axis. Assumes the vector is
+     * normalized.
+     *
+     * @return itself
+     */
+    public final Vec3DDouble snapToAxis() {
+        if (MathUtils.abs(x) < 0.5f) {
+            x = 0;
+        } else {
+            x = x < 0 ? -1 : 1;
+            y = z = 0;
+        }
+        if (MathUtils.abs(y) < 0.5f) {
+            y = 0;
+        } else {
+            y = y < 0 ? -1 : 1;
+            x = z = 0;
+        }
+        if (MathUtils.abs(z) < 0.5f) {
+            z = 0;
+        } else {
+            z = z < 0 ? -1 : 1;
+            x = y = 0;
+        }
+        return this;
+    }
+
+    @Override
+    public final Vec3DDouble sub(double a, double b, double c) {
+        return new Vec3DDouble(x - a, y - b, z - c);
+    }
+
+    @Override
+    public final Vec3DDouble sub(ReadonlyVec3DDouble v) {
+        return new Vec3DDouble(x - v.x(), y - v.y(), z - v.z());
+    }
+
+    public final Vec3DDouble sub(Vec3DDouble v) {
+        return new Vec3DDouble(x - v.x, y - v.y, z - v.z);
+    }
+
+    /**
+     * Subtracts vector {a,b,c} and overrides coordinates with result.
+     *
+     * @param a
+     *            X coordinate
+     * @param b
+     *            Y coordinate
+     * @param c
+     *            Z coordinate
+     *
+     * @return itself
+     */
+    public final Vec3DDouble subSelf(double a, double b, double c) {
+        x -= a;
+        y -= b;
+        z -= c;
+        return this;
+    }
+
+    public final Vec3DDouble subSelf(ReadonlyVec3DDouble v) {
+        x -= v.x();
+        y -= v.y();
+        z -= v.z();
+        return this;
+    }
+
+    /**
+     * Subtracts vector v and overrides coordinates with result.
+     *
+     * @param v
+     *            vector to be subtracted
+     *
+     * @return itself
+     */
+    public final Vec3DDouble subSelf(Vec3DDouble v) {
+        x -= v.x;
+        y -= v.y;
+        z -= v.z;
+        return this;
+    }
+
+    @Override
+    public final Vec2D to2DXY() {
+        return new Vec2D((float)x, (float)y);
+    }
+
+    @Override
+    public final Vec2D to2DXZ() {
+        return new Vec2D((float)x, (float)z);
+    }
+
+    @Override
+    public final Vec2D to2DYZ() {
+        return new Vec2D((float)y, (float)z);
+    }
+
+    @Override
+    public double[] toArray() {
+        return new double[] { x, y, z };
+    }
+
+    @Override
+    public double[] toArray4(double w) {
+        return new double[] { x, y, z, w };
+    }
+
+    public final Vec3DDouble toCartesian() {
+        final double a = x * Math.cos(z);
+        final double xx = a * Math.cos(y);
+        final double yy = x * Math.sin(z);
+        final double zz = a * Math.sin(y);
+        x = xx;
+        y = yy;
+        z = zz;
+        return this;
+    }
+
+    public final Vec3DDouble toSpherical() {
+        final double xx = Math.abs(x) <= MathUtils.EPS ? MathUtils.EPS : x;
+        final double zz = z;
+
+        final double radius = Math.sqrt((xx * xx) + (y * y) + (zz * zz));
+        z = Math.asin(y / radius);
+        y = Math.atan(zz / xx) + (xx < 0.0 ? MathUtils.PI : 0);
+        x = radius;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuffer sb = new StringBuffer(48);
+        sb.append("{x:").append(x).append(", y:").append(y).append(", z:")
+                .append(z).append("}");
+        return sb.toString();
+    }
+
+    @Override
+    public final double x() {
+        return x;
+    }
+
+    @Override
+    public final double y() {
+        return y;
+    }
+
+    @Override
+    public final double z() {
+        return z;
+    }
+}
diff --git a/src/java/org/web3d/util/spatial/VolumetricSpaceArrayTriangle.java b/src/java/org/web3d/util/spatial/VolumetricSpaceArrayTriangle.java
index 1a08d40db605831c684ba95d377b6dff532e2b87..ff7525cc91147e0a5b56d23c40f3a8b73bd4fd77 100755
--- a/src/java/org/web3d/util/spatial/VolumetricSpaceArrayTriangle.java
+++ b/src/java/org/web3d/util/spatial/VolumetricSpaceArrayTriangle.java
@@ -1,69 +1,69 @@
-/*****************************************************************************
- *                        Yumetech Copyright (c) 2011
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.util.spatial;
-
-import java.util.*;
-
-import toxi.geom.Vec3D;
-
-/**
- *  A Volumetric Space which stores triangles.
- *
- * Code adapted from toxiclibs copyright Copyright(c) 2006-2011 Karsten Schmidt
- *
- * @author Alan Hudson
- */
-public class VolumetricSpaceArrayTriangle extends VolumetricSpaceTriangle {
-
-    protected Set<Triangle>[] data;
-
-    @SuppressWarnings("unchecked") // generic array type HashSet[]
-    public VolumetricSpaceArrayTriangle(Vec3D scale, int resX, int resY, int resZ) {
-        super(scale, resX, resY, resZ);
-        data = new HashSet[resX * resY * resZ];
-    }
-
-    @Override
-    public void clear() {
-        for (Set<Triangle> data1 : data) {
-            data1.clear();
-        }
-    }
-
-    public Set[] getData() {
-        return data;
-    }
-
-    @Override
-    public void insertAt(int x, int y, int z, Triangle tri) {
-        int idx = x + y * resX + z * sliceRes;
-        Set<Triangle> val = data[idx];
-
-        if (val == null) {
-            val = new HashSet<>(1);
-            data[idx] = val;
-        }
-//System.out.println("Adding tri at: " + x + " " + y + " " + z);
-        val.add(tri);
-    }
-
-    @Override
-    public Set<Triangle> getVoxelAt(int index) {
-        return data[index];
-    }
-
-    @Override
-    public Set<Triangle> getVoxelAt(int x, int y, int z) {
-        return data[x + y * resX + z * sliceRes];
-    }
-}
+/*****************************************************************************
+ *                        Yumetech Copyright (c) 2011
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.util.spatial;
+
+import java.util.*;
+
+import toxi.geom.Vec3D;
+
+/**
+ *  A Volumetric Space which stores triangles.
+ *
+ * Code adapted from toxiclibs copyright Copyright(c) 2006-2011 Karsten Schmidt
+ *
+ * @author Alan Hudson
+ */
+public class VolumetricSpaceArrayTriangle extends VolumetricSpaceTriangle {
+
+    protected Set<Triangle>[] data;
+
+    @SuppressWarnings("unchecked") // generic array type HashSet[]
+    public VolumetricSpaceArrayTriangle(Vec3D scale, int resX, int resY, int resZ) {
+        super(scale, resX, resY, resZ);
+        data = new HashSet[resX * resY * resZ];
+    }
+
+    @Override
+    public void clear() {
+        for (Set<Triangle> data1 : data) {
+            data1.clear();
+        }
+    }
+
+    public Set[] getData() {
+        return data;
+    }
+
+    @Override
+    public void insertAt(int x, int y, int z, Triangle tri) {
+        int idx = x + y * resX + z * sliceRes;
+        Set<Triangle> val = data[idx];
+
+        if (val == null) {
+            val = new HashSet<>(1);
+            data[idx] = val;
+        }
+//System.out.println("Adding tri at: " + x + " " + y + " " + z);
+        val.add(tri);
+    }
+
+    @Override
+    public Set<Triangle> getVoxelAt(int index) {
+        return data[index];
+    }
+
+    @Override
+    public Set<Triangle> getVoxelAt(int x, int y, int z) {
+        return data[x + y * resX + z * sliceRes];
+    }
+}
diff --git a/src/java/org/web3d/vrml/export/BaseRetainedExporter.java b/src/java/org/web3d/vrml/export/BaseRetainedExporter.java
index 327d9eb5e5ed7627b11bae5aa27d0b0b1bbd6cd6..2743029dd88fba301114e586c194552a2f95db88 100644
--- a/src/java/org/web3d/vrml/export/BaseRetainedExporter.java
+++ b/src/java/org/web3d/vrml/export/BaseRetainedExporter.java
@@ -324,6 +324,15 @@ public abstract class BaseRetainedExporter extends Exporter implements BinaryCon
     // ContentHandler methods
     //----------------------------------------------------------
 
+    /**
+     * Declaration of the end of the document. There will be no further parsing
+     * and hence events after this.
+     *
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
     @Override
     public void endDocument() throws SAVException, VRMLException {
         builder.endDocument();
@@ -333,10 +342,7 @@ public abstract class BaseRetainedExporter extends Exporter implements BinaryCon
 
         if (convertOldContent) {
             if (hanimFound)
-            {
-                componentList.add(new ComponentInfo("H-Anim",1));
-                componentList.add(new ComponentInfo("HAnim",1)); // HAnim in X3Dv4, allowed for backwards compatibility
-            }
+                componentList.add(new ComponentInfo("H-Anim",1)); // TODO HAnim in X3Dv4
             if (geospatialFound)
                 componentList.add(new ComponentInfo("Geospatial",1));
         }
diff --git a/src/java/org/web3d/vrml/export/ExporterFactory.java b/src/java/org/web3d/vrml/export/ExporterFactory.java
index 8de954b75f88b45276c4b6bbd0e1feb004ff847a..5944496bd76da8789aee6d2ca27952a8043f5e37 100644
--- a/src/java/org/web3d/vrml/export/ExporterFactory.java
+++ b/src/java/org/web3d/vrml/export/ExporterFactory.java
@@ -1,27 +1,27 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-package org.web3d.vrml.export;
-
-// Standard library imports
-// None
-
-// Application specific imports
-// None
-
-/**
- * A factory for getting an exporter for an encoding.
- *
- * @author Alan Hudson.
- * @version $Revision: 1.2 $
- */
-public class ExporterFactory {
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+package org.web3d.vrml.export;
+
+// Standard library imports
+// None
+
+// Application specific imports
+// None
+
+/**
+ * A factory for getting an exporter for an encoding.
+ *
+ * @author Alan Hudson.
+ * @version $Revision: 1.2 $
+ */
+public class ExporterFactory {
+}
diff --git a/src/java/org/web3d/vrml/export/X3DBinaryRetainedExporter.java b/src/java/org/web3d/vrml/export/X3DBinaryRetainedExporter.java
index 807432916f08b7932f809f2fedfc8cae526071b3..e286fd845f6215977bda64d906dee2e4bb18f0a8 100644
--- a/src/java/org/web3d/vrml/export/X3DBinaryRetainedExporter.java
+++ b/src/java/org/web3d/vrml/export/X3DBinaryRetainedExporter.java
@@ -1,126 +1,126 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.export;
-
-// External imports
-import java.io.*;
-
-import org.j3d.util.ErrorReporter;
-
-// Local imports
-import org.web3d.vrml.nodes.*;
-
-/**
- * X3D XML exporter using a retained Scenegraph.
- *
- * TODO: I do not think this class is used anymore and its binary processing
- * is now incorrect.
- *
- * Known Issues:
- *
- *    Proto node fields are copied into instances
- *
- * @author Alan Hudson
- * @version $Revision: 1.8 $
- */
-public class X3DBinaryRetainedExporter extends X3DXMLRetainedExporter
-    implements SceneGraphTraversalSimpleObserver {
-
-    /** The original stream */
-    private OutputStream origStream;
-
-    /**
-     * Create a new exporter for the given spec version
-     *
-     * @param os The stream to export the code to
-     * @param major The major version number of this scene
-     * @param minor The minor version number of this scene
-     * @param errorReporter The error reporter to use
-     * @param compressionMethod The method to use for compression
-     * @param quantizeParam The largest quantization acceptable using lossy methods
-     */
-    public X3DBinaryRetainedExporter(OutputStream os, int major, int minor,
-        ErrorReporter errorReporter, int compressionMethod, float quantizeParam) {
-
-        super(new ByteArrayOutputStream(), major, minor, errorReporter);
-
-        this.compressionMethod = compressionMethod;
-        this.quantizeParam = quantizeParam;
-
-        if (compressionMethod == X3DBinarySerializer.METHOD_SMALLEST_LOSSY) {
-            useNC = true;
-        }
-
-        origStream = os;
-
-        printDocType = false;
-        stripWhitespace = true;
-
-        encodingTo = ".x3db";
-    }
-
-    /**
-     * Write a scene out.
-     *
-     * @param scene The scene to write
-     */
-    @Override
-    public void writeScene(VRMLScene scene) {
-        boolean wait = false;
-
-//long stage = startTime;
-//System.out.println("Initial Parsing Time     : " + (System.currentTimeMillis() - stage));
-//if (wait) waitForInput();
-
-        super.writeScene(scene);
-
-//System.out.println("Write to XML encoded file: " + (System.currentTimeMillis() - stage));
-//if (wait) waitForInput();
-//stage = System.currentTimeMillis();
-
-        String buff = filterWriter.toString();
-//System.out.println("Convert to String        : " + (System.currentTimeMillis() - stage));
-//stage = System.currentTimeMillis();
-
-        StringBufferInputStream bis = new StringBufferInputStream(buff);
-        BufferedInputStream buffis = new BufferedInputStream(bis);
-
-        X3DBinarySerializer bs = new X3DBinarySerializer(compressionMethod,
-           false, quantizeParam);
-
-        bs.setProtoMap(protoMap);
-        bs.writeFiltered(buffis, origStream);
-
-        try {
-            origStream.close();
-        } catch(IOException ioe) {
-            ioe.printStackTrace(System.err);
-        }
-//System.out.println("Write to FI Binary       : " + (System.currentTimeMillis() - stage));
-//System.out.println("total time               : " + (System.currentTimeMillis() - startTime));
-    }
-
-    private void waitForInput() {
-        InputStreamReader isr = new InputStreamReader ( System.in );
-        BufferedReader br = new BufferedReader ( isr );
-        String s = null;
-
-        System.out.println("Press return to continue");
-        try {
-           s = br.readLine ();
-        }
-        catch ( IOException ioe ) {
-           // won't happen too often from the keyboard
-        }
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.export;
+
+// External imports
+import java.io.*;
+
+import org.j3d.util.ErrorReporter;
+
+// Local imports
+import org.web3d.vrml.nodes.*;
+
+/**
+ * X3D XML exporter using a retained Scenegraph.
+ *
+ * TODO: I do not think this class is used anymore and its binary processing
+ * is now incorrect.
+ *
+ * Known Issues:
+ *
+ *    Proto node fields are copied into instances
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.8 $
+ */
+public class X3DBinaryRetainedExporter extends X3DXMLRetainedExporter
+    implements SceneGraphTraversalSimpleObserver {
+
+    /** The original stream */
+    private OutputStream origStream;
+
+    /**
+     * Create a new exporter for the given spec version
+     *
+     * @param os The stream to export the code to
+     * @param major The major version number of this scene
+     * @param minor The minor version number of this scene
+     * @param errorReporter The error reporter to use
+     * @param compressionMethod The method to use for compression
+     * @param quantizeParam The largest quantization acceptable using lossy methods
+     */
+    public X3DBinaryRetainedExporter(OutputStream os, int major, int minor,
+        ErrorReporter errorReporter, int compressionMethod, float quantizeParam) {
+
+        super(new ByteArrayOutputStream(), major, minor, errorReporter);
+
+        this.compressionMethod = compressionMethod;
+        this.quantizeParam = quantizeParam;
+
+        if (compressionMethod == X3DBinarySerializer.METHOD_SMALLEST_LOSSY) {
+            useNC = true;
+        }
+
+        origStream = os;
+
+        printDocType = false;
+        stripWhitespace = true;
+
+        encodingTo = ".x3db";
+    }
+
+    /**
+     * Write a scene out.
+     *
+     * @param scene The scene to write
+     */
+    @Override
+    public void writeScene(VRMLScene scene) {
+        boolean wait = false;
+
+//long stage = startTime;
+//System.out.println("Initial Parsing Time     : " + (System.currentTimeMillis() - stage));
+//if (wait) waitForInput();
+
+        super.writeScene(scene);
+
+//System.out.println("Write to XML encoded file: " + (System.currentTimeMillis() - stage));
+//if (wait) waitForInput();
+//stage = System.currentTimeMillis();
+
+        String buff = filterWriter.toString();
+//System.out.println("Convert to String        : " + (System.currentTimeMillis() - stage));
+//stage = System.currentTimeMillis();
+
+        StringBufferInputStream bis = new StringBufferInputStream(buff);
+        BufferedInputStream buffis = new BufferedInputStream(bis);
+
+        X3DBinarySerializer bs = new X3DBinarySerializer(compressionMethod,
+           false, quantizeParam);
+
+        bs.setProtoMap(protoMap);
+        bs.writeFiltered(buffis, origStream);
+
+        try {
+            origStream.close();
+        } catch(IOException ioe) {
+            ioe.printStackTrace(System.err);
+        }
+//System.out.println("Write to FI Binary       : " + (System.currentTimeMillis() - stage));
+//System.out.println("total time               : " + (System.currentTimeMillis() - startTime));
+    }
+
+    private void waitForInput() {
+        InputStreamReader isr = new InputStreamReader ( System.in );
+        BufferedReader br = new BufferedReader ( isr );
+        String s = null;
+
+        System.out.println("Press return to continue");
+        try {
+           s = br.readLine ();
+        }
+        catch ( IOException ioe ) {
+           // won't happen too often from the keyboard
+        }
+    }
+}
diff --git a/src/java/org/web3d/vrml/export/X3DBinarySerializer.java b/src/java/org/web3d/vrml/export/X3DBinarySerializer.java
index 96b3a104a2f42f0420bed9aef8ea95e1eeb724db..caf3e9362c10a07a7c1471c92aa3c1ab4225520d 100644
--- a/src/java/org/web3d/vrml/export/X3DBinarySerializer.java
+++ b/src/java/org/web3d/vrml/export/X3DBinarySerializer.java
@@ -1,1073 +1,1073 @@
-/*****************************************************************************
- *                    Yumetech, Inc Copyright (c) 2001-2006
- *                               Java Source
- *
- * This source is licensed under the BSD license.
- * Please read docs/BSD.txt for the text of the license.
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.export;
-
-// External imports
-import com.sun.xml.fastinfoset.algorithm.BuiltInEncodingAlgorithmFactory;
-import com.sun.xml.fastinfoset.QualifiedName;
-import com.sun.xml.fastinfoset.sax.AttributesHolder;
-import com.sun.xml.fastinfoset.sax.SAXDocumentSerializer;
-import com.sun.xml.fastinfoset.vocab.SerializerVocabulary;
-
-import java.io.*;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.xml.transform.*;
-import javax.xml.parsers.*;
-import javax.xml.transform.sax.SAXResult;
-
-import org.jvnet.fastinfoset.EncodingAlgorithm;
-import org.jvnet.fastinfoset.EncodingAlgorithmIndexes;
-
-import org.xml.sax.*;
-
-// Local imports
-import org.web3d.util.SimpleStack;
-import org.web3d.vrml.lang.*;
-import org.web3d.vrml.renderer.DefaultNodeFactory;
-import org.web3d.parser.x3d.X3DFieldReader;
-import org.web3d.parser.x3d.*;
-import org.web3d.vrml.nodes.*;
-import org.web3d.x3d.jaxp.X3DEntityResolver;
-import org.web3d.vrml.renderer.CRProtoCreator;
-import org.web3d.vrml.renderer.norender.NRProtoCreator;
-import org.web3d.vrml.renderer.CRVRMLScene;
-
-/**
- *  Serializes an X3D XML encoded document into an X3D binary document.
- *
- * TODO: Stats collection for non builtins isn't written
- * TODO: proto and script fields are encoded as strings
- *
- * @author Alan Hudson
- * @version $Revision: 1.11 $
- */
-public class X3DBinarySerializer {
-
-    // Encode files for fastest parsing
-    public static final int METHOD_FASTEST_PARSING = 0;
-
-    // Encode files for smallest size using non lossy techniques
-    public static final int METHOD_SMALLEST_NONLOSSY = 1;
-
-    // Encode files for smallest size using lossy techniques
-    public static final int METHOD_SMALLEST_LOSSY = 2;
-
-    // Encode files using Strings */
-    public static final int METHOD_STRINGS = 3;
-
-    // Smallest float difference for equality
-    private static final float FLOAT_EPS = 0.0000009f;
-
-    // Largest acceptable error for float quantization
-    private static float PARAM_FLOAT_LOSSY = 0.001f;
-
-    // Usage docs
-    private static final String USAGE = "Usage:  X3DSerializer [options] <input> <output>\n" +
-                                        "options:  -method [fastest, smallest, lossy]\n" +
-                                        "          -quantizeParam n\n" +
-                                        "          -savedefaults";
-
-    private Transformer _transformer;
-    private DocumentBuilder _docBuilder;
-    private Source _source = null;
-    private SAXResult _result = null;
-
-    protected static final String VALIDATION_FEATURE_ID = "http://xml.org/sax/features/validation";
-    protected static final String SCHEMA_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/schema";
-    protected static final String LOAD_DTD_ID = "http://apache.org/xml/features/nonvalidating/load-dtd-grammar";
-
-    /** The node factory used to create real node instances */
-    private VRMLNodeFactory nodeFactory;
-
-    /** Cache of nodes used for type information. NodeName --> Node*/
-    private Map<String, VRMLNodeType> nodeCache;
-
-    /** A field parser */
-    private X3DFieldReader fieldParser;
-
-    private int[] fieldTypeStats;
-    private int[] fieldTypeOrigSize;
-    private int[] fieldTypeNewSize;
-    private Map<Integer, String> fieldTypeMap;
-    private boolean collectStats = true;
-
-    /** What method should we use to compress */
-    private int method;
-
-    /** Should we remove defaults */
-    private boolean removeDefaults;
-
-    /** How many default values where removed */
-    private int defaults;
-
-    /** Single level proto map  */
-    private Map<String, VRMLFieldDeclaration> protoMap;
-
-    /** The creator used to instantiate protos */
-    protected CRProtoCreator protoCreator;
-
-    /** The spec major version to use */
-    private int majorVersion;
-
-    /** The spec minor version to use */
-    private int minorVersion;
-
-    /** Root node used for proto creation */
-    protected VRMLWorldRootNodeType root;
-
-    /** A Stack of element names */
-    private SimpleStack elementStack;
-
-    /**
-     * Creates a new instance of X3DSerializer
-     *
-     * @param compMethod What method to use
-     * @param rd Should we remove defaults
-     * @param lossParam maximum loss for lossy compression
-     */
-    public X3DBinarySerializer(int compMethod, boolean rd, float lossParam) {
-        method = compMethod;
-        removeDefaults = rd;
-        PARAM_FLOAT_LOSSY = lossParam;
-
-        elementStack = new SimpleStack();
-        elementStack.push("WorldRoot");
-
-        try {
-            // get a transformer and document builder
-            _transformer = TransformerFactory.newInstance().newTransformer();
-            _docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
-        } catch (TransformerConfigurationException | ParserConfigurationException e) {
-            e.printStackTrace(System.err);
-        }
-
-        majorVersion = 3;
-        minorVersion = 1;
-
-        nodeFactory = DefaultNodeFactory.newInstance(DefaultNodeFactory.NULL_RENDERER);
-        nodeFactory.setSpecVersion(majorVersion, minorVersion);
-        nodeFactory.setProfile("Immersive");
-
-        nodeCache = new HashMap<>();
-
-        fieldParser = new X3DFieldReader();
-        fieldParser.setCaseSensitive(false);
-
-        fieldTypeStats = new int[43];
-        fieldTypeOrigSize = new int[43];
-        fieldTypeNewSize = new int[43];
-        fieldTypeMap = new HashMap<>();
-        fieldTypeMap.put(FieldConstants.SFINT32, "SFInt32    ");
-        fieldTypeMap.put(FieldConstants.MFINT32, "MFInt32    ");
-        fieldTypeMap.put(FieldConstants.SFFLOAT, "SFFloat    ");
-        fieldTypeMap.put(FieldConstants.MFFLOAT, "MFFloat    ");
-        fieldTypeMap.put(FieldConstants.SFDOUBLE, "SFDouble   ");
-        fieldTypeMap.put(FieldConstants.MFDOUBLE, "MFDouble   ");
-        fieldTypeMap.put(FieldConstants.SFLONG, "SFLong     ");
-        fieldTypeMap.put(FieldConstants.MFLONG, "MFLong     ");
-        fieldTypeMap.put(FieldConstants.SFBOOL, "SFBool     ");
-        fieldTypeMap.put(FieldConstants.MFBOOL, "MFBool     ");
-        fieldTypeMap.put(FieldConstants.SFVEC2F, "SFVec2f    ");
-        fieldTypeMap.put(FieldConstants.MFVEC2F, "MFVec2f    ");
-        fieldTypeMap.put(FieldConstants.SFVEC2D, "SFVec2d    ");
-        fieldTypeMap.put(FieldConstants.MFVEC2D, "MFVec2d    ");
-        fieldTypeMap.put(FieldConstants.SFVEC3F, "SFVec3f    ");
-        fieldTypeMap.put(FieldConstants.MFVEC3F, "MFVec3f    ");
-        fieldTypeMap.put(FieldConstants.SFVEC3D, "SFVec3d    ");
-        fieldTypeMap.put(FieldConstants.MFVEC3D, "MFVec3d    ");
-        fieldTypeMap.put(FieldConstants.SFVEC4F, "SFVec4f    ");
-        fieldTypeMap.put(FieldConstants.MFVEC4F, "MFVec4f    ");
-        fieldTypeMap.put(FieldConstants.SFVEC4D, "SFVec4d    ");
-        fieldTypeMap.put(FieldConstants.MFVEC4D, "MFVec4d    ");
-        fieldTypeMap.put(FieldConstants.SFIMAGE, "SFImage    ");
-        fieldTypeMap.put(FieldConstants.MFIMAGE, "MFImage    ");
-        fieldTypeMap.put(FieldConstants.SFTIME, "SFTime     ");
-        fieldTypeMap.put(FieldConstants.MFTIME, "MFTime     ");
-        fieldTypeMap.put(FieldConstants.SFNODE, "SFNode     ");
-        fieldTypeMap.put(FieldConstants.MFNODE, "MFNode     ");
-        fieldTypeMap.put(FieldConstants.SFSTRING, "SFString   ");
-        fieldTypeMap.put(FieldConstants.MFSTRING, "MFString   ");
-        fieldTypeMap.put(FieldConstants.SFROTATION, "SFRotation ");
-        fieldTypeMap.put(FieldConstants.MFROTATION, "MFRotation ");
-        fieldTypeMap.put(FieldConstants.SFCOLOR, "SFColor    ");
-        fieldTypeMap.put(FieldConstants.MFCOLOR, "MFColor    ");
-        fieldTypeMap.put(FieldConstants.SFCOLORRGBA, "SFColorRGBA");
-        fieldTypeMap.put(FieldConstants.MFCOLORRGBA, "MFColorRGBA");
-        fieldTypeMap.put(FieldConstants.SFMATRIX3F, "SFMatrix3f ");
-        fieldTypeMap.put(FieldConstants.MFMATRIX3F, "MFMatrix3f ");
-        fieldTypeMap.put(FieldConstants.SFMATRIX3D, "SFMatrix3d ");
-        fieldTypeMap.put(FieldConstants.MFMATRIX3D, "MFMatrix3d ");
-        fieldTypeMap.put(FieldConstants.SFMATRIX4F, "SFMatrix4f ");
-        fieldTypeMap.put(FieldConstants.MFMATRIX4F, "MFMatrix4f ");
-        fieldTypeMap.put(FieldConstants.SFMATRIX4D, "SFMatrix4d ");
-        fieldTypeMap.put(FieldConstants.MFMATRIX4D, "MFMatrix4d ");
-
-        protoMap = new HashMap<>();
-    }
-
-    /**
-     * Set the map of node names to prototype decl. This will only have the top
-     * level protos. Nested proto's will not have field type information for
-     * encoding.
-     *
-     * @param protoMap The top level proto map
-     */
-    public void setProtoMap(Map<String, VRMLFieldDeclaration> protoMap) {
-        this.protoMap = protoMap;
-
-        protoCreator = new NRProtoCreator(nodeFactory,
-                "",
-                majorVersion,
-                minorVersion);
-
-        root =
-                (VRMLWorldRootNodeType) nodeFactory.createVRMLNode("WorldRoot",
-                false);
-
-        CRVRMLScene scene = new CRVRMLScene(majorVersion, minorVersion);
-        scene.setNodeFactory(nodeFactory);
-        WriteableSceneMetaData metaData = new WriteableSceneMetaData("3.0",
-                true,
-                SceneMetaData.BINARY_ENCODING);
-
-        scene.setMetaData(metaData);
-
-        root.setContainedScene(scene);
-
-    }
-
-    public void writeFiltered(InputStream input, OutputStream output) {
-
-        System.out.println("Code used****");
-        try {
-
-            try (OutputStream fos = output) {
-                SAXDocumentSerializer serializer = new SAXDocumentSerializer();
-                //  TODO: We'd like to catch most DEF name limits
-                serializer.setMaxAttributeValueSize(32);
-                serializer.setOutputStream(fos);
-                SerializerVocabulary initialVocabulary = new SerializerVocabulary();
-                // TODO: Does this do a copy?
-                initialVocabulary.setExternalVocabulary(X3DBinaryConstants.EXTERNAL_VOCABULARY_URI_STRING,
-                        X3DBinaryVocabulary.serializerVoc, false);
-                serializer.setVocabulary(initialVocabulary);
-                Map<String, EncodingAlgorithm> algorithms = new HashMap<>();
-                algorithms.put(ByteEncodingAlgorithm.ALGORITHM_URI, new ByteEncodingAlgorithm());
-                algorithms.put(DeltazlibIntArrayAlgorithm.ALGORITHM_URI, new DeltazlibIntArrayAlgorithm());
-                if (method == METHOD_SMALLEST_LOSSY) {
-                    // Only global control available currently
-                    algorithms.put(QuantizedzlibFloatArrayAlgorithm.ALGORITHM_URI,
-                            new QuantizedzlibFloatArrayAlgorithm(PARAM_FLOAT_LOSSY));
-                } else {
-                    // Default is no loss
-                    algorithms.put(QuantizedzlibFloatArrayAlgorithm.ALGORITHM_URI, new QuantizedzlibFloatArrayAlgorithm());
-                }   serializer.setRegisteredEncodingAlgorithms(algorithms);
-                // Obtain an instance of an XMLReader implementation
-                // from a system property
-                XMLReader parser = javax.xml.parsers.SAXParserFactory.newInstance().newSAXParser().getXMLReader();
-                parser.setFeature(VALIDATION_FEATURE_ID, false);
-                X3DEntityResolver resolver = new X3DEntityResolver();
-                parser.setEntityResolver(resolver);
-
-                // Create a new instance and register it with the parser
-                ContentHandler contentHandler = new X3DFilter(serializer);
-                parser.setContentHandler(contentHandler);
-                InputSource is = new InputSource(input);
-                parser.parse(is);
-            }
-        } catch (SAXException | IOException | ParserConfigurationException e) {
-            e.printStackTrace(System.err);
-        }
-    }
-
-    public class X3DFilter implements ContentHandler {
-
-        private ContentHandler parent;
-
-        public X3DFilter(ContentHandler parent) {
-            this.parent = parent;
-        }
-
-        @Override
-        public void startElement(String namespaceURI, String localName,
-                String qualifiedName, Attributes atts) throws SAXException {
-
-            int len = atts.getLength();
-
-            if (atts.getLength() > 0) {
-
-                if (localName.equals("fieldValue")) {
-                    AttributesHolder aholder = new AttributesHolder();
-
-                    String fieldName = atts.getValue("name");
-                    aholder.addAttribute(new QualifiedName("", "", "name",
-                            "name"), fieldName);
-
-//                System.out.println("Looking for: " + (String)elementStack.peek() + "." + fieldName);
-                    VRMLFieldDeclaration decl = protoMap.get(elementStack.peek() + "." + fieldName);
-
-                    if (decl != null) {
-                        encodeField(decl.getFieldType(), "value", "value", atts.getValue("value"), aholder, null);
-                    } else {
-                        aholder.addAttribute(new QualifiedName("", "", "value",
-                                "value"), atts.getValue("value"));
-                    }
-
-                    parent.startElement(namespaceURI, localName, qualifiedName, aholder);
-
-                    elementStack.push("fieldValue");
-                    return;
-                }
-
-                try {
-                    VRMLNodeType node;
-
-                    node = nodeCache.get(localName);
-
-                    if (localName.equals("ProtoInstance")) {
-                        parent.startElement(namespaceURI, localName, qualifiedName, atts);
-                        elementStack.push(atts.getValue("name"));
-
-                        return;
-                    }
-
-                    if (node == null) {
-                        node = (VRMLNodeType) nodeFactory.createVRMLNode(localName, false);
-                        nodeCache.put(localName, node);
-                    }
-
-                    AttributesHolder aholder = new AttributesHolder();
-                    VRMLFieldDeclaration decl = null;
-                    String attName;
-
-                    boolean inMI = localName.equals("MetadataInteger");
-
-                    for (int i = 0; i < len; i++) {
-                        attName = atts.getLocalName(i);
-
-                        int idx = node.getFieldIndex(attName);
-
-                        if (inMI && attName.equals("value")) {
-                            if (atts.getValue("name").equals("payload")) {
-                                decl = new VRMLFieldDeclaration(FieldConstants.FIELD,
-                                        "MFInt32", "value");
-                                idx = 0;
-                                int[] ival = fieldParser.MFInt32(atts.getValue(i));
-
-                                aholder.addAttributeWithAlgorithmData(
-                                        new QualifiedName("", "", atts.getLocalName(i), atts.getQName(i)),
-                                        null,
-                                        EncodingAlgorithmIndexes.INT,
-                                        ival);
-                                continue;
-                            }
-                        }
-
-                        if (idx > -1) {
-                            decl = node.getFieldDeclaration(idx);
-                        } else if (attName.equals("encoder")) {
-                            decl = new VRMLFieldDeclaration(FieldConstants.FIELD,
-                                    "SFInt32", "encoder");
-                            idx = 0;
-                        } else if (attName.equals("data")) {
-                            decl = new VRMLFieldDeclaration(FieldConstants.FIELD,
-                                    "MFInt32", "data");
-                            idx = 0;
-                            int[] ival = fieldParser.MFInt32(atts.getValue(i));
-
-                            aholder.addAttributeWithAlgorithmData(
-                                    new QualifiedName("", "", atts.getLocalName(i), atts.getQName(i)),
-                                    null,
-                                    EncodingAlgorithmIndexes.INT,
-                                    ival);
-                            continue;
-                        }
-
-                        VRMLFieldData field = null;
-                        if (idx != -1) {
-                            int accessType = decl.getAccessType();
-
-                            if (accessType == FieldConstants.EVENTIN
-                                    || accessType == FieldConstants.EVENTOUT) {
-
-//                            System.out.println("Skiping: " + atts.getLocalName(i));
-                                // Skip inputOnly and outputOnly DTD defaults
-                                continue;
-                            }
-
-                            field = node.getFieldValue(idx);
-                        }
-
-//System.out.println("att: " + atts.getLocalName(i) + " idx: " + idx);
-//System.out.println("att_val: " + atts.getValue(i) + ":");
-                        if (idx > -1 && method != METHOD_STRINGS) {
-                            encodeField(decl.getFieldType(), atts.getLocalName(i), atts.getQName(i), atts.getValue(i), aholder, field);
-                        } else {
-                            //System.out.println("Non X3D field: " + atts.getLocalName(i));
-                            aholder.addAttribute(new QualifiedName("", "", atts.getLocalName(i),
-                                    atts.getQName(i)), atts.getValue(i));
-
-                        }
-                    }
-                    parent.startElement(namespaceURI, localName, qualifiedName, aholder);
-                } catch (UnsupportedNodeException une) {
-                    // Any unknown nodes should be passed along anyway
-                    parent.startElement(namespaceURI, localName, qualifiedName, atts);
-                } catch (SAXException | InvalidFieldTypeException | InvalidFieldFormatException | InvalidFieldException e) {
-                    // Any unknown nodes should be passed along anyway
-                    System.err.println("***Unhandled element: " + localName);
-                    e.printStackTrace(System.err);
-                }
-            } else {
-                parent.startElement(namespaceURI, localName, qualifiedName, atts);
-            }
-
-            elementStack.push(localName);
-        }
-
-        @Override
-        public void endElement(String namespaceURI, String localName,
-                String qualifiedName) throws SAXException {
-
-            parent.endElement(namespaceURI, localName, qualifiedName);
-
-            elementStack.pop();
-        }
-
-        // Methods that pass data along unchanged:
-        @Override
-        public void startDocument() throws SAXException {
-            parent.startDocument();
-        }
-
-        @Override
-        public void startPrefixMapping(String prefix, String uri)
-                throws SAXException {
-            parent.startPrefixMapping(prefix, uri);
-        }
-
-        @Override
-        public void endPrefixMapping(String prefix)
-                throws SAXException {
-            parent.endPrefixMapping(prefix);
-        }
-
-        @Override
-        public void setDocumentLocator(Locator locator) {
-            parent.setDocumentLocator(locator);
-        }
-
-        @Override
-        public void endDocument() throws SAXException {
-            parent.endDocument();
-
-            String sval;
-            String sval2;
-
-            if (removeDefaults) {
-                System.out.println(defaults + " default fields removed");
-            }
-        }
-        int chars = 0;
-
-        @Override
-        public void characters(char[] text, int start, int length)
-                throws SAXException {
-
-            chars += length;
-            parent.characters(text, start, length);
-        }
-
-        @Override
-        public void ignorableWhitespace(char[] text, int start,
-                int length) throws SAXException {
-
-            // TODO: Should we get rid of this?
-//System.out.println("iws: " + length);
-            parent.ignorableWhitespace(text, start, length);
-        }
-
-        @Override
-        public void processingInstruction(String target, String data)
-                throws SAXException {
-            parent.processingInstruction(target, data);
-        }
-
-        @Override
-        public void skippedEntity(String name)
-                throws SAXException {
-            parent.skippedEntity(name);
-        }
-    }
-
-// Local Methods
-    public void encodeField(int fieldType, String name, String qName, String value, AttributesHolder aholder, VRMLFieldData field) {
-        float f;
-        boolean b;
-        float[] fval;
-        int[] ival;
-        int k;
-        double[] dval;
-        int clen;
-
-        fieldTypeStats[fieldType]++;
-        fieldTypeOrigSize[fieldType] += value.length();
-
-//System.out.println("encode: " + name + " qName: " + qName + " fieldType: " + fieldType + " value: " + value);
-        switch (fieldType) {
-            case FieldConstants.SFINT32:
-                if (removeDefaults && field != null) {
-                    k = fieldParser.SFInt32(value);
-                    if (k == field.intValue) {
-                        defaults++;
-                        break;
-                    }
-                }
-
-                aholder.addAttribute(new QualifiedName("", "", name,
-                        qName), value);
-                break;
-            case FieldConstants.SFTIME:
-                aholder.addAttribute(new QualifiedName("", "", name,
-                        qName), value);
-                break;
-            case FieldConstants.SFLONG:
-                aholder.addAttribute(new QualifiedName("", "", name,
-                        qName), value);
-                break;
-            case FieldConstants.SFDOUBLE:
-                aholder.addAttribute(new QualifiedName("", "", name,
-                        qName), value);
-                break;
-            case FieldConstants.SFBOOL:
-                if (removeDefaults && field != null) {
-                    b = fieldParser.SFBool(value);
-                    if (b == field.booleanValue) {
-                        defaults++;
-                        break;
-                    }
-                }
-
-                aholder.addAttribute(new QualifiedName("", "", name,
-                        qName), value);
-                break;
-            case FieldConstants.SFFLOAT:
-                if (removeDefaults && field != null) {
-                    f = fieldParser.SFFloat(value);
-                    if (Math.abs(f - field.floatValue) <= FLOAT_EPS) {
-                        defaults++;
-                        break;
-                    }
-                }
-
-                // TODO: Should we use FLOATS, or string?
-                aholder.addAttribute(new QualifiedName("", "", name,
-                        qName), value);
-                break;
-            case FieldConstants.SFSTRING:
-                if (removeDefaults && field != null) {
-                    if (value.equals(field.stringValue)) {
-                        defaults++;
-                        break;
-                    }
-                }
-
-                aholder.addAttribute(new QualifiedName("", "", name,
-                        qName), value);
-                break;
-            case FieldConstants.MFSTRING:
-                aholder.addAttribute(new QualifiedName("", "", name,
-                        qName), value);
-                break;
-            case FieldConstants.SFROTATION:
-                fval = fieldParser.SFRotation(value);
-
-                if (removeDefaults && field != null) {
-                    if (fval.length == field.floatArrayValues.length) {
-
-                        boolean equal = true;
-
-                        for (int j = 0; j < fval.length; j++) {
-
-                            if (Math.abs(fval[j] - field.floatArrayValues[j]) > FLOAT_EPS) {
-                                equal = false;
-
-                                break;
-                            }
-                        }
-
-                        if (equal) {
-                            defaults++;
-                            break;
-                        }
-                    }
-                }
-
-                if (fval != null && fval.length != 0) {
-                    aholder.addAttributeWithAlgorithmData(
-                            new QualifiedName("", "", name, qName),
-                            null,
-                            EncodingAlgorithmIndexes.FLOAT,
-                            fval);
-
-                    if (collectStats) {
-                        clen = BuiltInEncodingAlgorithmFactory.floatEncodingAlgorithm.getOctetLengthFromPrimitiveLength(fval.length);
-                        fieldTypeNewSize[FieldConstants.SFROTATION] += clen;
-                    }
-                }
-                break;
-            case FieldConstants.MFROTATION:
-                fval = fieldParser.MFRotation(value);
-                encodeFloatArray(value, fval, name, qName, aholder, fieldType);
-                break;
-            case FieldConstants.SFCOLORRGBA:
-                fval = fieldParser.SFColorRGBA(value);
-
-                if (removeDefaults && field != null) {
-                    if (fval.length == field.floatArrayValues.length) {
-
-                        boolean equal = true;
-
-                        for (int j = 0; j < fval.length; j++) {
-
-                            if (Math.abs(fval[j] - field.floatArrayValues[j]) > FLOAT_EPS) {
-                                equal = false;
-
-                                break;
-                            }
-                        }
-
-                        if (equal) {
-                            defaults++;
-                            break;
-                        }
-                    }
-                }
-
-                if (fval != null && fval.length != 0) {
-                    aholder.addAttributeWithAlgorithmData(
-                            new QualifiedName("", "", name, qName),
-                            null,
-                            EncodingAlgorithmIndexes.FLOAT,
-                            fval);
-                }
-                break;
-            case FieldConstants.MFCOLORRGBA:
-                fval = fieldParser.MFColorRGBA(value);
-                encodeFloatArray(value, fval, name, qName, aholder, fieldType);
-                break;
-            case FieldConstants.SFCOLOR:
-                fval = fieldParser.SFColor(value);
-
-                if (removeDefaults && field != null) {
-                    if (fval.length == field.floatArrayValues.length) {
-
-                        boolean equal = true;
-
-                        for (int j = 0; j < fval.length; j++) {
-
-                            if (Math.abs(fval[j] - field.floatArrayValues[j]) > FLOAT_EPS) {
-                                equal = false;
-
-                                break;
-                            }
-                        }
-
-                        if (equal) {
-                            defaults++;
-                            break;
-                        }
-                    }
-                }
-
-                if (fval != null && fval.length != 0) {
-                    aholder.addAttributeWithAlgorithmData(
-                            new QualifiedName("", "", name, qName),
-                            null,
-                            EncodingAlgorithmIndexes.FLOAT,
-                            fval);
-                }
-                break;
-            case FieldConstants.MFCOLOR:
-                fval = fieldParser.MFColor(value);
-                encodeFloatArray(value, fval, name, qName, aholder, fieldType);
-                break;
-            case FieldConstants.SFVEC2D:
-                dval = fieldParser.SFVec2d(value);
-                if (dval != null && dval.length != 0) {
-                    aholder.addAttributeWithAlgorithmData(
-                            new QualifiedName("", "", name, qName),
-                            null,
-                            EncodingAlgorithmIndexes.DOUBLE,
-                            dval);
-                }
-                break;
-            case FieldConstants.MFVEC2D:
-                dval = fieldParser.MFVec2d(value);
-                if (dval != null && dval.length != 0) {
-                    aholder.addAttributeWithAlgorithmData(
-                            new QualifiedName("", "", name, qName),
-                            null,
-                            EncodingAlgorithmIndexes.DOUBLE,
-                            dval);
-                }
-                break;
-            case FieldConstants.SFVEC3D:
-                dval = fieldParser.SFVec3d(value);
-                if (dval != null && dval.length != 0) {
-                    aholder.addAttributeWithAlgorithmData(
-                            new QualifiedName("", "", name, qName),
-                            null,
-                            EncodingAlgorithmIndexes.DOUBLE,
-                            dval);
-                }
-                break;
-            case FieldConstants.MFVEC3D:
-                dval = fieldParser.MFVec3d(value);
-                if (dval != null && dval.length != 0) {
-                    aholder.addAttributeWithAlgorithmData(
-                            new QualifiedName("", "", name, qName),
-                            null,
-                            EncodingAlgorithmIndexes.DOUBLE,
-                            dval);
-                }
-                break;
-            case FieldConstants.SFVEC2F:
-                fval = fieldParser.SFVec2f(value);
-
-                if (removeDefaults && field != null) {
-                    if (fval.length == field.floatArrayValues.length) {
-
-                        boolean equal = true;
-
-                        for (int j = 0; j < fval.length; j++) {
-
-                            if (Math.abs(fval[j] - field.floatArrayValues[j]) > FLOAT_EPS) {
-                                equal = false;
-
-                                break;
-                            }
-                        }
-
-                        if (equal) {
-                            defaults++;
-                            break;
-                        }
-                    }
-                }
-
-                if (fval != null && fval.length != 0) {
-                    aholder.addAttributeWithAlgorithmData(
-                            new QualifiedName("", "", name, qName),
-                            null,
-                            EncodingAlgorithmIndexes.FLOAT,
-                            fval);
-                }
-                break;
-            case FieldConstants.MFVEC2F:
-                fval = fieldParser.MFVec2f(value);
-                encodeFloatArray(value, fval, name, qName, aholder, fieldType);
-                break;
-            case FieldConstants.SFVEC3F:
-                fval = fieldParser.SFVec3f(value);
-
-                if (removeDefaults && field != null) {
-                    if (fval.length == field.floatArrayValues.length) {
-
-                        boolean equal = true;
-
-                        for (int j = 0; j < fval.length; j++) {
-
-                            if (Math.abs(fval[j] - field.floatArrayValues[j]) > FLOAT_EPS) {
-                                equal = false;
-
-                                break;
-                            }
-                        }
-
-                        if (equal) {
-                            defaults++;
-                            break;
-                        }
-                    }
-                }
-
-                if (fval != null && fval.length != 0) {
-                    aholder.addAttributeWithAlgorithmData(
-                            new QualifiedName("", "", name, qName),
-                            null,
-                            EncodingAlgorithmIndexes.FLOAT,
-                            fval);
-                    if (collectStats) {
-                        clen = BuiltInEncodingAlgorithmFactory.floatEncodingAlgorithm.getOctetLengthFromPrimitiveLength(fval.length);
-                        fieldTypeNewSize[FieldConstants.SFVEC3F] += clen;
-                    }
-                }
-                break;
-            case FieldConstants.MFVEC3F:
-                fval = fieldParser.MFVec3f(value);
-
-                encodeFloatArray(value, fval, name, qName, aholder, fieldType);
-
-                break;
-            case FieldConstants.SFVEC4F:
-                fval = fieldParser.SFVec4f(value);
-                if (fval != null && fval.length != 0) {
-                    aholder.addAttributeWithAlgorithmData(
-                            new QualifiedName("", "", name, qName),
-                            null,
-                            EncodingAlgorithmIndexes.FLOAT,
-                            fval);
-                }
-                break;
-            case FieldConstants.MFVEC4F:
-                fval = fieldParser.MFVec4f(value);
-                encodeFloatArray(value, fval, name, qName, aholder, fieldType);
-                break;
-            case FieldConstants.MFFLOAT:
-                fval = fieldParser.MFFloat(value);
-                encodeFloatArray(value, fval, name, qName, aholder, FieldConstants.MFFLOAT);
-                break;
-            case FieldConstants.MFDOUBLE:
-                dval = fieldParser.MFDouble(value);
-                if (dval != null && dval.length != 0) {
-                    aholder.addAttributeWithAlgorithmData(
-                            new QualifiedName("", "", name, qName),
-                            null,
-                            EncodingAlgorithmIndexes.DOUBLE,
-                            dval);
-                }
-                //encodeFloatArray(value, fval, name, qName, aholder, FieldConstants.MFFLOAT);
-                break;
-            case FieldConstants.SFMATRIX3F:
-                fval = fieldParser.SFMatrix3f(value);
-
-                if (removeDefaults && field != null) {
-                    if (fval.length == field.floatArrayValues.length) {
-
-                        boolean equal = true;
-
-                        for (int j = 0; j < fval.length; j++) {
-
-                            if (Math.abs(fval[j] - field.floatArrayValues[j]) > FLOAT_EPS) {
-                                equal = false;
-
-                                break;
-                            }
-                        }
-
-                        if (equal) {
-                            defaults++;
-                            break;
-                        }
-                    }
-                }
-
-                if (fval != null && fval.length != 0) {
-                    switch (method) {
-                        case METHOD_SMALLEST_LOSSY:
-                            aholder.addAttributeWithAlgorithmData(
-                                    new QualifiedName("", "", name, qName),
-                                    QuantizedzlibFloatArrayAlgorithm.ALGORITHM_URI,
-                                    X3DBinaryConstants.QUANTIZED_ZLIB_FLOAT_ARRAY_ALGORITHM_ID,
-                                    fval);
-                            break;
-                        default:
-                            aholder.addAttributeWithAlgorithmData(
-                                    new QualifiedName("", "", name, qName),
-                                    null,
-                                    EncodingAlgorithmIndexes.FLOAT,
-                                    fval);
-                            break;
-                    }
-                }
-                break;
-            case FieldConstants.MFMATRIX3F:
-                fval = fieldParser.MFMatrix3f(value);
-                encodeFloatArray(value, fval, name, qName, aholder, fieldType);
-                break;
-            case FieldConstants.SFMATRIX4F:
-                fval = fieldParser.SFMatrix4f(value);
-
-                if (removeDefaults && field != null) {
-                    if (fval.length == field.floatArrayValues.length) {
-
-                        boolean equal = true;
-
-                        for (int j = 0; j < fval.length; j++) {
-
-                            if (Math.abs(fval[j] - field.floatArrayValues[j]) > FLOAT_EPS) {
-                                equal = false;
-
-                                break;
-                            }
-                        }
-
-                        if (equal) {
-                            defaults++;
-                            break;
-                        }
-                    }
-                }
-
-                encodeFloatArray(value, fval, name, qName, aholder, fieldType);
-                break;
-            case FieldConstants.MFMATRIX4F:
-                fval = fieldParser.MFMatrix4f(value);
-                encodeFloatArray(value, fval, name, qName, aholder, fieldType);
-                break;
-            case FieldConstants.SFMATRIX3D:
-                dval = fieldParser.SFMatrix3d(value);
-                if (dval != null && dval.length != 0) {
-                    aholder.addAttributeWithAlgorithmData(
-                            new QualifiedName("", "", name, qName),
-                            null,
-                            EncodingAlgorithmIndexes.DOUBLE,
-                            dval);
-                }
-                break;
-            case FieldConstants.MFTIME:
-                dval = fieldParser.MFTime(value);
-                if (dval != null && dval.length != 0) {
-                    aholder.addAttributeWithAlgorithmData(
-                            new QualifiedName("", "", name, qName),
-                            null,
-                            EncodingAlgorithmIndexes.DOUBLE,
-                            dval);
-                }
-                break;
-            case FieldConstants.MFMATRIX3D:
-                dval = fieldParser.MFMatrix3d(value);
-                if (dval != null && dval.length != 0) {
-                    aholder.addAttributeWithAlgorithmData(
-                            new QualifiedName("", "", name, qName),
-                            null,
-                            EncodingAlgorithmIndexes.DOUBLE,
-                            dval);
-                }
-                break;
-            case FieldConstants.SFMATRIX4D:
-                dval = fieldParser.SFMatrix4d(value);
-                if (dval != null && dval.length != 0) {
-                    aholder.addAttributeWithAlgorithmData(
-                            new QualifiedName("", "", name, qName),
-                            null,
-                            EncodingAlgorithmIndexes.DOUBLE,
-                            dval);
-                }
-                break;
-            case FieldConstants.MFMATRIX4D:
-                dval = fieldParser.MFMatrix4d(value);
-                if (dval != null && dval.length != 0) {
-                    aholder.addAttributeWithAlgorithmData(
-                            new QualifiedName("", "", name, qName),
-                            null,
-                            EncodingAlgorithmIndexes.DOUBLE,
-                            dval);
-                }
-                break;
-            case FieldConstants.SFIMAGE:
-                ival = fieldParser.SFImage(value);
-                if (ival != null && ival.length != 0) {
-                    aholder.addAttributeWithAlgorithmData(
-                            new QualifiedName("", "", name, qName),
-                            null,
-                            EncodingAlgorithmIndexes.INT,
-                            ival);
-                }
-                break;
-            case FieldConstants.MFIMAGE:
-                ival = fieldParser.MFImage(value);
-                if (ival != null && ival.length != 0) {
-                    aholder.addAttributeWithAlgorithmData(
-                            new QualifiedName("", "", name, qName),
-                            null,
-                            EncodingAlgorithmIndexes.INT,
-                            ival);
-                }
-                break;
-            case FieldConstants.MFINT32:
-                ival = fieldParser.MFInt32(value);
-
-                System.out.println("BinarySerializer " + name + " " + java.util.Arrays.toString(ival));
-
-                aholder.addAttributeWithAlgorithmData(
-                        new QualifiedName("", "", name, qName),
-                        DeltazlibIntArrayAlgorithm.ALGORITHM_URI,
-                        X3DBinaryConstants.DELTA_ZLIB_INT_ARRAY_ALGORITHM_ID,
-                        ival);
-
-                break;
-            default:
-                System.out.println("Unhandled field: " + name);
-
-        }
-    }
-
-    /**
-     * Encode float array data. This is optimized for MF* types, not types like
-     * SFVec3f.
-     *
-     * @param attVal The field value
-     * @param fval The parsed float array value
-     * @param atts The current attributes array
-     * @param aholder The current attributes holder
-     * @param ftype The X3D field type, defined in FieldConstants
-     */
-    private void encodeFloatArray(String attVal, float[] fval, String localName, String qName, AttributesHolder aholder,
-            int ftype) {
-
-        int clen;
-
-        if (fval != null && fval.length != 0) {
-            switch (method) {
-                case METHOD_SMALLEST_LOSSY:
-                    aholder.addAttributeWithAlgorithmData(
-                            new QualifiedName("", "", localName, qName),
-                            QuantizedzlibFloatArrayAlgorithm.ALGORITHM_URI,
-                            X3DBinaryConstants.QUANTIZED_ZLIB_FLOAT_ARRAY_ALGORITHM_ID,
-                            fval);
-                    break;
-                case METHOD_SMALLEST_NONLOSSY:
-                    aholder.addAttributeWithAlgorithmData(
-                            new QualifiedName("", "", localName, qName),
-                            QuantizedzlibFloatArrayAlgorithm.ALGORITHM_URI,
-                            X3DBinaryConstants.QUANTIZED_ZLIB_FLOAT_ARRAY_ALGORITHM_ID,
-                            fval);
-                    break;
-                default:
-                    clen = BuiltInEncodingAlgorithmFactory.floatEncodingAlgorithm.getOctetLengthFromPrimitiveLength(fval.length);
-
-                    if (clen <= attVal.length()) {
-                        aholder.addAttributeWithAlgorithmData(
-                                new QualifiedName("", "", localName, qName),
-                                null,
-                                EncodingAlgorithmIndexes.FLOAT,
-                                fval);
-                        if (collectStats) {
-                            fieldTypeNewSize[ftype] += clen;
-                        }
-                    } else {
-                        aholder.addAttribute(new QualifiedName("", "", localName,
-                                qName), attVal);
-                        if (collectStats) {
-                            fieldTypeNewSize[ftype] += attVal.length();
-                        }
-                    }
-                    break;
-            }
-        }
-    }
-}
+/*****************************************************************************
+ *                    Yumetech, Inc Copyright (c) 2001-2006
+ *                               Java Source
+ *
+ * This source is licensed under the BSD license.
+ * Please read docs/BSD.txt for the text of the license.
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.export;
+
+// External imports
+import com.sun.xml.fastinfoset.algorithm.BuiltInEncodingAlgorithmFactory;
+import com.sun.xml.fastinfoset.QualifiedName;
+import com.sun.xml.fastinfoset.sax.AttributesHolder;
+import com.sun.xml.fastinfoset.sax.SAXDocumentSerializer;
+import com.sun.xml.fastinfoset.vocab.SerializerVocabulary;
+
+import java.io.*;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.transform.*;
+import javax.xml.parsers.*;
+import javax.xml.transform.sax.SAXResult;
+
+import org.jvnet.fastinfoset.EncodingAlgorithm;
+import org.jvnet.fastinfoset.EncodingAlgorithmIndexes;
+
+import org.xml.sax.*;
+
+// Local imports
+import org.web3d.util.SimpleStack;
+import org.web3d.vrml.lang.*;
+import org.web3d.vrml.renderer.DefaultNodeFactory;
+import org.web3d.parser.x3d.X3DFieldReader;
+import org.web3d.parser.x3d.*;
+import org.web3d.vrml.nodes.*;
+import org.web3d.x3d.jaxp.X3DEntityResolver;
+import org.web3d.vrml.renderer.CRProtoCreator;
+import org.web3d.vrml.renderer.norender.NRProtoCreator;
+import org.web3d.vrml.renderer.CRVRMLScene;
+
+/**
+ *  Serializes an X3D XML encoded document into an X3D binary document.
+ *
+ * TODO: Stats collection for non builtins isn't written
+ * TODO: proto and script fields are encoded as strings
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.11 $
+ */
+public class X3DBinarySerializer {
+
+    // Encode files for fastest parsing
+    public static final int METHOD_FASTEST_PARSING = 0;
+
+    // Encode files for smallest size using non lossy techniques
+    public static final int METHOD_SMALLEST_NONLOSSY = 1;
+
+    // Encode files for smallest size using lossy techniques
+    public static final int METHOD_SMALLEST_LOSSY = 2;
+
+    // Encode files using Strings */
+    public static final int METHOD_STRINGS = 3;
+
+    // Smallest float difference for equality
+    private static final float FLOAT_EPS = 0.0000009f;
+
+    // Largest acceptable error for float quantization
+    private static float PARAM_FLOAT_LOSSY = 0.001f;
+
+    // Usage docs
+    private static final String USAGE = "Usage:  X3DSerializer [options] <input> <output>\n" +
+                                        "options:  -method [fastest, smallest, lossy]\n" +
+                                        "          -quantizeParam n\n" +
+                                        "          -savedefaults";
+
+    private Transformer _transformer;
+    private DocumentBuilder _docBuilder;
+    private Source _source = null;
+    private SAXResult _result = null;
+
+    protected static final String VALIDATION_FEATURE_ID = "http://xml.org/sax/features/validation";
+    protected static final String SCHEMA_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/schema";
+    protected static final String LOAD_DTD_ID = "http://apache.org/xml/features/nonvalidating/load-dtd-grammar";
+
+    /** The node factory used to create real node instances */
+    private VRMLNodeFactory nodeFactory;
+
+    /** Cache of nodes used for type information. NodeName --> Node*/
+    private Map<String, VRMLNodeType> nodeCache;
+
+    /** A field parser */
+    private X3DFieldReader fieldParser;
+
+    private int[] fieldTypeStats;
+    private int[] fieldTypeOrigSize;
+    private int[] fieldTypeNewSize;
+    private Map<Integer, String> fieldTypeMap;
+    private boolean collectStats = true;
+
+    /** What method should we use to compress */
+    private int method;
+
+    /** Should we remove defaults */
+    private boolean removeDefaults;
+
+    /** How many default values where removed */
+    private int defaults;
+
+    /** Single level proto map  */
+    private Map<String, VRMLFieldDeclaration> protoMap;
+
+    /** The creator used to instantiate protos */
+    protected CRProtoCreator protoCreator;
+
+    /** The spec major version to use */
+    private int majorVersion;
+
+    /** The spec minor version to use */
+    private int minorVersion;
+
+    /** Root node used for proto creation */
+    protected VRMLWorldRootNodeType root;
+
+    /** A Stack of element names */
+    private SimpleStack elementStack;
+
+    /**
+     * Creates a new instance of X3DSerializer
+     *
+     * @param compMethod What method to use
+     * @param rd Should we remove defaults
+     * @param lossParam maximum loss for lossy compression
+     */
+    public X3DBinarySerializer(int compMethod, boolean rd, float lossParam) {
+        method = compMethod;
+        removeDefaults = rd;
+        PARAM_FLOAT_LOSSY = lossParam;
+
+        elementStack = new SimpleStack();
+        elementStack.push("WorldRoot");
+
+        try {
+            // get a transformer and document builder
+            _transformer = TransformerFactory.newInstance().newTransformer();
+            _docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+        } catch (TransformerConfigurationException | ParserConfigurationException e) {
+            e.printStackTrace(System.err);
+        }
+
+        majorVersion = 3;
+        minorVersion = 1;
+
+        nodeFactory = DefaultNodeFactory.newInstance(DefaultNodeFactory.NULL_RENDERER);
+        nodeFactory.setSpecVersion(majorVersion, minorVersion);
+        nodeFactory.setProfile("Immersive");
+
+        nodeCache = new HashMap<>();
+
+        fieldParser = new X3DFieldReader();
+        fieldParser.setCaseSensitive(false);
+
+        fieldTypeStats = new int[43];
+        fieldTypeOrigSize = new int[43];
+        fieldTypeNewSize = new int[43];
+        fieldTypeMap = new HashMap<>();
+        fieldTypeMap.put(FieldConstants.SFINT32, "SFInt32    ");
+        fieldTypeMap.put(FieldConstants.MFINT32, "MFInt32    ");
+        fieldTypeMap.put(FieldConstants.SFFLOAT, "SFFloat    ");
+        fieldTypeMap.put(FieldConstants.MFFLOAT, "MFFloat    ");
+        fieldTypeMap.put(FieldConstants.SFDOUBLE, "SFDouble   ");
+        fieldTypeMap.put(FieldConstants.MFDOUBLE, "MFDouble   ");
+        fieldTypeMap.put(FieldConstants.SFLONG, "SFLong     ");
+        fieldTypeMap.put(FieldConstants.MFLONG, "MFLong     ");
+        fieldTypeMap.put(FieldConstants.SFBOOL, "SFBool     ");
+        fieldTypeMap.put(FieldConstants.MFBOOL, "MFBool     ");
+        fieldTypeMap.put(FieldConstants.SFVEC2F, "SFVec2f    ");
+        fieldTypeMap.put(FieldConstants.MFVEC2F, "MFVec2f    ");
+        fieldTypeMap.put(FieldConstants.SFVEC2D, "SFVec2d    ");
+        fieldTypeMap.put(FieldConstants.MFVEC2D, "MFVec2d    ");
+        fieldTypeMap.put(FieldConstants.SFVEC3F, "SFVec3f    ");
+        fieldTypeMap.put(FieldConstants.MFVEC3F, "MFVec3f    ");
+        fieldTypeMap.put(FieldConstants.SFVEC3D, "SFVec3d    ");
+        fieldTypeMap.put(FieldConstants.MFVEC3D, "MFVec3d    ");
+        fieldTypeMap.put(FieldConstants.SFVEC4F, "SFVec4f    ");
+        fieldTypeMap.put(FieldConstants.MFVEC4F, "MFVec4f    ");
+        fieldTypeMap.put(FieldConstants.SFVEC4D, "SFVec4d    ");
+        fieldTypeMap.put(FieldConstants.MFVEC4D, "MFVec4d    ");
+        fieldTypeMap.put(FieldConstants.SFIMAGE, "SFImage    ");
+        fieldTypeMap.put(FieldConstants.MFIMAGE, "MFImage    ");
+        fieldTypeMap.put(FieldConstants.SFTIME, "SFTime     ");
+        fieldTypeMap.put(FieldConstants.MFTIME, "MFTime     ");
+        fieldTypeMap.put(FieldConstants.SFNODE, "SFNode     ");
+        fieldTypeMap.put(FieldConstants.MFNODE, "MFNode     ");
+        fieldTypeMap.put(FieldConstants.SFSTRING, "SFString   ");
+        fieldTypeMap.put(FieldConstants.MFSTRING, "MFString   ");
+        fieldTypeMap.put(FieldConstants.SFROTATION, "SFRotation ");
+        fieldTypeMap.put(FieldConstants.MFROTATION, "MFRotation ");
+        fieldTypeMap.put(FieldConstants.SFCOLOR, "SFColor    ");
+        fieldTypeMap.put(FieldConstants.MFCOLOR, "MFColor    ");
+        fieldTypeMap.put(FieldConstants.SFCOLORRGBA, "SFColorRGBA");
+        fieldTypeMap.put(FieldConstants.MFCOLORRGBA, "MFColorRGBA");
+        fieldTypeMap.put(FieldConstants.SFMATRIX3F, "SFMatrix3f ");
+        fieldTypeMap.put(FieldConstants.MFMATRIX3F, "MFMatrix3f ");
+        fieldTypeMap.put(FieldConstants.SFMATRIX3D, "SFMatrix3d ");
+        fieldTypeMap.put(FieldConstants.MFMATRIX3D, "MFMatrix3d ");
+        fieldTypeMap.put(FieldConstants.SFMATRIX4F, "SFMatrix4f ");
+        fieldTypeMap.put(FieldConstants.MFMATRIX4F, "MFMatrix4f ");
+        fieldTypeMap.put(FieldConstants.SFMATRIX4D, "SFMatrix4d ");
+        fieldTypeMap.put(FieldConstants.MFMATRIX4D, "MFMatrix4d ");
+
+        protoMap = new HashMap<>();
+    }
+
+    /**
+     * Set the map of node names to prototype decl. This will only have the top
+     * level protos. Nested proto's will not have field type information for
+     * encoding.
+     *
+     * @param protoMap The top level proto map
+     */
+    public void setProtoMap(Map<String, VRMLFieldDeclaration> protoMap) {
+        this.protoMap = protoMap;
+
+        protoCreator = new NRProtoCreator(nodeFactory,
+                "",
+                majorVersion,
+                minorVersion);
+
+        root =
+                (VRMLWorldRootNodeType) nodeFactory.createVRMLNode("WorldRoot",
+                false);
+
+        CRVRMLScene scene = new CRVRMLScene(majorVersion, minorVersion);
+        scene.setNodeFactory(nodeFactory);
+        WriteableSceneMetaData metaData = new WriteableSceneMetaData("3.0",
+                true,
+                SceneMetaData.BINARY_ENCODING);
+
+        scene.setMetaData(metaData);
+
+        root.setContainedScene(scene);
+
+    }
+
+    public void writeFiltered(InputStream input, OutputStream output) {
+
+        System.out.println("Code used****");
+        try {
+
+            try (OutputStream fos = output) {
+                SAXDocumentSerializer serializer = new SAXDocumentSerializer();
+                //  TODO: We'd like to catch most DEF name limits
+                serializer.setMaxAttributeValueSize(32);
+                serializer.setOutputStream(fos);
+                SerializerVocabulary initialVocabulary = new SerializerVocabulary();
+                // TODO: Does this do a copy?
+                initialVocabulary.setExternalVocabulary(X3DBinaryConstants.EXTERNAL_VOCABULARY_URI_STRING,
+                        X3DBinaryVocabulary.serializerVoc, false);
+                serializer.setVocabulary(initialVocabulary);
+                Map<String, EncodingAlgorithm> algorithms = new HashMap<>();
+                algorithms.put(ByteEncodingAlgorithm.ALGORITHM_URI, new ByteEncodingAlgorithm());
+                algorithms.put(DeltazlibIntArrayAlgorithm.ALGORITHM_URI, new DeltazlibIntArrayAlgorithm());
+                if (method == METHOD_SMALLEST_LOSSY) {
+                    // Only global control available currently
+                    algorithms.put(QuantizedzlibFloatArrayAlgorithm.ALGORITHM_URI,
+                            new QuantizedzlibFloatArrayAlgorithm(PARAM_FLOAT_LOSSY));
+                } else {
+                    // Default is no loss
+                    algorithms.put(QuantizedzlibFloatArrayAlgorithm.ALGORITHM_URI, new QuantizedzlibFloatArrayAlgorithm());
+                }   serializer.setRegisteredEncodingAlgorithms(algorithms);
+                // Obtain an instance of an XMLReader implementation
+                // from a system property
+                XMLReader parser = javax.xml.parsers.SAXParserFactory.newInstance().newSAXParser().getXMLReader();
+                parser.setFeature(VALIDATION_FEATURE_ID, false);
+                X3DEntityResolver resolver = new X3DEntityResolver();
+                parser.setEntityResolver(resolver);
+
+                // Create a new instance and register it with the parser
+                ContentHandler contentHandler = new X3DFilter(serializer);
+                parser.setContentHandler(contentHandler);
+                InputSource is = new InputSource(input);
+                parser.parse(is);
+            }
+        } catch (SAXException | IOException | ParserConfigurationException e) {
+            e.printStackTrace(System.err);
+        }
+    }
+
+    public class X3DFilter implements ContentHandler {
+
+        private ContentHandler parent;
+
+        public X3DFilter(ContentHandler parent) {
+            this.parent = parent;
+        }
+
+        @Override
+        public void startElement(String namespaceURI, String localName,
+                String qualifiedName, Attributes atts) throws SAXException {
+
+            int len = atts.getLength();
+
+            if (atts.getLength() > 0) {
+
+                if (localName.equals("fieldValue")) {
+                    AttributesHolder aholder = new AttributesHolder();
+
+                    String fieldName = atts.getValue("name");
+                    aholder.addAttribute(new QualifiedName("", "", "name",
+                            "name"), fieldName);
+
+//                System.out.println("Looking for: " + (String)elementStack.peek() + "." + fieldName);
+                    VRMLFieldDeclaration decl = protoMap.get(elementStack.peek() + "." + fieldName);
+
+                    if (decl != null) {
+                        encodeField(decl.getFieldType(), "value", "value", atts.getValue("value"), aholder, null);
+                    } else {
+                        aholder.addAttribute(new QualifiedName("", "", "value",
+                                "value"), atts.getValue("value"));
+                    }
+
+                    parent.startElement(namespaceURI, localName, qualifiedName, aholder);
+
+                    elementStack.push("fieldValue");
+                    return;
+                }
+
+                try {
+                    VRMLNodeType node;
+
+                    node = nodeCache.get(localName);
+
+                    if (localName.equals("ProtoInstance")) {
+                        parent.startElement(namespaceURI, localName, qualifiedName, atts);
+                        elementStack.push(atts.getValue("name"));
+
+                        return;
+                    }
+
+                    if (node == null) {
+                        node = (VRMLNodeType) nodeFactory.createVRMLNode(localName, false);
+                        nodeCache.put(localName, node);
+                    }
+
+                    AttributesHolder aholder = new AttributesHolder();
+                    VRMLFieldDeclaration decl = null;
+                    String attName;
+
+                    boolean inMI = localName.equals("MetadataInteger");
+
+                    for (int i = 0; i < len; i++) {
+                        attName = atts.getLocalName(i);
+
+                        int idx = node.getFieldIndex(attName);
+
+                        if (inMI && attName.equals("value")) {
+                            if (atts.getValue("name").equals("payload")) {
+                                decl = new VRMLFieldDeclaration(FieldConstants.FIELD,
+                                        "MFInt32", "value");
+                                idx = 0;
+                                int[] ival = fieldParser.MFInt32(atts.getValue(i));
+
+                                aholder.addAttributeWithAlgorithmData(
+                                        new QualifiedName("", "", atts.getLocalName(i), atts.getQName(i)),
+                                        null,
+                                        EncodingAlgorithmIndexes.INT,
+                                        ival);
+                                continue;
+                            }
+                        }
+
+                        if (idx > -1) {
+                            decl = node.getFieldDeclaration(idx);
+                        } else if (attName.equals("encoder")) {
+                            decl = new VRMLFieldDeclaration(FieldConstants.FIELD,
+                                    "SFInt32", "encoder");
+                            idx = 0;
+                        } else if (attName.equals("data")) {
+                            decl = new VRMLFieldDeclaration(FieldConstants.FIELD,
+                                    "MFInt32", "data");
+                            idx = 0;
+                            int[] ival = fieldParser.MFInt32(atts.getValue(i));
+
+                            aholder.addAttributeWithAlgorithmData(
+                                    new QualifiedName("", "", atts.getLocalName(i), atts.getQName(i)),
+                                    null,
+                                    EncodingAlgorithmIndexes.INT,
+                                    ival);
+                            continue;
+                        }
+
+                        VRMLFieldData field = null;
+                        if (idx != -1) {
+                            int accessType = decl.getAccessType();
+
+                            if (accessType == FieldConstants.EVENTIN
+                                    || accessType == FieldConstants.EVENTOUT) {
+
+//                            System.out.println("Skiping: " + atts.getLocalName(i));
+                                // Skip inputOnly and outputOnly DTD defaults
+                                continue;
+                            }
+
+                            field = node.getFieldValue(idx);
+                        }
+
+//System.out.println("att: " + atts.getLocalName(i) + " idx: " + idx);
+//System.out.println("att_val: " + atts.getValue(i) + ":");
+                        if (idx > -1 && method != METHOD_STRINGS) {
+                            encodeField(decl.getFieldType(), atts.getLocalName(i), atts.getQName(i), atts.getValue(i), aholder, field);
+                        } else {
+                            //System.out.println("Non X3D field: " + atts.getLocalName(i));
+                            aholder.addAttribute(new QualifiedName("", "", atts.getLocalName(i),
+                                    atts.getQName(i)), atts.getValue(i));
+
+                        }
+                    }
+                    parent.startElement(namespaceURI, localName, qualifiedName, aholder);
+                } catch (UnsupportedNodeException une) {
+                    // Any unknown nodes should be passed along anyway
+                    parent.startElement(namespaceURI, localName, qualifiedName, atts);
+                } catch (SAXException | InvalidFieldTypeException | InvalidFieldFormatException | InvalidFieldException e) {
+                    // Any unknown nodes should be passed along anyway
+                    System.err.println("***Unhandled element: " + localName);
+                    e.printStackTrace(System.err);
+                }
+            } else {
+                parent.startElement(namespaceURI, localName, qualifiedName, atts);
+            }
+
+            elementStack.push(localName);
+        }
+
+        @Override
+        public void endElement(String namespaceURI, String localName,
+                String qualifiedName) throws SAXException {
+
+            parent.endElement(namespaceURI, localName, qualifiedName);
+
+            elementStack.pop();
+        }
+
+        // Methods that pass data along unchanged:
+        @Override
+        public void startDocument() throws SAXException {
+            parent.startDocument();
+        }
+
+        @Override
+        public void startPrefixMapping(String prefix, String uri)
+                throws SAXException {
+            parent.startPrefixMapping(prefix, uri);
+        }
+
+        @Override
+        public void endPrefixMapping(String prefix)
+                throws SAXException {
+            parent.endPrefixMapping(prefix);
+        }
+
+        @Override
+        public void setDocumentLocator(Locator locator) {
+            parent.setDocumentLocator(locator);
+        }
+
+        @Override
+        public void endDocument() throws SAXException {
+            parent.endDocument();
+
+            String sval;
+            String sval2;
+
+            if (removeDefaults) {
+                System.out.println(defaults + " default fields removed");
+            }
+        }
+        int chars = 0;
+
+        @Override
+        public void characters(char[] text, int start, int length)
+                throws SAXException {
+
+            chars += length;
+            parent.characters(text, start, length);
+        }
+
+        @Override
+        public void ignorableWhitespace(char[] text, int start,
+                int length) throws SAXException {
+
+            // TODO: Should we get rid of this?
+//System.out.println("iws: " + length);
+            parent.ignorableWhitespace(text, start, length);
+        }
+
+        @Override
+        public void processingInstruction(String target, String data)
+                throws SAXException {
+            parent.processingInstruction(target, data);
+        }
+
+        @Override
+        public void skippedEntity(String name)
+                throws SAXException {
+            parent.skippedEntity(name);
+        }
+    }
+
+// Local Methods
+    public void encodeField(int fieldType, String name, String qName, String value, AttributesHolder aholder, VRMLFieldData field) {
+        float f;
+        boolean b;
+        float[] fval;
+        int[] ival;
+        int k;
+        double[] dval;
+        int clen;
+
+        fieldTypeStats[fieldType]++;
+        fieldTypeOrigSize[fieldType] += value.length();
+
+//System.out.println("encode: " + name + " qName: " + qName + " fieldType: " + fieldType + " value: " + value);
+        switch (fieldType) {
+            case FieldConstants.SFINT32:
+                if (removeDefaults && field != null) {
+                    k = fieldParser.SFInt32(value);
+                    if (k == field.intValue) {
+                        defaults++;
+                        break;
+                    }
+                }
+
+                aholder.addAttribute(new QualifiedName("", "", name,
+                        qName), value);
+                break;
+            case FieldConstants.SFTIME:
+                aholder.addAttribute(new QualifiedName("", "", name,
+                        qName), value);
+                break;
+            case FieldConstants.SFLONG:
+                aholder.addAttribute(new QualifiedName("", "", name,
+                        qName), value);
+                break;
+            case FieldConstants.SFDOUBLE:
+                aholder.addAttribute(new QualifiedName("", "", name,
+                        qName), value);
+                break;
+            case FieldConstants.SFBOOL:
+                if (removeDefaults && field != null) {
+                    b = fieldParser.SFBool(value);
+                    if (b == field.booleanValue) {
+                        defaults++;
+                        break;
+                    }
+                }
+
+                aholder.addAttribute(new QualifiedName("", "", name,
+                        qName), value);
+                break;
+            case FieldConstants.SFFLOAT:
+                if (removeDefaults && field != null) {
+                    f = fieldParser.SFFloat(value);
+                    if (Math.abs(f - field.floatValue) <= FLOAT_EPS) {
+                        defaults++;
+                        break;
+                    }
+                }
+
+                // TODO: Should we use FLOATS, or string?
+                aholder.addAttribute(new QualifiedName("", "", name,
+                        qName), value);
+                break;
+            case FieldConstants.SFSTRING:
+                if (removeDefaults && field != null) {
+                    if (value.equals(field.stringValue)) {
+                        defaults++;
+                        break;
+                    }
+                }
+
+                aholder.addAttribute(new QualifiedName("", "", name,
+                        qName), value);
+                break;
+            case FieldConstants.MFSTRING:
+                aholder.addAttribute(new QualifiedName("", "", name,
+                        qName), value);
+                break;
+            case FieldConstants.SFROTATION:
+                fval = fieldParser.SFRotation(value);
+
+                if (removeDefaults && field != null) {
+                    if (fval.length == field.floatArrayValues.length) {
+
+                        boolean equal = true;
+
+                        for (int j = 0; j < fval.length; j++) {
+
+                            if (Math.abs(fval[j] - field.floatArrayValues[j]) > FLOAT_EPS) {
+                                equal = false;
+
+                                break;
+                            }
+                        }
+
+                        if (equal) {
+                            defaults++;
+                            break;
+                        }
+                    }
+                }
+
+                if (fval != null && fval.length != 0) {
+                    aholder.addAttributeWithAlgorithmData(
+                            new QualifiedName("", "", name, qName),
+                            null,
+                            EncodingAlgorithmIndexes.FLOAT,
+                            fval);
+
+                    if (collectStats) {
+                        clen = BuiltInEncodingAlgorithmFactory.floatEncodingAlgorithm.getOctetLengthFromPrimitiveLength(fval.length);
+                        fieldTypeNewSize[FieldConstants.SFROTATION] += clen;
+                    }
+                }
+                break;
+            case FieldConstants.MFROTATION:
+                fval = fieldParser.MFRotation(value);
+                encodeFloatArray(value, fval, name, qName, aholder, fieldType);
+                break;
+            case FieldConstants.SFCOLORRGBA:
+                fval = fieldParser.SFColorRGBA(value);
+
+                if (removeDefaults && field != null) {
+                    if (fval.length == field.floatArrayValues.length) {
+
+                        boolean equal = true;
+
+                        for (int j = 0; j < fval.length; j++) {
+
+                            if (Math.abs(fval[j] - field.floatArrayValues[j]) > FLOAT_EPS) {
+                                equal = false;
+
+                                break;
+                            }
+                        }
+
+                        if (equal) {
+                            defaults++;
+                            break;
+                        }
+                    }
+                }
+
+                if (fval != null && fval.length != 0) {
+                    aholder.addAttributeWithAlgorithmData(
+                            new QualifiedName("", "", name, qName),
+                            null,
+                            EncodingAlgorithmIndexes.FLOAT,
+                            fval);
+                }
+                break;
+            case FieldConstants.MFCOLORRGBA:
+                fval = fieldParser.MFColorRGBA(value);
+                encodeFloatArray(value, fval, name, qName, aholder, fieldType);
+                break;
+            case FieldConstants.SFCOLOR:
+                fval = fieldParser.SFColor(value);
+
+                if (removeDefaults && field != null) {
+                    if (fval.length == field.floatArrayValues.length) {
+
+                        boolean equal = true;
+
+                        for (int j = 0; j < fval.length; j++) {
+
+                            if (Math.abs(fval[j] - field.floatArrayValues[j]) > FLOAT_EPS) {
+                                equal = false;
+
+                                break;
+                            }
+                        }
+
+                        if (equal) {
+                            defaults++;
+                            break;
+                        }
+                    }
+                }
+
+                if (fval != null && fval.length != 0) {
+                    aholder.addAttributeWithAlgorithmData(
+                            new QualifiedName("", "", name, qName),
+                            null,
+                            EncodingAlgorithmIndexes.FLOAT,
+                            fval);
+                }
+                break;
+            case FieldConstants.MFCOLOR:
+                fval = fieldParser.MFColor(value);
+                encodeFloatArray(value, fval, name, qName, aholder, fieldType);
+                break;
+            case FieldConstants.SFVEC2D:
+                dval = fieldParser.SFVec2d(value);
+                if (dval != null && dval.length != 0) {
+                    aholder.addAttributeWithAlgorithmData(
+                            new QualifiedName("", "", name, qName),
+                            null,
+                            EncodingAlgorithmIndexes.DOUBLE,
+                            dval);
+                }
+                break;
+            case FieldConstants.MFVEC2D:
+                dval = fieldParser.MFVec2d(value);
+                if (dval != null && dval.length != 0) {
+                    aholder.addAttributeWithAlgorithmData(
+                            new QualifiedName("", "", name, qName),
+                            null,
+                            EncodingAlgorithmIndexes.DOUBLE,
+                            dval);
+                }
+                break;
+            case FieldConstants.SFVEC3D:
+                dval = fieldParser.SFVec3d(value);
+                if (dval != null && dval.length != 0) {
+                    aholder.addAttributeWithAlgorithmData(
+                            new QualifiedName("", "", name, qName),
+                            null,
+                            EncodingAlgorithmIndexes.DOUBLE,
+                            dval);
+                }
+                break;
+            case FieldConstants.MFVEC3D:
+                dval = fieldParser.MFVec3d(value);
+                if (dval != null && dval.length != 0) {
+                    aholder.addAttributeWithAlgorithmData(
+                            new QualifiedName("", "", name, qName),
+                            null,
+                            EncodingAlgorithmIndexes.DOUBLE,
+                            dval);
+                }
+                break;
+            case FieldConstants.SFVEC2F:
+                fval = fieldParser.SFVec2f(value);
+
+                if (removeDefaults && field != null) {
+                    if (fval.length == field.floatArrayValues.length) {
+
+                        boolean equal = true;
+
+                        for (int j = 0; j < fval.length; j++) {
+
+                            if (Math.abs(fval[j] - field.floatArrayValues[j]) > FLOAT_EPS) {
+                                equal = false;
+
+                                break;
+                            }
+                        }
+
+                        if (equal) {
+                            defaults++;
+                            break;
+                        }
+                    }
+                }
+
+                if (fval != null && fval.length != 0) {
+                    aholder.addAttributeWithAlgorithmData(
+                            new QualifiedName("", "", name, qName),
+                            null,
+                            EncodingAlgorithmIndexes.FLOAT,
+                            fval);
+                }
+                break;
+            case FieldConstants.MFVEC2F:
+                fval = fieldParser.MFVec2f(value);
+                encodeFloatArray(value, fval, name, qName, aholder, fieldType);
+                break;
+            case FieldConstants.SFVEC3F:
+                fval = fieldParser.SFVec3f(value);
+
+                if (removeDefaults && field != null) {
+                    if (fval.length == field.floatArrayValues.length) {
+
+                        boolean equal = true;
+
+                        for (int j = 0; j < fval.length; j++) {
+
+                            if (Math.abs(fval[j] - field.floatArrayValues[j]) > FLOAT_EPS) {
+                                equal = false;
+
+                                break;
+                            }
+                        }
+
+                        if (equal) {
+                            defaults++;
+                            break;
+                        }
+                    }
+                }
+
+                if (fval != null && fval.length != 0) {
+                    aholder.addAttributeWithAlgorithmData(
+                            new QualifiedName("", "", name, qName),
+                            null,
+                            EncodingAlgorithmIndexes.FLOAT,
+                            fval);
+                    if (collectStats) {
+                        clen = BuiltInEncodingAlgorithmFactory.floatEncodingAlgorithm.getOctetLengthFromPrimitiveLength(fval.length);
+                        fieldTypeNewSize[FieldConstants.SFVEC3F] += clen;
+                    }
+                }
+                break;
+            case FieldConstants.MFVEC3F:
+                fval = fieldParser.MFVec3f(value);
+
+                encodeFloatArray(value, fval, name, qName, aholder, fieldType);
+
+                break;
+            case FieldConstants.SFVEC4F:
+                fval = fieldParser.SFVec4f(value);
+                if (fval != null && fval.length != 0) {
+                    aholder.addAttributeWithAlgorithmData(
+                            new QualifiedName("", "", name, qName),
+                            null,
+                            EncodingAlgorithmIndexes.FLOAT,
+                            fval);
+                }
+                break;
+            case FieldConstants.MFVEC4F:
+                fval = fieldParser.MFVec4f(value);
+                encodeFloatArray(value, fval, name, qName, aholder, fieldType);
+                break;
+            case FieldConstants.MFFLOAT:
+                fval = fieldParser.MFFloat(value);
+                encodeFloatArray(value, fval, name, qName, aholder, FieldConstants.MFFLOAT);
+                break;
+            case FieldConstants.MFDOUBLE:
+                dval = fieldParser.MFDouble(value);
+                if (dval != null && dval.length != 0) {
+                    aholder.addAttributeWithAlgorithmData(
+                            new QualifiedName("", "", name, qName),
+                            null,
+                            EncodingAlgorithmIndexes.DOUBLE,
+                            dval);
+                }
+                //encodeFloatArray(value, fval, name, qName, aholder, FieldConstants.MFFLOAT);
+                break;
+            case FieldConstants.SFMATRIX3F:
+                fval = fieldParser.SFMatrix3f(value);
+
+                if (removeDefaults && field != null) {
+                    if (fval.length == field.floatArrayValues.length) {
+
+                        boolean equal = true;
+
+                        for (int j = 0; j < fval.length; j++) {
+
+                            if (Math.abs(fval[j] - field.floatArrayValues[j]) > FLOAT_EPS) {
+                                equal = false;
+
+                                break;
+                            }
+                        }
+
+                        if (equal) {
+                            defaults++;
+                            break;
+                        }
+                    }
+                }
+
+                if (fval != null && fval.length != 0) {
+                    switch (method) {
+                        case METHOD_SMALLEST_LOSSY:
+                            aholder.addAttributeWithAlgorithmData(
+                                    new QualifiedName("", "", name, qName),
+                                    QuantizedzlibFloatArrayAlgorithm.ALGORITHM_URI,
+                                    X3DBinaryConstants.QUANTIZED_ZLIB_FLOAT_ARRAY_ALGORITHM_ID,
+                                    fval);
+                            break;
+                        default:
+                            aholder.addAttributeWithAlgorithmData(
+                                    new QualifiedName("", "", name, qName),
+                                    null,
+                                    EncodingAlgorithmIndexes.FLOAT,
+                                    fval);
+                            break;
+                    }
+                }
+                break;
+            case FieldConstants.MFMATRIX3F:
+                fval = fieldParser.MFMatrix3f(value);
+                encodeFloatArray(value, fval, name, qName, aholder, fieldType);
+                break;
+            case FieldConstants.SFMATRIX4F:
+                fval = fieldParser.SFMatrix4f(value);
+
+                if (removeDefaults && field != null) {
+                    if (fval.length == field.floatArrayValues.length) {
+
+                        boolean equal = true;
+
+                        for (int j = 0; j < fval.length; j++) {
+
+                            if (Math.abs(fval[j] - field.floatArrayValues[j]) > FLOAT_EPS) {
+                                equal = false;
+
+                                break;
+                            }
+                        }
+
+                        if (equal) {
+                            defaults++;
+                            break;
+                        }
+                    }
+                }
+
+                encodeFloatArray(value, fval, name, qName, aholder, fieldType);
+                break;
+            case FieldConstants.MFMATRIX4F:
+                fval = fieldParser.MFMatrix4f(value);
+                encodeFloatArray(value, fval, name, qName, aholder, fieldType);
+                break;
+            case FieldConstants.SFMATRIX3D:
+                dval = fieldParser.SFMatrix3d(value);
+                if (dval != null && dval.length != 0) {
+                    aholder.addAttributeWithAlgorithmData(
+                            new QualifiedName("", "", name, qName),
+                            null,
+                            EncodingAlgorithmIndexes.DOUBLE,
+                            dval);
+                }
+                break;
+            case FieldConstants.MFTIME:
+                dval = fieldParser.MFTime(value);
+                if (dval != null && dval.length != 0) {
+                    aholder.addAttributeWithAlgorithmData(
+                            new QualifiedName("", "", name, qName),
+                            null,
+                            EncodingAlgorithmIndexes.DOUBLE,
+                            dval);
+                }
+                break;
+            case FieldConstants.MFMATRIX3D:
+                dval = fieldParser.MFMatrix3d(value);
+                if (dval != null && dval.length != 0) {
+                    aholder.addAttributeWithAlgorithmData(
+                            new QualifiedName("", "", name, qName),
+                            null,
+                            EncodingAlgorithmIndexes.DOUBLE,
+                            dval);
+                }
+                break;
+            case FieldConstants.SFMATRIX4D:
+                dval = fieldParser.SFMatrix4d(value);
+                if (dval != null && dval.length != 0) {
+                    aholder.addAttributeWithAlgorithmData(
+                            new QualifiedName("", "", name, qName),
+                            null,
+                            EncodingAlgorithmIndexes.DOUBLE,
+                            dval);
+                }
+                break;
+            case FieldConstants.MFMATRIX4D:
+                dval = fieldParser.MFMatrix4d(value);
+                if (dval != null && dval.length != 0) {
+                    aholder.addAttributeWithAlgorithmData(
+                            new QualifiedName("", "", name, qName),
+                            null,
+                            EncodingAlgorithmIndexes.DOUBLE,
+                            dval);
+                }
+                break;
+            case FieldConstants.SFIMAGE:
+                ival = fieldParser.SFImage(value);
+                if (ival != null && ival.length != 0) {
+                    aholder.addAttributeWithAlgorithmData(
+                            new QualifiedName("", "", name, qName),
+                            null,
+                            EncodingAlgorithmIndexes.INT,
+                            ival);
+                }
+                break;
+            case FieldConstants.MFIMAGE:
+                ival = fieldParser.MFImage(value);
+                if (ival != null && ival.length != 0) {
+                    aholder.addAttributeWithAlgorithmData(
+                            new QualifiedName("", "", name, qName),
+                            null,
+                            EncodingAlgorithmIndexes.INT,
+                            ival);
+                }
+                break;
+            case FieldConstants.MFINT32:
+                ival = fieldParser.MFInt32(value);
+
+                System.out.println("BinarySerializer " + name + " " + java.util.Arrays.toString(ival));
+
+                aholder.addAttributeWithAlgorithmData(
+                        new QualifiedName("", "", name, qName),
+                        DeltazlibIntArrayAlgorithm.ALGORITHM_URI,
+                        X3DBinaryConstants.DELTA_ZLIB_INT_ARRAY_ALGORITHM_ID,
+                        ival);
+
+                break;
+            default:
+                System.out.println("Unhandled field: " + name);
+
+        }
+    }
+
+    /**
+     * Encode float array data. This is optimized for MF* types, not types like
+     * SFVec3f.
+     *
+     * @param attVal The field value
+     * @param fval The parsed float array value
+     * @param atts The current attributes array
+     * @param aholder The current attributes holder
+     * @param ftype The X3D field type, defined in FieldConstants
+     */
+    private void encodeFloatArray(String attVal, float[] fval, String localName, String qName, AttributesHolder aholder,
+            int ftype) {
+
+        int clen;
+
+        if (fval != null && fval.length != 0) {
+            switch (method) {
+                case METHOD_SMALLEST_LOSSY:
+                    aholder.addAttributeWithAlgorithmData(
+                            new QualifiedName("", "", localName, qName),
+                            QuantizedzlibFloatArrayAlgorithm.ALGORITHM_URI,
+                            X3DBinaryConstants.QUANTIZED_ZLIB_FLOAT_ARRAY_ALGORITHM_ID,
+                            fval);
+                    break;
+                case METHOD_SMALLEST_NONLOSSY:
+                    aholder.addAttributeWithAlgorithmData(
+                            new QualifiedName("", "", localName, qName),
+                            QuantizedzlibFloatArrayAlgorithm.ALGORITHM_URI,
+                            X3DBinaryConstants.QUANTIZED_ZLIB_FLOAT_ARRAY_ALGORITHM_ID,
+                            fval);
+                    break;
+                default:
+                    clen = BuiltInEncodingAlgorithmFactory.floatEncodingAlgorithm.getOctetLengthFromPrimitiveLength(fval.length);
+
+                    if (clen <= attVal.length()) {
+                        aholder.addAttributeWithAlgorithmData(
+                                new QualifiedName("", "", localName, qName),
+                                null,
+                                EncodingAlgorithmIndexes.FLOAT,
+                                fval);
+                        if (collectStats) {
+                            fieldTypeNewSize[ftype] += clen;
+                        }
+                    } else {
+                        aholder.addAttribute(new QualifiedName("", "", localName,
+                                qName), attVal);
+                        if (collectStats) {
+                            fieldTypeNewSize[ftype] += attVal.length();
+                        }
+                    }
+                    break;
+            }
+        }
+    }
+}
diff --git a/src/java/org/web3d/vrml/export/X3DClassicRetainedExporter.java b/src/java/org/web3d/vrml/export/X3DClassicRetainedExporter.java
index 742ffa69c9cf12783099fff5646ae73c017495bf..d79a44816dd0f5c33bac73a06650f7991eeac265 100644
--- a/src/java/org/web3d/vrml/export/X3DClassicRetainedExporter.java
+++ b/src/java/org/web3d/vrml/export/X3DClassicRetainedExporter.java
@@ -1,1864 +1,1864 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-package org.web3d.vrml.export;
-
-// External imports
-import java.io.*;
-import java.util.*;
-
-import org.j3d.util.IntHashMap;
-import org.j3d.util.ErrorReporter;
-
-// Local imports
-import org.web3d.util.DoubleToString;
-import org.web3d.util.Version;
-
-import org.web3d.vrml.lang.*;
-import org.web3d.vrml.sav.*;
-
-import org.web3d.vrml.nodes.*;
-import org.web3d.vrml.nodes.proto.*;
-
-import org.web3d.vrml.renderer.CRExternPrototypeDecl;
-import org.web3d.vrml.renderer.CRProtoInstance;
-import org.web3d.vrml.renderer.common.nodes.AbstractDynamicFieldNode;
-
-/**
- * X3D Classic exporter using a retained Scenegraph.
- * <p>
- *
- * Known Issues:
- *    Proto node fields are copied into instances
- *
- * @author Alan Hudson
- * @version $Revision: 1.25 $
- */
-public class X3DClassicRetainedExporter extends BaseRetainedExporter
-    implements SceneGraphTraversalSimpleObserver {
-
-    /** The indent String to replicate per level */
-    private static String INDENT_STRING = "   ";
-
-    /** The current indent level */
-    private int indent;
-
-    /** The current indent string */
-    private String indentString;
-
-    /** A mapping of indent to String */
-    private IntHashMap<String> indentMap;
-
-    /** Temporary map during traversal for use references */
-    private Set<VRMLNodeType> usedNodes;
-
-    /** The current set of proto definitions */
-    private Set<VRMLNodeTemplate> protoDeclSet;
-
-    /** Traverser for printing proto's */
-    private SceneGraphTraverser traverser;
-
-    /** The world root */
-    private VRMLWorldRootNodeType root;
-
-    /**
-     * Create a new exporter for the given spec version
-     *
-     * @param os The stream to export the code to
-     * @param major The major version number of this scene
-     * @param minor The minor version number of this scene
-     * @param errorReporter The error reporter to use
-     */
-    public X3DClassicRetainedExporter(OutputStream os, int major, int minor,
-        ErrorReporter errorReporter) {
-
-        this(os, major, minor, errorReporter, -1);
-    }
-
-    /**
-     * Create a new exporter for the given spec version
-     *
-     * @param os The stream to export the code to
-     * @param major The major version number of this scene
-     * @param minor The minor version number of this scene
-     * @param errorReporter The error reporter to use
-     * @param sigDigits The number of significant digits to use in printing floats
-     */
-    public X3DClassicRetainedExporter(OutputStream os, int major, int minor,
-        ErrorReporter errorReporter, int sigDigits) {
-
-        super(major, minor, errorReporter, sigDigits);
-
-        p = new PrintWriter(os, true);
-        init();
-    }
-
-    /**
-     *  Common initialization routine.
-     */
-    private void init() {
-        usedNodes = new HashSet<>();
-        indentString = "";
-        indentMap = new IntHashMap<>();
-        protoDeclSet = new HashSet<>();
-
-        traverser = new SceneGraphTraverser();
-    }
-
-    /**
-     * Write a scene out.
-     *
-     * @param scene The scene to write
-     */
-    public void writeScene(VRMLScene scene) {
-        usedNodes.clear();
-
-        Map<String, VRMLNode> defs = scene.getDEFNodes();
-        currentDefMap = new HashMap<>(defs.size());
-        reverseMap(defs, currentDefMap);
-        Map<VRMLNode, String> saveMap = currentDefMap;
-
-        List<VRMLNodeTemplate> protoList = scene.getNodeTemplates();
-        Iterator<VRMLNodeTemplate> itr = protoList.iterator();
-
-        root = (VRMLWorldRootNodeType) scene.getRootNode();
-
-        Object proto;
-        traverser.setObserver(this);
-
-        while(itr.hasNext()) {
-            proto = itr.next();
-
-            if (proto instanceof ExternalPrototypeDecl) {
-                printExternalPrototypeDecl((CRExternPrototypeDecl)proto);
-            } else {
-                printPrototypeDecl((PrototypeDecl)proto);
-            }
-        }
-
-        currentDefMap = saveMap;
-        traverse(root, true);
-
-        printImports(scene.getImports());
-
-        List<ROUTE> routeList = scene.getRoutes();
-        int len = routeList.size();
-
-        for(int i=0; i < len; i++) {
-            printROUTE(routeList.get(i), currentDefMap);
-        }
-
-        printExports(scene.getExports());
-        p.flush();
-    }
-
-    /**
-     * Declaration of the end of the document. There will be no further parsing
-     * and hence events after this.
-     *
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    @Override
-    public void endDocument() throws SAVException, VRMLException {
-        // TODO: Double happen currently from SAVAdaptor and GeneralisedReader.
-        if (!processingDocument)
-            return;
-
-        processingDocument = false;
-
-        super.endDocument();
-
-        writeScene(scene);
-    }
-
-    /**
-     * Print the header.
-     *
-     * @param major The major version
-     * @param minor The minor version
-     */
-    @Override
-    public void printHeader(int major, int minor) {
-        p.print("#X3D V");
-        p.print(major);
-        p.print(".");
-        p.print(minor);
-        p.println(" utf8");
-        p.println();
-    }
-
-    @Override
-    public void printExporterInfo() {
-        p.print("# Exported by Xj3D's: ");
-        p.print(getClass().getName() + " v" + Version.BUILD_MAJOR_VERSION + Version.PERIOD + Version.BUILD_MINOR_VERSION);
-        p.println();
-    }
-
-    /**
-     * Print the profile decl.
-     *
-     * @param profile The profile
-     */
-    @Override
-    public void printProfile(String profile) {
-        p.println();
-        p.print("PROFILE ");
-        p.println(profile);
-        p.println();
-    }
-
-    /**
-     * Print the component decl
-     *
-     * @param comps The component list
-     */
-    @Override
-    public void printComponents(ComponentInfo[] comps) {
-        int len = comps.length;
-
-        for(int i=0; i < len; i++) {
-            p.print("COMPONENT ");
-            p.print(comps[i].getName());
-            p.print(":");
-            p.println(comps[i].getLevel());
-        }
-
-        if (len > 0)
-            p.println();
-    }
-
-    /**
-     * Print the MetaData.
-     *
-     * @param meta The scene Metadata map
-     */
-    @Override
-    public void printMetaData(Map<String, String> meta) {
-        Map.Entry[] entries;
-
-        entries = new Map.Entry[meta.size()];
-        meta.entrySet().toArray(entries);
-
-        int len = entries.length;
-
-        String key;
-        String value;
-
-        for(int i=0; i < len; i++) {
-            key = (String) entries[i].getKey();
-            value = (String) entries[i].getValue();
-
-            key = key.replace("\\","\\\\");
-            value = value.replace("\\","\\\\");
-
-            // Make sure to also retain double quoted terms in this string
-            value = value.replace("\"", "\\\"");
-
-            p.println("META \"" + key + "\" \"" +  value + "\"");
-        }
-
-        if (len > 0)
-            p.println();
-    }
-
-    /**
-     * Print a ROUTE statement.
-     *
-     * @param route The ROUTE to print
-     * @param defMap The DEF map
-     */
-    @Override
-    public void printROUTE(ROUTE route, Map<VRMLNode, String> defMap) {
-        VRMLNode source = route.getSourceNode();
-        VRMLNode dest = route.getDestinationNode();
-        VRMLFieldDeclaration sourceDecl;
-        VRMLFieldDeclaration destDecl;
-        String sourceDEF;
-        String destDEF;
-
-        if (dest instanceof ImportNodeProxy) {
-            destDEF = ((ImportNodeProxy)dest).getImportedName();
-        } else {
-            destDEF = defMap.get(dest);
-        }
-
-        if (source instanceof ImportNodeProxy) {
-            sourceDEF = ((ImportNodeProxy)source).getImportedName();
-        } else {
-            sourceDEF = defMap.get(source);
-        }
-
-        sourceDecl = source.getFieldDeclaration(route.getSourceIndex());
-        destDecl = dest.getFieldDeclaration(route.getDestinationIndex());
-
-        p.print(indentString);
-        p.print("ROUTE ");
-        p.print(sourceDEF);
-        p.print(".");
-        p.print(sourceDecl.getName());
-        p.print(" TO ");
-        p.print(destDEF);
-        p.print(".");
-        p.println(destDecl.getName());
-    }
-
-    /**
-     * Print Exports.
-     *
-     * @param exports A map of exports(name,AS).
-     */
-    @Override
-    public void printExports(Map<String, String> exports) {
-
-        @SuppressWarnings("unchecked") // generic array type
-        Map.Entry<String, String>[] entries = new Map.Entry[exports.size()];
-        exports.entrySet().toArray(entries);
-
-        String name;
-        String as;
-
-        for (Map.Entry<String, String> entrie : entries) {
-            name = entrie.getValue();
-            as = entrie.getKey();
-            p.print(indentString);
-            p.print("EXPORT ");
-            p.print(name);
-            if (as != null && !name.equals(as)) {
-                p.print(" AS ");
-                p.println(as);
-            } else {
-                p.println();
-            }
-        }
-    }
-
-    /**
-     * Print Imports.
-     *
-     * @param imports A map of imports(exported, String[] {def, as}.
-     */
-    @Override
-    public void printImports(Map<String, VRMLNode> imports) {
-        Map.Entry[] entries;
-
-        entries = new Map.Entry[imports.size()];
-        imports.entrySet().toArray(entries);
-
-        String exported;
-        Object obj;
-        String[] defas;
-        ImportNodeProxy proxy;
-
-        for (Map.Entry entrie : entries) {
-            exported = (String) entrie.getKey();
-            obj = entrie.getValue();
-            if (obj instanceof String[]) {
-                defas = (String[]) entrie.getValue();
-                p.print(indentString);
-                p.print("IMPORT ");
-                p.print(defas[0]);
-                p.print(".");
-                p.print(defas[1]);
-                p.print(" AS ");
-                p.println(exported);
-            } else {
-                proxy = (ImportNodeProxy) obj;
-
-                p.print(indentString);
-                p.print("IMPORT ");
-                p.print(proxy.getInlineDEFName());
-                p.print(".");
-                p.print(proxy.getExportedName());
-                p.print(" AS ");
-                p.println(proxy.getImportedName());
-            }
-        }
-    }
-
-    /**
-     * Print a node and its children.
-     *
-     * @param source The root node
-     * @param ignoreFirst Should we ignore the first node.  Used for WorldRoot and ProtoBody
-     */
-    public void traverse(VRMLNode source, boolean ignoreFirst) {
-
-        if(source == null)
-            return;
-
-        if (ignoreFirst)
-            recurseSimpleSceneGraphChild((VRMLNodeType)source);
-        else
-            processSimpleNode(null, -1, (VRMLNodeType)source);
-    }
-
-    /**
-     * Process a single simple node with its callback
-     */
-    private void processSimpleNode(VRMLNodeType parent,
-                                   int field,
-                                   VRMLNodeType kid) {
-
-        boolean use = usedNodes.contains(kid);
-
-        if(!use)
-            usedNodes.add(kid);
-
-        indentUp();
-
-        if (use) {
-            String defName = currentDefMap.get(kid);
-
-            if (defName == null) {
-                errorReporter.warningReport("Can't find DEF for: " + kid, null);
-                printDefMap(currentDefMap);
-            }
-
-            p.print("USE ");
-            p.println(defName);
-
-            indentDown();
-        } else {
-            printStartNode(kid, use, currentDefMap, currentIsMap);
-
-            // now recurse
-            recurseSimpleSceneGraphChild(kid);
-
-            indentDown();
-            printEndNode(kid);
-        }
-    }
-
-    /**
-     * Internal convenience method that separates the startup traversal code
-     * from the recursive mechanism using the detailed detailObs.
-     *
-     * @param parent The root of the current item to traverse
-     */
-    private void recurseSimpleSceneGraphChild(VRMLNodeType parent) {
-
-        int[] fields = parent.getNodeFieldIndices();
-
-        if(fields == null || fields.length == 0)
-            return;
-
-        VRMLFieldData value;
-        boolean printField;
-        boolean printFieldDecl = false;
-        boolean printValue;
-        int accessType;
-        int fieldMetadata = parent.getFieldIndex("metadata");
-
-        if (parent instanceof AbstractDynamicFieldNode)
-            printFieldDecl = true;
-
-        // TODO: likely will fail when proto's are indented correctly
-        printField = indent > 0;
-
-        for(int i = 0; i < fields.length; i++) {
-            printValue = false;
-
-            // This doubles up IS, seems like it should be needed
-/*
-            String is = findIS(parent, fields[i], currentIsMap);
-
-            if (is != null) {
-                VRMLFieldDeclaration decl = parent.getFieldDeclaration(fields[i]);
-                p.print(indentString);
-                p.print(decl.getName());
-                p.print(" IS ");
-                p.println(is);
-                continue;
-            }
-*/
-            try {
-                value = parent.getFieldValue(fields[i]);
-            } catch(InvalidFieldException ife) {
-                continue;
-            }
-
-            if (printFieldDecl && i == fieldMetadata) {
-                if (value.nodeValue == null) {
-                    // ignore empty metadata for script/proto
-                    continue;
-                }
-
-                printFieldDecl = false;
-            }
-
-            if(value.dataType == VRMLFieldData.NODE_ARRAY_DATA) {
-                if (printField) {
-                    VRMLFieldDeclaration decl = parent.getFieldDeclaration(fields[i]);
-                    p.print(indentString);
-                    if (printFieldDecl) {
-                        accessType = decl.getAccessType();
-                        if (accessType == FieldConstants.FIELD ||
-                            accessType == FieldConstants.EXPOSEDFIELD) {
-
-                            printValue = true;
-                        }
-
-                        printDeclNoValue(decl);
-                        p.print(decl.getName());
-
-                        if (printValue)
-                            p.print(" [");
-                    } else {
-                        if (value.numElements != 0) {
-                            p.print(decl.getName());
-                            p.print(" [");
-                        }
-                    }
-                }
-
-                for(int j = 0; j < value.numElements; j++) {
-                    if(value.nodeArrayValues[j] == null)
-                        continue;
-
-                    if (convertOldContent) {
-                        if (value.nodeArrayValues[j].getVRMLNodeName().equals("GeoOrigin") &&
-                            !parent.getFieldDeclaration(fields[i]).getName().equals("geoOrigin")) {
-
-                            continue;
-                        }
-                    }
-
-
-                    processSimpleNode(parent,
-                                      fields[i], value.nodeArrayValues[j]);
-                }
-
-                if (printFieldDecl) {
-                    if (printValue)
-                        p.println("]");
-                    else
-                        p.println();
-                } else if (printField) {
-                    if (value.numElements != 0) {
-                        p.print(indentString);
-                        p.println("]");
-                    } else {
-                        p.println();
-                    }
-                }
-
-            } else {
-                if (value.nodeValue == null && !printFieldDecl)
-                    continue;
-
-                if (printField) {
-                    VRMLFieldDeclaration decl = parent.getFieldDeclaration(fields[i]);
-                    p.print(indentString);
-
-                    if (printFieldDecl) {
-                        printDeclNoValue(decl);
-
-                        accessType = decl.getAccessType();
-                        if (accessType == FieldConstants.FIELD ||
-                            accessType == FieldConstants.EXPOSEDFIELD) {
-
-                            printValue = true;
-                        }
-
-                    }
-
-                    p.print(decl.getName());
-                    p.print(" ");
-
-                    if (value.nodeValue == null && printFieldDecl) {
-                        if (printValue)
-                            p.println("NULL");
-                        else
-                            p.println();
-                        continue;
-                    }
-                }
-
-                processSimpleNode(parent,
-                                  fields[i],
-                                  (VRMLNodeType)value.nodeValue);
-                if (printField && !printFieldDecl)
-                    p.println();
-            }
-        }
-    }
-
-    /**
-     * Print the start of a node, and all its non node fields.
-     *
-     * @param node The node to print
-     * @param use Is it a USE
-     * @param defMap The current mapping of nodes to DEF names
-     * @param isMap The current mapping of fields to IS names
-     */
-    public void printStartScriptNode(AbstractDynamicFieldNode node, boolean use, Map<VRMLNode, String> defMap, Map<Integer, List<ProtoFieldInfo>> isMap) {
-        List<VRMLFieldDeclaration> fields = node.getAllFields();
-
-        Iterator<VRMLFieldDeclaration> itr = fields.iterator();
-
-        int field_must_evaluate = node.getFieldIndex("mustEvaluate");
-        int field_direct_output = node.getFieldIndex("directOutput");
-        int field_url = node.getFieldIndex("url");
-        int field_metadata = node.getFieldIndex("metadata");
-
-        while(itr.hasNext()) {
-            VRMLFieldDeclaration decl = itr.next();
-
-            if(decl == null)
-                continue;
-
-            VRMLFieldData data;
-            int idx = node.getFieldIndex(decl.getName());
-
-            try {
-                data = node.getFieldValue(idx);
-            } catch(InvalidFieldException e) {
-                errorReporter.errorReport("Can't get field: " + decl.getName() +
-                                    " for: " + node, null);
-                continue;
-            }
-
-            if (idx == field_metadata) {
-                // handled elsewhere
-                continue;
-            } else if (idx == field_must_evaluate) {
-                if (data.booleanValue) {
-                    p.print(indentString);
-                    p.print(decl.getName());
-                    p.print(" ");
-
-                    printFieldValue(node, data, decl);
-                }
-                continue;
-            } else if (idx == field_direct_output) {
-                if (data.booleanValue) {
-                    p.print(indentString);
-                    p.print(decl.getName());
-                    p.print(" ");
-
-                    printFieldValue(node, data, decl);
-                }
-                continue;
-            } else if (idx == field_url) {
-                // handled in printEndNode
-                continue;
-            }
-
-            printScriptFieldDecl(node,decl,idx,data,defMap,currentIsMap);
-        }
-
-        indentDown();
-    }
-
-    /**
-     * Print the start of a node, and all its non node fields.
-     *
-     * @param node The node to print
-     * @param use Is it a USE
-     * @param defMap The current mapping of nodes to DEF names
-     * @param isMap The current mapping of fields to IS names
-     */
-    public void printStartNode(VRMLNodeType node, boolean use, Map<VRMLNode, String> defMap, Map<Integer, List<ProtoFieldInfo>> isMap) {
-        String defName = defMap.get(node);
-
-        if (defName != null) {
-            p.print("DEF ");
-            p.print(defName);
-            p.print(" ");
-        }
-
-        String name = node.getVRMLNodeName();
-
-        if (convertOldContent) {
-            String newName = oldProtos.get(name);
-            if (newName != null) {
-                name = newName;
-            }
-        }
-
-        p.print(name);
-        p.println(" {");
-        indentUp();
-
-        if (node instanceof AbstractDynamicFieldNode) {
-            printStartScriptNode((AbstractDynamicFieldNode)node, use, defMap, isMap);
-            return;
-        }
-
-        defaultNode = (VRMLNodeType) defaultNodes.get(name);
-        if (defaultNode == null && !(node instanceof CRProtoInstance)) {
-            defaultNode = (VRMLNodeType) nodeFactory.createVRMLNode(name, false);
-
-            if (defaultNode == null) {
-                errorReporter.errorReport("Could not create node: " + name, null);
-            }
-
-            defaultNodes.put(name,defaultNode);
-        }
-
-        int len = node.getNumFields();
-        int len2;
-        boolean upgradeInline = false;
-        boolean removeWorldUrl = false;
-        HashSet<Integer> urlFields = null;
-        String worldUrl = null;
-
-        if (node instanceof VRMLExternalNodeType) {
-            removeWorldUrl = true;
-            worldUrl = ((VRMLExternalNodeType)node).getWorldUrl();
-
-            urlFields = new HashSet<>();
-
-            if (node instanceof VRMLSingleExternalNodeType) {
-                urlFields.add(node.getFieldIndex("url"));
-            } else {
-                int[] indexes = ((VRMLMultiExternalNodeType)node).getUrlFieldIndexes();
-                for(int i=0; i < indexes.length; i++) {
-                    urlFields.add(indexes[i]);
-                }
-            }
-        }
-
-        if (upgrading) {
-            if (name.equals("Inline")) {
-                upgradeInline = true;
-            }
-        }
-
-        // Create a fields list to approximate a getAllFields for everyone
-        List<VRMLFieldDeclaration> fields = new ArrayList<>();
-
-        if (node instanceof AbstractProto) {
-            List<VRMLFieldDeclaration> pfields = ((VRMLNodeTemplate)node).getAllFields();
-            Iterator<VRMLFieldDeclaration> itr = pfields.iterator();
-            while(itr.hasNext()) {
-                fields.add(itr.next());
-            }
-        } else {
-            for(int i = 0; i < len; i++) {
-                VRMLFieldDeclaration decl = node.getFieldDeclaration(i);
-                fields.add(decl);
-            }
-        }
-
-        Iterator<VRMLFieldDeclaration> itr = fields.iterator();
-        int idx;
-        int didx = 0;
-        String fieldName;
-
-        while(itr.hasNext()) {
-            VRMLFieldDeclaration decl = itr.next();
-            VRMLFieldDeclaration defaultDecl = null;
-
-            if(decl == null)
-                continue;
-
-            fieldName = decl.getName();
-
-            idx = node.getFieldIndex(fieldName);
-            if (defaultNode != null) {
-                didx = defaultNode.getFieldIndex(fieldName);
-                defaultDecl = defaultNode.getFieldDeclaration(didx);
-            }
-
-            String is = findIS(node, idx, isMap);
-
-            if (is != null) {
-                p.print(indentString);
-                p.print(decl.getName());
-                p.print(" IS ");
-                p.println(is);
-                continue;
-            }
-
-            int access = decl.getAccessType();
-            if (access == FieldConstants.EVENTIN || access == FieldConstants.EVENTOUT)
-                continue;
-
-            VRMLFieldData data;
-            try {
-                data = node.getFieldValue(idx);
-
-            } catch(InvalidFieldException e) {
-                //System.out.println("Can't get field: " + decl.getName() + " for: " + node + " named: " + node.getVRMLNodeName());
-                //System.out.println("Index: " + idx);
-                continue;
-            }
-
-            if (defaultNode != null && isDefault(node, decl, didx, data, defaultNode)) {
-                continue;
-            } else if (node instanceof CRProtoInstance) {
-                CRProtoInstance inst = (CRProtoInstance) node;
-
-                if (inst.isDefaultValue(idx))
-                    continue;
-            }
-
-            // Ignore Node types here, they are handled later
-            if (data.dataType == VRMLFieldData.NODE_DATA ||
-                data.dataType == VRMLFieldData.NODE_ARRAY_DATA)
-                    continue;
-
-            if (removeWorldUrl && (urlFields.contains(idx))) {
-                String[] url = data.stringArrayValues;
-
-                if (url != null && worldUrl != null) {
-                    for(int j=0; j < url.length; j++) {
-                        if (url[j] != null && url[j].startsWith(worldUrl)) {
-                            url[j] = url[j].substring(worldUrl.length());
-                        }
-                    }
-
-                    data.stringArrayValues = url;
-                }
-            }
-
-            if (upgradeInline) {
-                if (decl.getName().equals("url")) {
-                    String[] url = data.stringArrayValues;
-
-                    if (url != null) {
-                        for(int j=0; j < url.length; j++) {
-                            int pos = url[j].indexOf(".wrl");
-                            if (pos >= 0) {
-                                url[j] = url[j].substring(0, pos);
-                                url[j] = url[j] + ".x3dv";
-                            }
-                        }
-
-                        data.stringArrayValues = url;
-                    }
-                }
-            }
-
-            p.print(indentString);
-            p.print(decl.getName());
-
-            p.print(" ");
-
-            printFieldValue(node, data, decl);
-        }
-
-        indentDown();
-    }
-
-    /**
-     * Print the end of a node.
-     *
-     * @param node The node
-     */
-    public void printEndNode(VRMLNodeType node) {
-        if (node instanceof AbstractDynamicFieldNode) {
-            indentUp();
-
-            int field_url = node.getFieldIndex("url");
-
-            VRMLFieldDeclaration decl = node.getFieldDeclaration(field_url);
-
-            VRMLFieldData data = null;
-            try {
-                data = node.getFieldValue(field_url);
-
-            } catch(InvalidFieldException e) {
-                StringBuilder buf = new StringBuilder("Can't get field: ");
-                buf.append(decl.getName());
-                buf.append(" for: ");
-                buf.append(node);
-                buf.append(" named: ");
-                buf.append(node.getVRMLNodeName());
-                buf.append("\nIndex: ");
-                buf.append(field_url);
-
-                errorReporter.errorReport(buf.toString(), null);
-            }
-
-            p.print(indentString);
-            p.print(decl.getName());
-            p.print(" ");
-
-            if (upgrading) {
-                String[] urls = new String[data.stringArrayValues.length];
-
-                boolean foundProtocol = false;
-
-                int len = urls.length;
-                int len2;
-
-                for(int i=0; i < len; i++) {
-                    urls[i] = data.stringArrayValues[i];
-
-                    if (!foundProtocol && (urls[i].startsWith("javascript:") ||
-                        urls[i].startsWith("vrmlscript:"))) {
-
-                        urls[i] = "ecmascript:" + urls[i].substring(11);
-                        foundProtocol = true;
-                    }
-
-                    len2 = scriptPatterns.length;
-
-                    for(int j=0; j < len2; j++) {
-                        urls[i] = scriptPatterns[j].matcher(urls[i]).replaceAll(scriptReplacements[j]);
-                    }
-                }
-
-                data.stringArrayValues = urls;
-            }
-            printFieldValue(node, data, decl);
-
-            indentDown();
-        }
-
-        p.print(indentString);
-        p.println("}");
-    }
-
-    //-------------------------------------------------------------------------
-    // SceneGraphTraverserSimpleObserver methods
-    //-------------------------------------------------------------------------
-
-    /**
-     * Notification of a child node.
-     *
-     * @param parent The parent node of this node
-     * @param child The child node that is being observed
-     * @param field The index of the child field in its parent node
-     * @param used true if the node reference is actually a USE
-     */
-    @Override
-    public void observedNode(VRMLNodeType parent,
-                             VRMLNodeType child,
-                             int field,
-                             boolean used) {
-
-        if (child instanceof ProtoInstancePlaceHolder) {
-            protoDeclSet.add(((ProtoInstancePlaceHolder)child).getProtoDefinition());
-        }
-    }
-
-    /**
-     * Print a proto declaration.
-     *
-     * @param proto The decl to print
-     */
-    @Override
-    public void printPrototypeDecl(PrototypeDecl proto) {
-        currentDefMap = new HashMap<>();
-        Map<VRMLNode, String> saveMap = currentDefMap;
-        reverseMap(proto.getDEFMap(), currentDefMap);
-
-        currentIsMap = proto.getISMaps();
-        currentPrototypeDecl = proto;
-
-        VRMLGroupingNodeType body = proto.getBodyGroup();
-        VRMLNodeType[] children = body.getChildren();
-
-        String name = proto.getVRMLNodeName();
-
-        // Create an instance for default removal
-        VRMLNode n = protoCreator.newInstance(proto,
-                                              root,
-                                              majorVersion,
-                                              minorVersion,
-                                              false);
-
-        defaultNodes.put(proto.getVRMLNodeName(), n);
-
-
-        if (convertOldContent && oldProtos.get(name) != null)
-            return;
-
-        p.print(indentString);
-        p.print("PROTO ");
-        p.print(name);
-        p.println(" [");
-
-        indentUp();
-        // Print Proto Interface
-        List<VRMLFieldDeclaration> fields = proto.getAllFields();
-        Iterator<VRMLFieldDeclaration> itr = fields.iterator();
-        int idx;
-        boolean valReq;
-
-        while(itr.hasNext()) {
-            VRMLFieldDeclaration decl = itr.next();
-
-            idx = proto.getFieldIndex(decl.getName());
-            VRMLFieldData val = null;
-            int access = decl.getAccessType();
-
-            if (access != FieldConstants.EVENTIN && access != FieldConstants.EVENTOUT) {
-                val = proto.getFieldValue(idx);
-                valReq = true;
-            } else {
-                valReq = false;
-            }
-
-            if (decl.getName().equals("metadata")) {
-                if (val == null || val.nodeValue == null)
-                continue;
-            }
-
-            printProtoFieldDecl(decl,idx,val,currentDefMap,currentIsMap, valReq);
-        }
-
-        indentDown();
-        p.print(indentString);
-        p.println("] {");
-        indentUp();
-
-        // Find all nested proto's
-        protoDeclSet.clear();
-        for (VRMLNodeType children1 : children) {
-            traverser.reset();
-            traverser.traverseGraph(children1);
-        }
-
-        PrototypeDecl[] pList = new PrototypeDecl[protoDeclSet.size()];
-        protoDeclSet.toArray((VRMLNodeTemplate[])pList);
-
-        for (PrototypeDecl pList1 : pList) {
-            printPrototypeDecl(pList1);
-        }
-
-        // Restore after printing subs, do we need a stack?
-        currentDefMap = saveMap;
-        currentIsMap = proto.getISMaps();
-        currentPrototypeDecl = proto;
-
-        for (VRMLNodeType children1 : children) {
-            p.print(indentString);
-            traverse(children1, false);
-        }
-
-        printImports(proto.getImportDecls());
-
-        Set<ProtoROUTE> routeSet = proto.getRouteDecls();
-        Iterator<ProtoROUTE> ritr = routeSet.iterator();
-
-        while(ritr.hasNext()) {
-            printROUTE(ritr.next(), currentDefMap);
-        }
-
-        indentDown();
-        p.print(indentString);
-        p.println("}");
-    }
-
-    /**
-     * Print an external proto declaration.
-     *
-     * @param proto The decl to print
-     */
-    public void printExternalPrototypeDecl(CRExternPrototypeDecl proto) {
-        currentDefMap = new HashMap<>();
-
-        String name = proto.getVRMLNodeName();
-
-        if (convertOldContent && oldProtos.get(name) != null)
-            return;
-
-        p.print(indentString);
-        p.print("EXTERNPROTO ");
-        p.print(name);
-        p.println(" [");
-
-        indentUp();
-        // Print Proto Interface
-        List<VRMLFieldDeclaration> fields = proto.getAllFields();
-        Iterator<VRMLFieldDeclaration> itr = fields.iterator();
-        int idx;
-
-        while(itr.hasNext()) {
-            VRMLFieldDeclaration decl = itr.next();
-            idx = proto.getFieldIndex(decl.getName());
-            VRMLFieldData val = null;
-
-            // Ignore metadata for EP
-            if (decl.getName().equals("metadata"))
-                continue;
-
-            printProtoFieldDecl(decl,idx,null,currentDefMap,currentIsMap, false);
-        }
-
-        indentDown();
-        p.print(indentString);
-        p.print("] ");
-
-        // The url was saved in epToUrl
-        // Might use getUrl, but it has worldURL baked in
-
-        String[] url = epToUrl.get(proto.getVRMLNodeName());
-
-        p.print("[");
-        int len = url.length;
-
-        for(int i=0; i < len; i++) {
-            p.print("\"");
-
-            if (upgrading) {
-                int pos = url[i].indexOf(".wrl");
-                int locpos = url[i].indexOf("#");
-
-                if (pos >= 0) {
-                    String original = url[i];
-                    url[i] = url[i].substring(0, pos);
-
-                    url[i] = url[i] + ".x3dv";
-
-                    if (locpos > 0) {
-                        String target = original.substring(locpos);
-
-                        url[i] = url[i] + target;
-                    }
-                }
-            }
-
-            p.print(url[i]);
-            p.print("\"");
-
-            if (i != len - 1)
-                p.println();
-        }
-        p.println("]\n");
-        // No defaults for extern protos
-    }
-
-    /**
-     * Determine if a field is a MF* or SF*.
-     *
-     * @return true if a MF*
-     */
-    private boolean isMFField(VRMLFieldDeclaration decl) {
-        int ft = decl.getFieldType();
-
-        // All MF* are even currently.  Change to a switch if that
-        // changes.
-        return ft % 2 == 0;
-    }
-
-    /**
-     * Increment the indent level.  This updates the identString.
-     */
-    private void indentUp() {
-        indent++;
-
-        indentString = indentMap.get(indent);
-
-        if (indentString == null) {
-            StringBuilder buff = new StringBuilder(indent * INDENT_STRING.length());
-
-            for(int i=0; i < indent; i++) {
-                buff.append(INDENT_STRING);
-            }
-
-            indentString = buff.toString();
-            indentMap.put(indent, indentString);
-        }
-    }
-
-    /**
-     * Decrement the indent level.  This updates the identString.
-     */
-    private void indentDown() {
-        indent--;
-
-        indentString = indentMap.get(indent);
-
-        if (indentString == null) {
-            StringBuilder buff = new StringBuilder(indent * INDENT_STRING.length());
-
-            for(int i=0; i < indent; i++) {
-                buff.append(INDENT_STRING);
-            }
-
-            indentString = buff.toString();
-        }
-    }
-
-    private void printProtoFieldDecl(VRMLFieldDeclaration decl, int idx,
-        VRMLFieldData val, Map<VRMLNode, String> defMap, Map<Integer, List<ProtoFieldInfo>> isMap, boolean valRequired) {
-
-        p.print(indentString);
-        int access = decl.getAccessType();
-        switch(access) {
-            case FieldConstants.FIELD:
-                p.print("initializeOnly ");
-                break;
-            case FieldConstants.EXPOSEDFIELD:
-                p.print("inputOutput ");
-                break;
-            case FieldConstants.EVENTIN:
-                p.print("inputOnly ");
-                break;
-            case FieldConstants.EVENTOUT:
-                p.print("outputOnly ");
-                break;
-            default:
-                errorReporter.errorReport("Unknown field type in X3DClassicExporter: " +
-                                    access, null);
-        }
-
-        p.print(decl.getFieldTypeString());
-        p.print(" ");
-        p.print(decl.getName());
-        p.print(" ");
-
-        // Print the field value
-
-        VRMLNode node;
-
-        if (val != null) {
-            switch(val.dataType) {
-                case VRMLFieldData.NODE_DATA:
-                    node = val.nodeValue;
-                    if (node == null)
-                        p.println(" NULL");
-                    else
-                        traverse(node, false);
-
-                    break;
-                case VRMLFieldData.NODE_ARRAY_DATA:
-                    p.println("[");
-                    VRMLNode[] nodes = val.nodeArrayValues;
-                    int len = nodes.length;
-
-                    indentUp();
-                    for(int i=0; i < len; i++) {
-                        p.print(indentString);
-                        traverse(nodes[i], false);
-                    }
-
-                    indentDown();
-                    p.print(indentString);
-                    p.println("]");
-                    break;
-                default:
-                    // NULL node is ok as it will never need name conversion
-                    printFieldValue(null, val, decl);
-            }
-        } else {
-            if (valRequired) {
-                // Null is ok as it will never need name conversion
-                printFieldValue(null, val, decl);
-            }
-
-            p.println();
-        }
-    }
-
-    /**
-     * Print a field decl with the value part.
-     */
-    private void printDeclNoValue(VRMLFieldDeclaration decl) {
-        int access = decl.getAccessType();
-        switch(access) {
-            case FieldConstants.FIELD:
-                p.print("initializeOnly ");
-                break;
-            case FieldConstants.EXPOSEDFIELD:
-                p.print("inputOutput ");
-                break;
-            case FieldConstants.EVENTIN:
-                p.print("inputOnly ");
-                break;
-            case FieldConstants.EVENTOUT:
-                p.print("outputOnly ");
-                break;
-            default:
-                errorReporter.errorReport("Unknown field type in X3DClassicExporter: " +
-                                          access, null);
-        }
-
-        p.print(decl.getFieldTypeString());
-        p.print(" ");
-    }
-
-    /**
-     * Print a script field decl including value.
-     *
-     * @param node The script node
-     * @param decl The field decl
-     * @param idx The field index
-     * @param val The field value
-     * @param defMap The current DEF map
-     * @param isMap The current IS map
-     */
-    private void printScriptFieldDecl(VRMLNodeType node,
-        VRMLFieldDeclaration decl, int idx, VRMLFieldData val, Map<VRMLNode, String> defMap,
-        Map<Integer, List<ProtoFieldInfo>> isMap) {
-
-        String is = findIS(node, idx, isMap);
-
-        if (is == null && val != null && (
-            val.dataType == VRMLFieldData.NODE_DATA ||
-            val.dataType == VRMLFieldData.NODE_ARRAY_DATA)) {
-            // Don't print decl yet
-            return;
-        }
-
-        p.print(indentString);
-
-        printDeclNoValue(decl);
-
-        if (is != null) {
-            p.print(decl.getName());
-            p.print(" ");
-            p.print("IS ");
-            p.println(is);
-            return;
-        }
-
-        int access = decl.getAccessType();
-        if (access == FieldConstants.EVENTIN ||
-            access == FieldConstants.EVENTOUT) {
-
-            p.println(decl.getName());
-            return;
-        }
-
-        // Print the field value
-
-        VRMLNode n;
-
-        if (val != null) {
-            switch(val.dataType) {
-                case VRMLFieldData.NODE_DATA:
-                    // ignore
-                    break;
-                case VRMLFieldData.NODE_ARRAY_DATA:
-                    // ignore
-                    break;
-                default:
-                    p.print(decl.getName());
-                    p.print(" ");
-                    printFieldValue(node, val, decl);
-                    p.println();
-            }
-        }
-    }
-
-    /**
-     * Is this field a default value.
-     *
-     * @param node The node
-     * @param decl The field decl
-     * @param i The field index
-     * @param data The value
-     * @param defaultNode The default node to compare to
-     *
-     * @return true if its a default
-     */
-    private boolean isDefault(VRMLNodeType node, VRMLFieldDeclaration decl, int i,
-        VRMLFieldData data, VRMLNodeType defaultNode) {
-
-        VRMLFieldData defaultData;
-
-        try {
-            defaultData = defaultNode.getFieldValue(i);
-        } catch(InvalidFieldException e) {
-//                e.printStackTrace(System.err);
-            StringBuilder buf = new StringBuilder("Can't get field: ");
-            buf.append(decl.getName());
-            buf.append(" for: ");
-            buf.append(node);
-            buf.append(" named: ");
-            buf.append(node.getVRMLNodeName());
-            buf.append("\nIndex: ");
-            buf.append(i);
-
-            errorReporter.errorReport(buf.toString(), null);
-
-            return false;
-        }
-
-        // No value means a proto instance without a value registered
-        if (data == null)
-            return true;
-
-        boolean same = true;
-        int len2;
-
-        switch(data.dataType) {
-            case VRMLFieldData.BOOLEAN_DATA:
-                if (defaultData.booleanValue != data.booleanValue)
-                    same = false;
-                break;
-            case VRMLFieldData.INT_DATA:
-                if (defaultData.intValue != data.intValue)
-                    same = false;
-                break;
-            case VRMLFieldData.LONG_DATA:
-                if (defaultData.longValue != data.longValue)
-                    same = false;
-                break;
-            case VRMLFieldData.FLOAT_DATA:
-                if (defaultData.floatValue != data.floatValue)
-                    same = false;
-                break;
-            case VRMLFieldData.DOUBLE_DATA:
-                if (defaultData.doubleValue != data.doubleValue)
-                    same = false;
-                break;
-            case VRMLFieldData.STRING_DATA:
-                if (defaultData.stringValue == null) {
-                    return false;
-                }
-
-                if (!defaultData.stringValue.equals(data.stringValue))
-                    same = false;
-                break;
-            case VRMLFieldData.NODE_DATA:
-                // ignore
-                break;
-
-            case VRMLFieldData.BOOLEAN_ARRAY_DATA:
-                if (defaultData.booleanArrayValues == null &&
-                    data.booleanArrayValues == null) {
-
-                    break;
-                }
-
-                if (defaultData.booleanArrayValues == null ||
-                    data.booleanArrayValues == null) {
-
-                    same = false;
-                    break;
-                }
-
-                if (defaultData.booleanArrayValues.length != data.booleanArrayValues.length) {
-                    same = false;
-                    break;
-                }
-                len2 = defaultData.booleanArrayValues.length;
-
-                for(int j=0; j < len2; j++) {
-                    if (defaultData.booleanArrayValues[j] != data.booleanArrayValues[j]) {
-                        same = false;
-                        break;
-                    }
-                }
-                break;
-
-            case VRMLFieldData.INT_ARRAY_DATA:
-                if (defaultData.intArrayValues == null &&
-                    data.intArrayValues == null) {
-
-                    break;
-                }
-
-                if (defaultData.intArrayValues == null ||
-                    data.intArrayValues == null) {
-
-                    same = false;
-                    break;
-                }
-
-                if (defaultData.intArrayValues.length != data.intArrayValues.length) {
-                    same = false;
-                    break;
-                }
-                len2 = defaultData.intArrayValues.length;
-
-                for(int j=0; j < len2; j++) {
-                    if (defaultData.intArrayValues[j] != data.intArrayValues[j]) {
-                        same = false;
-                        break;
-                    }
-                }
-
-                break;
-
-            case VRMLFieldData.LONG_ARRAY_DATA:
-                if (defaultData.longArrayValues == null &&
-                    data.longArrayValues == null) {
-
-                    break;
-                }
-
-                if (defaultData.longArrayValues == null ||
-                    data.longArrayValues == null) {
-
-                    same = false;
-                    break;
-                }
-
-                if (defaultData.longArrayValues.length != data.longArrayValues.length) {
-                    same = false;
-                    break;
-                }
-                len2 = defaultData.longArrayValues.length;
-
-                for(int j=0; j < len2; j++) {
-                    if (defaultData.longArrayValues[j] != data.longArrayValues[j]) {
-                        same = false;
-                        break;
-                    }
-                }
-
-                break;
-
-            case VRMLFieldData.FLOAT_ARRAY_DATA:
-                if (defaultData.floatArrayValues == null &&
-                    data.floatArrayValues == null) {
-
-                    break;
-                }
-
-                if (defaultData.floatArrayValues == null ||
-                    data.floatArrayValues == null) {
-
-                    same = false;
-                    break;
-                }
-
-                if (defaultData.floatArrayValues.length != data.floatArrayValues.length) {
-                    same = false;
-                    break;
-                }
-                len2 = defaultData.floatArrayValues.length;
-
-                for(int j=0; j < len2; j++) {
-                    if (defaultData.floatArrayValues[j] != data.floatArrayValues[j]) {
-                        same = false;
-                        break;
-                    }
-                }
-                break;
-
-            case VRMLFieldData.DOUBLE_ARRAY_DATA:
-                if (defaultData.doubleArrayValues == null &&
-                    data.doubleArrayValues == null) {
-
-                    break;
-                }
-
-                if (defaultData.doubleArrayValues == null ||
-                    data.doubleArrayValues == null) {
-
-                    same = false;
-                    break;
-                }
-
-                if (defaultData.doubleArrayValues.length != data.doubleArrayValues.length) {
-                   same = false;
-                   break;
-                }
-
-                len2 = defaultData.doubleArrayValues.length;
-
-                for(int j=0; j < len2; j++) {
-                    if (defaultData.doubleArrayValues[j] != data.doubleArrayValues[j]) {
-                        same = false;
-                        break;
-                    }
-                }
-
-                break;
-
-            case VRMLFieldData.NODE_ARRAY_DATA:
-                //ignore
-                break;
-
-            case VRMLFieldData.STRING_ARRAY_DATA:
-                if (defaultData.stringArrayValues == null &&
-                    data.stringArrayValues == null) {
-
-                    break;
-                }
-
-                if (defaultData.stringArrayValues == null ||
-                    data.stringArrayValues == null) {
-
-                    same = false;
-                    break;
-                }
-
-                if (defaultData.stringArrayValues.length != data.stringArrayValues.length) {
-                    same = false;
-                    break;
-                }
-                len2 = defaultData.stringArrayValues.length;
-
-                for(int j=0; j < len2; j++) {
-                    if (defaultData.stringArrayValues[j] == null && data.stringArrayValues[j] == null)
-                        continue;
-
-                    if (defaultData.stringArrayValues[j] == null ||
-                        data.stringArrayValues[j] == null) {
-
-                        same = false;
-                        break;
-                    }
-
-                    if (!defaultData.stringArrayValues[j].equals(data.stringArrayValues[j])) {
-                        same = false;
-                        break;
-                    }
-                }
-                break;
-        }
-
-        return same;
-    }
-
-    /**
-     * Print a field value.  Ignores Node fields.
-     *
-     * @param node The node.  Used for field remap, null is ok if not desired.
-     * @param data The data to print
-     * @param decl The field declaration
-     */
-    private void printFieldValue(VRMLNodeType node, VRMLFieldData data, VRMLFieldDeclaration decl) {
-        int len2;
-        boolean ismf;
-        int span;
-        int idx;
-
-        if (data == null) {
-            // All MF* are even currently.  Change to a switch if that
-            // changes.
-
-            int ftype = decl.getFieldType();
-
-            if (ftype % 2 == 0) {
-                p.print("[ ]");
-            } else if (ftype == FieldConstants.SFNODE)
-                p.print("NULL");
-            else {
-                // We have a SF without a value field.  Not sure exactly what do here.
-                // I think its illegal except for SFString.  But it might mean default value.
-                // Handle for SFString, leave a message for others
-                if (ftype == FieldConstants.SFSTRING) {
-                    p.print("\"\"");
-                } else {
-                    errorReporter.warningReport("Empty value field for: " + decl, null);
-                }
-            }
-
-            return;
-        }
-
-        if (convertOldContent && node != null) {
-            String fieldKey = node.getVRMLNodeName() + "." + decl.getName();
-            Integer newFieldType = fieldRemap.get(fieldKey);
-
-            if (newFieldType != null) {
-                int newType = newFieldType;
-
-                convertFieldData(newType, data, decl);
-            }
-        }
-
-        switch(data.dataType) {
-            case VRMLFieldData.NODE_ARRAY_DATA:
-                //ignore, handled elsewhere
-                break;
-
-            case VRMLFieldData.NODE_DATA:
-                // ignore, handled elsewhere
-                break;
-
-            case VRMLFieldData.BOOLEAN_DATA:
-                if (data.booleanValue)
-                    p.println("TRUE");
-                else
-                    p.println("FALSE");
-
-                break;
-
-            case VRMLFieldData.INT_DATA:
-                p.println(data.intValue);
-                break;
-
-            case VRMLFieldData.LONG_DATA:
-                p.println(data.longValue);
-                break;
-
-            case VRMLFieldData.FLOAT_DATA:
-                p.println(data.floatValue);
-                break;
-
-            case VRMLFieldData.DOUBLE_DATA:
-                p.println(data.doubleValue);
-                break;
-
-            case VRMLFieldData.STRING_DATA:
-                if (data.stringValue == null) {
-                    p.println("\"\"");
-                } else {
-                    p.print("\"");
-                    p.print(data.stringValue);
-                    p.println("\"");
-                }
-                break;
-
-            case VRMLFieldData.BOOLEAN_ARRAY_DATA:
-                if (data.booleanArrayValues == null)
-                    break;
-
-                p.print("[");
-                len2 = data.numElements;
-                for(int j=0; j < len2 - 1; j++) {
-                    if(data.booleanArrayValues[j]) {
-                        p.print("TRUE,");
-                    } else {
-                        p.print("FALSE,");
-                    }
-                }
-
-                if(data.booleanArrayValues[len2 - 1]) {
-                    p.print("TRUE");
-                } else {
-                    p.print("FALSE");
-                }
-
-                p.println("]");
-                break;
-
-            case VRMLFieldData.INT_ARRAY_DATA:
-                if (data.intArrayValues == null)
-                    break;
-
-                p.print("[");
-                len2 = data.numElements;
-                for(int j=0; j < len2 - 1; j++) {
-                    p.print(data.intArrayValues[j]);
-                    p.print(" ");
-                }
-
-                p.print(data.intArrayValues[len2 - 1]);
-                p.println("]");
-
-                break;
-
-            case VRMLFieldData.LONG_ARRAY_DATA:
-                if (data.longArrayValues == null)
-                    break;
-
-                p.print("[");
-                len2 = data.numElements;
-                for(int j=0; j < len2 - 1; j++) {
-                    p.print(data.longArrayValues[j]);
-                    p.print(" ");
-                }
-
-                p.print(data.longArrayValues[len2 - 1]);
-                p.println("]");
-                break;
-
-            case VRMLFieldData.FLOAT_ARRAY_DATA:
-                if (data.floatArrayValues == null)
-                    break;
-
-                ismf = isMFField(decl);
-
-                StringBuilder sb = new StringBuilder();
-
-                if (ismf) {
-                    sb.append("[");
-                    len2 = data.numElements;
-
-                    if (len2 > 0) {
-                        span = data.floatArrayValues.length / len2;
-                        idx = 0;
-                        for(int j=0; j < len2; j++) {
-                            for(int k=0; k < span; k++) {
-                                DoubleToString.appendFormatted(sb,data.floatArrayValues[idx++],sigDigits);
-                                //p.print(data.floatArrayValue[idx++]);
-                                if (k != span - 1)
-                                    sb.append(" ");
-                            }
-                            if (j != len2 -1) {
-                                sb.append(", ");
-                            }
-                        }
-                    }
-                    sb.append("]\n");
-                    p.print(sb.toString());
-                } else {
-                    len2 = data.floatArrayValues.length;
-                    for(int j=0; j < len2; j++) {
-                        DoubleToString.appendFormatted(sb,data.floatArrayValues[j],sigDigits);
-
-                        //p.print(data.floatArrayValue[j]);
-                        if (j != len2 -1 )
-                            sb.append(" ");
-                    }
-                    sb.append("\n");
-                    p.print(sb.toString());
-                }
-                break;
-
-            case VRMLFieldData.DOUBLE_ARRAY_DATA:
-                if (data.doubleArrayValues == null)
-                    break;
-
-                ismf = isMFField(decl);
-
-                if (ismf) {
-                    p.print("[");
-                    len2 = data.numElements;
-
-                    if (len2 > 0) {
-                        span = data.doubleArrayValues.length / len2;
-                        idx = 0;
-                        for(int j=0; j < len2; j++) {
-                            for(int k=0; k < span; k++) {
-                                p.print(data.doubleArrayValues[idx++]);
-                                if (k != span - 1)
-                                    p.print(" ");
-                            }
-                            if (j != len2 -1) {
-                                p.print(", ");
-                            }
-                        }
-                    }
-                    p.println("]");
-                } else {
-                    len2 = data.doubleArrayValues.length;
-                    for(int j=0; j < len2; j++) {
-                        p.print(data.doubleArrayValues[j]);
-                        if (j != len2 -1 )
-                            p.print(" ");
-                    }
-                    p.println();
-                }
-                break;
-
-            case VRMLFieldData.STRING_ARRAY_DATA:
-                if (data.stringArrayValues == null)
-                    break;
-
-                p.print("[");
-
-				len2 = data.numElements;
-                if (len2 > 0) {
-					for(int j=0; j < len2 - 1; j++) {
-						p.print("\"");
-						p.print(data.stringArrayValues[j]);
-						p.print("\",");
-					}
-					p.print("\"");
-					p.print(data.stringArrayValues[len2 - 1]);
-					p.print("\"");
-				}
-                p.println("]");
-                break;
-
-            default:
-                errorReporter.messageReport("Unhandled case in switch printFieldValue");
-        }
-    }
-
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+package org.web3d.vrml.export;
+
+// External imports
+import java.io.*;
+import java.util.*;
+
+import org.j3d.util.IntHashMap;
+import org.j3d.util.ErrorReporter;
+
+// Local imports
+import org.web3d.util.DoubleToString;
+import org.web3d.util.Version;
+
+import org.web3d.vrml.lang.*;
+import org.web3d.vrml.sav.*;
+
+import org.web3d.vrml.nodes.*;
+import org.web3d.vrml.nodes.proto.*;
+
+import org.web3d.vrml.renderer.CRExternPrototypeDecl;
+import org.web3d.vrml.renderer.CRProtoInstance;
+import org.web3d.vrml.renderer.common.nodes.AbstractDynamicFieldNode;
+
+/**
+ * X3D Classic exporter using a retained Scenegraph.
+ * <p>
+ *
+ * Known Issues:
+ *    Proto node fields are copied into instances
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.25 $
+ */
+public class X3DClassicRetainedExporter extends BaseRetainedExporter
+    implements SceneGraphTraversalSimpleObserver {
+
+    /** The indent String to replicate per level */
+    private static String INDENT_STRING = "   ";
+
+    /** The current indent level */
+    private int indent;
+
+    /** The current indent string */
+    private String indentString;
+
+    /** A mapping of indent to String */
+    private IntHashMap<String> indentMap;
+
+    /** Temporary map during traversal for use references */
+    private Set<VRMLNodeType> usedNodes;
+
+    /** The current set of proto definitions */
+    private Set<VRMLNodeTemplate> protoDeclSet;
+
+    /** Traverser for printing proto's */
+    private SceneGraphTraverser traverser;
+
+    /** The world root */
+    private VRMLWorldRootNodeType root;
+
+    /**
+     * Create a new exporter for the given spec version
+     *
+     * @param os The stream to export the code to
+     * @param major The major version number of this scene
+     * @param minor The minor version number of this scene
+     * @param errorReporter The error reporter to use
+     */
+    public X3DClassicRetainedExporter(OutputStream os, int major, int minor,
+        ErrorReporter errorReporter) {
+
+        this(os, major, minor, errorReporter, -1);
+    }
+
+    /**
+     * Create a new exporter for the given spec version
+     *
+     * @param os The stream to export the code to
+     * @param major The major version number of this scene
+     * @param minor The minor version number of this scene
+     * @param errorReporter The error reporter to use
+     * @param sigDigits The number of significant digits to use in printing floats
+     */
+    public X3DClassicRetainedExporter(OutputStream os, int major, int minor,
+        ErrorReporter errorReporter, int sigDigits) {
+
+        super(major, minor, errorReporter, sigDigits);
+
+        p = new PrintWriter(os, true);
+        init();
+    }
+
+    /**
+     *  Common initialization routine.
+     */
+    private void init() {
+        usedNodes = new HashSet<>();
+        indentString = "";
+        indentMap = new IntHashMap<>();
+        protoDeclSet = new HashSet<>();
+
+        traverser = new SceneGraphTraverser();
+    }
+
+    /**
+     * Write a scene out.
+     *
+     * @param scene The scene to write
+     */
+    public void writeScene(VRMLScene scene) {
+        usedNodes.clear();
+
+        Map<String, VRMLNode> defs = scene.getDEFNodes();
+        currentDefMap = new HashMap<>(defs.size());
+        reverseMap(defs, currentDefMap);
+        Map<VRMLNode, String> saveMap = currentDefMap;
+
+        List<VRMLNodeTemplate> protoList = scene.getNodeTemplates();
+        Iterator<VRMLNodeTemplate> itr = protoList.iterator();
+
+        root = (VRMLWorldRootNodeType) scene.getRootNode();
+
+        Object proto;
+        traverser.setObserver(this);
+
+        while(itr.hasNext()) {
+            proto = itr.next();
+
+            if (proto instanceof ExternalPrototypeDecl) {
+                printExternalPrototypeDecl((CRExternPrototypeDecl)proto);
+            } else {
+                printPrototypeDecl((PrototypeDecl)proto);
+            }
+        }
+
+        currentDefMap = saveMap;
+        traverse(root, true);
+
+        printImports(scene.getImports());
+
+        List<ROUTE> routeList = scene.getRoutes();
+        int len = routeList.size();
+
+        for(int i=0; i < len; i++) {
+            printROUTE(routeList.get(i), currentDefMap);
+        }
+
+        printExports(scene.getExports());
+        p.flush();
+    }
+
+    /**
+     * Declaration of the end of the document. There will be no further parsing
+     * and hence events after this.
+     *
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    @Override
+    public void endDocument() throws SAVException, VRMLException {
+        // TODO: Double happen currently from SAVAdaptor and GeneralisedReader.
+        if (!processingDocument)
+            return;
+
+        processingDocument = false;
+
+        super.endDocument();
+
+        writeScene(scene);
+    }
+
+    /**
+     * Print the header.
+     *
+     * @param major The major version
+     * @param minor The minor version
+     */
+    @Override
+    public void printHeader(int major, int minor) {
+        p.print("#X3D V");
+        p.print(major);
+        p.print(".");
+        p.print(minor);
+        p.println(" utf8");
+        p.println();
+    }
+
+    @Override
+    public void printExporterInfo() {
+        p.print("# Exported by Xj3D's: ");
+        p.print(getClass().getName() + " v" + Version.BUILD_MAJOR_VERSION + Version.PERIOD + Version.BUILD_MINOR_VERSION);
+        p.println();
+    }
+
+    /**
+     * Print the profile decl.
+     *
+     * @param profile The profile
+     */
+    @Override
+    public void printProfile(String profile) {
+        p.println();
+        p.print("PROFILE ");
+        p.println(profile);
+        p.println();
+    }
+
+    /**
+     * Print the component decl
+     *
+     * @param comps The component list
+     */
+    @Override
+    public void printComponents(ComponentInfo[] comps) {
+        int len = comps.length;
+
+        for(int i=0; i < len; i++) {
+            p.print("COMPONENT ");
+            p.print(comps[i].getName());
+            p.print(":");
+            p.println(comps[i].getLevel());
+        }
+
+        if (len > 0)
+            p.println();
+    }
+
+    /**
+     * Print the MetaData.
+     *
+     * @param meta The scene Metadata map
+     */
+    @Override
+    public void printMetaData(Map<String, String> meta) {
+        Map.Entry[] entries;
+
+        entries = new Map.Entry[meta.size()];
+        meta.entrySet().toArray(entries);
+
+        int len = entries.length;
+
+        String key;
+        String value;
+
+        for(int i=0; i < len; i++) {
+            key = (String) entries[i].getKey();
+            value = (String) entries[i].getValue();
+
+            key = key.replace("\\","\\\\");
+            value = value.replace("\\","\\\\");
+
+            // Make sure to also retain double quoted terms in this string
+            value = value.replace("\"", "\\\"");
+
+            p.println("META \"" + key + "\" \"" +  value + "\"");
+        }
+
+        if (len > 0)
+            p.println();
+    }
+
+    /**
+     * Print a ROUTE statement.
+     *
+     * @param route The ROUTE to print
+     * @param defMap The DEF map
+     */
+    @Override
+    public void printROUTE(ROUTE route, Map<VRMLNode, String> defMap) {
+        VRMLNode source = route.getSourceNode();
+        VRMLNode dest = route.getDestinationNode();
+        VRMLFieldDeclaration sourceDecl;
+        VRMLFieldDeclaration destDecl;
+        String sourceDEF;
+        String destDEF;
+
+        if (dest instanceof ImportNodeProxy) {
+            destDEF = ((ImportNodeProxy)dest).getImportedName();
+        } else {
+            destDEF = defMap.get(dest);
+        }
+
+        if (source instanceof ImportNodeProxy) {
+            sourceDEF = ((ImportNodeProxy)source).getImportedName();
+        } else {
+            sourceDEF = defMap.get(source);
+        }
+
+        sourceDecl = source.getFieldDeclaration(route.getSourceIndex());
+        destDecl = dest.getFieldDeclaration(route.getDestinationIndex());
+
+        p.print(indentString);
+        p.print("ROUTE ");
+        p.print(sourceDEF);
+        p.print(".");
+        p.print(sourceDecl.getName());
+        p.print(" TO ");
+        p.print(destDEF);
+        p.print(".");
+        p.println(destDecl.getName());
+    }
+
+    /**
+     * Print Exports.
+     *
+     * @param exports A map of exports(name,AS).
+     */
+    @Override
+    public void printExports(Map<String, String> exports) {
+
+        @SuppressWarnings("unchecked") // generic array type
+        Map.Entry<String, String>[] entries = new Map.Entry[exports.size()];
+        exports.entrySet().toArray(entries);
+
+        String name;
+        String as;
+
+        for (Map.Entry<String, String> entrie : entries) {
+            name = entrie.getValue();
+            as = entrie.getKey();
+            p.print(indentString);
+            p.print("EXPORT ");
+            p.print(name);
+            if (as != null && !name.equals(as)) {
+                p.print(" AS ");
+                p.println(as);
+            } else {
+                p.println();
+            }
+        }
+    }
+
+    /**
+     * Print Imports.
+     *
+     * @param imports A map of imports(exported, String[] {def, as}.
+     */
+    @Override
+    public void printImports(Map<String, VRMLNode> imports) {
+        Map.Entry[] entries;
+
+        entries = new Map.Entry[imports.size()];
+        imports.entrySet().toArray(entries);
+
+        String exported;
+        Object obj;
+        String[] defas;
+        ImportNodeProxy proxy;
+
+        for (Map.Entry entrie : entries) {
+            exported = (String) entrie.getKey();
+            obj = entrie.getValue();
+            if (obj instanceof String[]) {
+                defas = (String[]) entrie.getValue();
+                p.print(indentString);
+                p.print("IMPORT ");
+                p.print(defas[0]);
+                p.print(".");
+                p.print(defas[1]);
+                p.print(" AS ");
+                p.println(exported);
+            } else {
+                proxy = (ImportNodeProxy) obj;
+
+                p.print(indentString);
+                p.print("IMPORT ");
+                p.print(proxy.getInlineDEFName());
+                p.print(".");
+                p.print(proxy.getExportedName());
+                p.print(" AS ");
+                p.println(proxy.getImportedName());
+            }
+        }
+    }
+
+    /**
+     * Print a node and its children.
+     *
+     * @param source The root node
+     * @param ignoreFirst Should we ignore the first node.  Used for WorldRoot and ProtoBody
+     */
+    public void traverse(VRMLNode source, boolean ignoreFirst) {
+
+        if(source == null)
+            return;
+
+        if (ignoreFirst)
+            recurseSimpleSceneGraphChild((VRMLNodeType)source);
+        else
+            processSimpleNode(null, -1, (VRMLNodeType)source);
+    }
+
+    /**
+     * Process a single simple node with its callback
+     */
+    private void processSimpleNode(VRMLNodeType parent,
+                                   int field,
+                                   VRMLNodeType kid) {
+
+        boolean use = usedNodes.contains(kid);
+
+        if(!use)
+            usedNodes.add(kid);
+
+        indentUp();
+
+        if (use) {
+            String defName = currentDefMap.get(kid);
+
+            if (defName == null) {
+                errorReporter.warningReport("Can't find DEF for: " + kid, null);
+                printDefMap(currentDefMap);
+            }
+
+            p.print("USE ");
+            p.println(defName);
+
+            indentDown();
+        } else {
+            printStartNode(kid, use, currentDefMap, currentIsMap);
+
+            // now recurse
+            recurseSimpleSceneGraphChild(kid);
+
+            indentDown();
+            printEndNode(kid);
+        }
+    }
+
+    /**
+     * Internal convenience method that separates the startup traversal code
+     * from the recursive mechanism using the detailed detailObs.
+     *
+     * @param parent The root of the current item to traverse
+     */
+    private void recurseSimpleSceneGraphChild(VRMLNodeType parent) {
+
+        int[] fields = parent.getNodeFieldIndices();
+
+        if(fields == null || fields.length == 0)
+            return;
+
+        VRMLFieldData value;
+        boolean printField;
+        boolean printFieldDecl = false;
+        boolean printValue;
+        int accessType;
+        int fieldMetadata = parent.getFieldIndex("metadata");
+
+        if (parent instanceof AbstractDynamicFieldNode)
+            printFieldDecl = true;
+
+        // TODO: likely will fail when proto's are indented correctly
+        printField = indent > 0;
+
+        for(int i = 0; i < fields.length; i++) {
+            printValue = false;
+
+            // This doubles up IS, seems like it should be needed
+/*
+            String is = findIS(parent, fields[i], currentIsMap);
+
+            if (is != null) {
+                VRMLFieldDeclaration decl = parent.getFieldDeclaration(fields[i]);
+                p.print(indentString);
+                p.print(decl.getName());
+                p.print(" IS ");
+                p.println(is);
+                continue;
+            }
+*/
+            try {
+                value = parent.getFieldValue(fields[i]);
+            } catch(InvalidFieldException ife) {
+                continue;
+            }
+
+            if (printFieldDecl && i == fieldMetadata) {
+                if (value.nodeValue == null) {
+                    // ignore empty metadata for script/proto
+                    continue;
+                }
+
+                printFieldDecl = false;
+            }
+
+            if(value.dataType == VRMLFieldData.NODE_ARRAY_DATA) {
+                if (printField) {
+                    VRMLFieldDeclaration decl = parent.getFieldDeclaration(fields[i]);
+                    p.print(indentString);
+                    if (printFieldDecl) {
+                        accessType = decl.getAccessType();
+                        if (accessType == FieldConstants.FIELD ||
+                            accessType == FieldConstants.EXPOSEDFIELD) {
+
+                            printValue = true;
+                        }
+
+                        printDeclNoValue(decl);
+                        p.print(decl.getName());
+
+                        if (printValue)
+                            p.print(" [");
+                    } else {
+                        if (value.numElements != 0) {
+                            p.print(decl.getName());
+                            p.print(" [");
+                        }
+                    }
+                }
+
+                for(int j = 0; j < value.numElements; j++) {
+                    if(value.nodeArrayValues[j] == null)
+                        continue;
+
+                    if (convertOldContent) {
+                        if (value.nodeArrayValues[j].getVRMLNodeName().equals("GeoOrigin") &&
+                            !parent.getFieldDeclaration(fields[i]).getName().equals("geoOrigin")) {
+
+                            continue;
+                        }
+                    }
+
+
+                    processSimpleNode(parent,
+                                      fields[i], value.nodeArrayValues[j]);
+                }
+
+                if (printFieldDecl) {
+                    if (printValue)
+                        p.println("]");
+                    else
+                        p.println();
+                } else if (printField) {
+                    if (value.numElements != 0) {
+                        p.print(indentString);
+                        p.println("]");
+                    } else {
+                        p.println();
+                    }
+                }
+
+            } else {
+                if (value.nodeValue == null && !printFieldDecl)
+                    continue;
+
+                if (printField) {
+                    VRMLFieldDeclaration decl = parent.getFieldDeclaration(fields[i]);
+                    p.print(indentString);
+
+                    if (printFieldDecl) {
+                        printDeclNoValue(decl);
+
+                        accessType = decl.getAccessType();
+                        if (accessType == FieldConstants.FIELD ||
+                            accessType == FieldConstants.EXPOSEDFIELD) {
+
+                            printValue = true;
+                        }
+
+                    }
+
+                    p.print(decl.getName());
+                    p.print(" ");
+
+                    if (value.nodeValue == null && printFieldDecl) {
+                        if (printValue)
+                            p.println("NULL");
+                        else
+                            p.println();
+                        continue;
+                    }
+                }
+
+                processSimpleNode(parent,
+                                  fields[i],
+                                  (VRMLNodeType)value.nodeValue);
+                if (printField && !printFieldDecl)
+                    p.println();
+            }
+        }
+    }
+
+    /**
+     * Print the start of a node, and all its non node fields.
+     *
+     * @param node The node to print
+     * @param use Is it a USE
+     * @param defMap The current mapping of nodes to DEF names
+     * @param isMap The current mapping of fields to IS names
+     */
+    public void printStartScriptNode(AbstractDynamicFieldNode node, boolean use, Map<VRMLNode, String> defMap, Map<Integer, List<ProtoFieldInfo>> isMap) {
+        List<VRMLFieldDeclaration> fields = node.getAllFields();
+
+        Iterator<VRMLFieldDeclaration> itr = fields.iterator();
+
+        int field_must_evaluate = node.getFieldIndex("mustEvaluate");
+        int field_direct_output = node.getFieldIndex("directOutput");
+        int field_url = node.getFieldIndex("url");
+        int field_metadata = node.getFieldIndex("metadata");
+
+        while(itr.hasNext()) {
+            VRMLFieldDeclaration decl = itr.next();
+
+            if(decl == null)
+                continue;
+
+            VRMLFieldData data;
+            int idx = node.getFieldIndex(decl.getName());
+
+            try {
+                data = node.getFieldValue(idx);
+            } catch(InvalidFieldException e) {
+                errorReporter.errorReport("Can't get field: " + decl.getName() +
+                                    " for: " + node, null);
+                continue;
+            }
+
+            if (idx == field_metadata) {
+                // handled elsewhere
+                continue;
+            } else if (idx == field_must_evaluate) {
+                if (data.booleanValue) {
+                    p.print(indentString);
+                    p.print(decl.getName());
+                    p.print(" ");
+
+                    printFieldValue(node, data, decl);
+                }
+                continue;
+            } else if (idx == field_direct_output) {
+                if (data.booleanValue) {
+                    p.print(indentString);
+                    p.print(decl.getName());
+                    p.print(" ");
+
+                    printFieldValue(node, data, decl);
+                }
+                continue;
+            } else if (idx == field_url) {
+                // handled in printEndNode
+                continue;
+            }
+
+            printScriptFieldDecl(node,decl,idx,data,defMap,currentIsMap);
+        }
+
+        indentDown();
+    }
+
+    /**
+     * Print the start of a node, and all its non node fields.
+     *
+     * @param node The node to print
+     * @param use Is it a USE
+     * @param defMap The current mapping of nodes to DEF names
+     * @param isMap The current mapping of fields to IS names
+     */
+    public void printStartNode(VRMLNodeType node, boolean use, Map<VRMLNode, String> defMap, Map<Integer, List<ProtoFieldInfo>> isMap) {
+        String defName = defMap.get(node);
+
+        if (defName != null) {
+            p.print("DEF ");
+            p.print(defName);
+            p.print(" ");
+        }
+
+        String name = node.getVRMLNodeName();
+
+        if (convertOldContent) {
+            String newName = oldProtos.get(name);
+            if (newName != null) {
+                name = newName;
+            }
+        }
+
+        p.print(name);
+        p.println(" {");
+        indentUp();
+
+        if (node instanceof AbstractDynamicFieldNode) {
+            printStartScriptNode((AbstractDynamicFieldNode)node, use, defMap, isMap);
+            return;
+        }
+
+        defaultNode = (VRMLNodeType) defaultNodes.get(name);
+        if (defaultNode == null && !(node instanceof CRProtoInstance)) {
+            defaultNode = (VRMLNodeType) nodeFactory.createVRMLNode(name, false);
+
+            if (defaultNode == null) {
+                errorReporter.errorReport("Could not create node: " + name, null);
+            }
+
+            defaultNodes.put(name,defaultNode);
+        }
+
+        int len = node.getNumFields();
+        int len2;
+        boolean upgradeInline = false;
+        boolean removeWorldUrl = false;
+        HashSet<Integer> urlFields = null;
+        String worldUrl = null;
+
+        if (node instanceof VRMLExternalNodeType) {
+            removeWorldUrl = true;
+            worldUrl = ((VRMLExternalNodeType)node).getWorldUrl();
+
+            urlFields = new HashSet<>();
+
+            if (node instanceof VRMLSingleExternalNodeType) {
+                urlFields.add(node.getFieldIndex("url"));
+            } else {
+                int[] indexes = ((VRMLMultiExternalNodeType)node).getUrlFieldIndexes();
+                for(int i=0; i < indexes.length; i++) {
+                    urlFields.add(indexes[i]);
+                }
+            }
+        }
+
+        if (upgrading) {
+            if (name.equals("Inline")) {
+                upgradeInline = true;
+            }
+        }
+
+        // Create a fields list to approximate a getAllFields for everyone
+        List<VRMLFieldDeclaration> fields = new ArrayList<>();
+
+        if (node instanceof AbstractProto) {
+            List<VRMLFieldDeclaration> pfields = ((VRMLNodeTemplate)node).getAllFields();
+            Iterator<VRMLFieldDeclaration> itr = pfields.iterator();
+            while(itr.hasNext()) {
+                fields.add(itr.next());
+            }
+        } else {
+            for(int i = 0; i < len; i++) {
+                VRMLFieldDeclaration decl = node.getFieldDeclaration(i);
+                fields.add(decl);
+            }
+        }
+
+        Iterator<VRMLFieldDeclaration> itr = fields.iterator();
+        int idx;
+        int didx = 0;
+        String fieldName;
+
+        while(itr.hasNext()) {
+            VRMLFieldDeclaration decl = itr.next();
+            VRMLFieldDeclaration defaultDecl = null;
+
+            if(decl == null)
+                continue;
+
+            fieldName = decl.getName();
+
+            idx = node.getFieldIndex(fieldName);
+            if (defaultNode != null) {
+                didx = defaultNode.getFieldIndex(fieldName);
+                defaultDecl = defaultNode.getFieldDeclaration(didx);
+            }
+
+            String is = findIS(node, idx, isMap);
+
+            if (is != null) {
+                p.print(indentString);
+                p.print(decl.getName());
+                p.print(" IS ");
+                p.println(is);
+                continue;
+            }
+
+            int access = decl.getAccessType();
+            if (access == FieldConstants.EVENTIN || access == FieldConstants.EVENTOUT)
+                continue;
+
+            VRMLFieldData data;
+            try {
+                data = node.getFieldValue(idx);
+
+            } catch(InvalidFieldException e) {
+                //System.out.println("Can't get field: " + decl.getName() + " for: " + node + " named: " + node.getVRMLNodeName());
+                //System.out.println("Index: " + idx);
+                continue;
+            }
+
+            if (defaultNode != null && isDefault(node, decl, didx, data, defaultNode)) {
+                continue;
+            } else if (node instanceof CRProtoInstance) {
+                CRProtoInstance inst = (CRProtoInstance) node;
+
+                if (inst.isDefaultValue(idx))
+                    continue;
+            }
+
+            // Ignore Node types here, they are handled later
+            if (data.dataType == VRMLFieldData.NODE_DATA ||
+                data.dataType == VRMLFieldData.NODE_ARRAY_DATA)
+                    continue;
+
+            if (removeWorldUrl && (urlFields.contains(idx))) {
+                String[] url = data.stringArrayValues;
+
+                if (url != null && worldUrl != null) {
+                    for(int j=0; j < url.length; j++) {
+                        if (url[j] != null && url[j].startsWith(worldUrl)) {
+                            url[j] = url[j].substring(worldUrl.length());
+                        }
+                    }
+
+                    data.stringArrayValues = url;
+                }
+            }
+
+            if (upgradeInline) {
+                if (decl.getName().equals("url")) {
+                    String[] url = data.stringArrayValues;
+
+                    if (url != null) {
+                        for(int j=0; j < url.length; j++) {
+                            int pos = url[j].indexOf(".wrl");
+                            if (pos >= 0) {
+                                url[j] = url[j].substring(0, pos);
+                                url[j] = url[j] + ".x3dv";
+                            }
+                        }
+
+                        data.stringArrayValues = url;
+                    }
+                }
+            }
+
+            p.print(indentString);
+            p.print(decl.getName());
+
+            p.print(" ");
+
+            printFieldValue(node, data, decl);
+        }
+
+        indentDown();
+    }
+
+    /**
+     * Print the end of a node.
+     *
+     * @param node The node
+     */
+    public void printEndNode(VRMLNodeType node) {
+        if (node instanceof AbstractDynamicFieldNode) {
+            indentUp();
+
+            int field_url = node.getFieldIndex("url");
+
+            VRMLFieldDeclaration decl = node.getFieldDeclaration(field_url);
+
+            VRMLFieldData data = null;
+            try {
+                data = node.getFieldValue(field_url);
+
+            } catch(InvalidFieldException e) {
+                StringBuilder buf = new StringBuilder("Can't get field: ");
+                buf.append(decl.getName());
+                buf.append(" for: ");
+                buf.append(node);
+                buf.append(" named: ");
+                buf.append(node.getVRMLNodeName());
+                buf.append("\nIndex: ");
+                buf.append(field_url);
+
+                errorReporter.errorReport(buf.toString(), null);
+            }
+
+            p.print(indentString);
+            p.print(decl.getName());
+            p.print(" ");
+
+            if (upgrading) {
+                String[] urls = new String[data.stringArrayValues.length];
+
+                boolean foundProtocol = false;
+
+                int len = urls.length;
+                int len2;
+
+                for(int i=0; i < len; i++) {
+                    urls[i] = data.stringArrayValues[i];
+
+                    if (!foundProtocol && (urls[i].startsWith("javascript:") ||
+                        urls[i].startsWith("vrmlscript:"))) {
+
+                        urls[i] = "ecmascript:" + urls[i].substring(11);
+                        foundProtocol = true;
+                    }
+
+                    len2 = scriptPatterns.length;
+
+                    for(int j=0; j < len2; j++) {
+                        urls[i] = scriptPatterns[j].matcher(urls[i]).replaceAll(scriptReplacements[j]);
+                    }
+                }
+
+                data.stringArrayValues = urls;
+            }
+            printFieldValue(node, data, decl);
+
+            indentDown();
+        }
+
+        p.print(indentString);
+        p.println("}");
+    }
+
+    //-------------------------------------------------------------------------
+    // SceneGraphTraverserSimpleObserver methods
+    //-------------------------------------------------------------------------
+
+    /**
+     * Notification of a child node.
+     *
+     * @param parent The parent node of this node
+     * @param child The child node that is being observed
+     * @param field The index of the child field in its parent node
+     * @param used true if the node reference is actually a USE
+     */
+    @Override
+    public void observedNode(VRMLNodeType parent,
+                             VRMLNodeType child,
+                             int field,
+                             boolean used) {
+
+        if (child instanceof ProtoInstancePlaceHolder) {
+            protoDeclSet.add(((ProtoInstancePlaceHolder)child).getProtoDefinition());
+        }
+    }
+
+    /**
+     * Print a proto declaration.
+     *
+     * @param proto The decl to print
+     */
+    @Override
+    public void printPrototypeDecl(PrototypeDecl proto) {
+        currentDefMap = new HashMap<>();
+        Map<VRMLNode, String> saveMap = currentDefMap;
+        reverseMap(proto.getDEFMap(), currentDefMap);
+
+        currentIsMap = proto.getISMaps();
+        currentPrototypeDecl = proto;
+
+        VRMLGroupingNodeType body = proto.getBodyGroup();
+        VRMLNodeType[] children = body.getChildren();
+
+        String name = proto.getVRMLNodeName();
+
+        // Create an instance for default removal
+        VRMLNode n = protoCreator.newInstance(proto,
+                                              root,
+                                              majorVersion,
+                                              minorVersion,
+                                              false);
+
+        defaultNodes.put(proto.getVRMLNodeName(), n);
+
+
+        if (convertOldContent && oldProtos.get(name) != null)
+            return;
+
+        p.print(indentString);
+        p.print("PROTO ");
+        p.print(name);
+        p.println(" [");
+
+        indentUp();
+        // Print Proto Interface
+        List<VRMLFieldDeclaration> fields = proto.getAllFields();
+        Iterator<VRMLFieldDeclaration> itr = fields.iterator();
+        int idx;
+        boolean valReq;
+
+        while(itr.hasNext()) {
+            VRMLFieldDeclaration decl = itr.next();
+
+            idx = proto.getFieldIndex(decl.getName());
+            VRMLFieldData val = null;
+            int access = decl.getAccessType();
+
+            if (access != FieldConstants.EVENTIN && access != FieldConstants.EVENTOUT) {
+                val = proto.getFieldValue(idx);
+                valReq = true;
+            } else {
+                valReq = false;
+            }
+
+            if (decl.getName().equals("metadata")) {
+                if (val == null || val.nodeValue == null)
+                continue;
+            }
+
+            printProtoFieldDecl(decl,idx,val,currentDefMap,currentIsMap, valReq);
+        }
+
+        indentDown();
+        p.print(indentString);
+        p.println("] {");
+        indentUp();
+
+        // Find all nested proto's
+        protoDeclSet.clear();
+        for (VRMLNodeType children1 : children) {
+            traverser.reset();
+            traverser.traverseGraph(children1);
+        }
+
+        PrototypeDecl[] pList = new PrototypeDecl[protoDeclSet.size()];
+        protoDeclSet.toArray((VRMLNodeTemplate[])pList);
+
+        for (PrototypeDecl pList1 : pList) {
+            printPrototypeDecl(pList1);
+        }
+
+        // Restore after printing subs, do we need a stack?
+        currentDefMap = saveMap;
+        currentIsMap = proto.getISMaps();
+        currentPrototypeDecl = proto;
+
+        for (VRMLNodeType children1 : children) {
+            p.print(indentString);
+            traverse(children1, false);
+        }
+
+        printImports(proto.getImportDecls());
+
+        Set<ProtoROUTE> routeSet = proto.getRouteDecls();
+        Iterator<ProtoROUTE> ritr = routeSet.iterator();
+
+        while(ritr.hasNext()) {
+            printROUTE(ritr.next(), currentDefMap);
+        }
+
+        indentDown();
+        p.print(indentString);
+        p.println("}");
+    }
+
+    /**
+     * Print an external proto declaration.
+     *
+     * @param proto The decl to print
+     */
+    public void printExternalPrototypeDecl(CRExternPrototypeDecl proto) {
+        currentDefMap = new HashMap<>();
+
+        String name = proto.getVRMLNodeName();
+
+        if (convertOldContent && oldProtos.get(name) != null)
+            return;
+
+        p.print(indentString);
+        p.print("EXTERNPROTO ");
+        p.print(name);
+        p.println(" [");
+
+        indentUp();
+        // Print Proto Interface
+        List<VRMLFieldDeclaration> fields = proto.getAllFields();
+        Iterator<VRMLFieldDeclaration> itr = fields.iterator();
+        int idx;
+
+        while(itr.hasNext()) {
+            VRMLFieldDeclaration decl = itr.next();
+            idx = proto.getFieldIndex(decl.getName());
+            VRMLFieldData val = null;
+
+            // Ignore metadata for EP
+            if (decl.getName().equals("metadata"))
+                continue;
+
+            printProtoFieldDecl(decl,idx,null,currentDefMap,currentIsMap, false);
+        }
+
+        indentDown();
+        p.print(indentString);
+        p.print("] ");
+
+        // The url was saved in epToUrl
+        // Might use getUrl, but it has worldURL baked in
+
+        String[] url = epToUrl.get(proto.getVRMLNodeName());
+
+        p.print("[");
+        int len = url.length;
+
+        for(int i=0; i < len; i++) {
+            p.print("\"");
+
+            if (upgrading) {
+                int pos = url[i].indexOf(".wrl");
+                int locpos = url[i].indexOf("#");
+
+                if (pos >= 0) {
+                    String original = url[i];
+                    url[i] = url[i].substring(0, pos);
+
+                    url[i] = url[i] + ".x3dv";
+
+                    if (locpos > 0) {
+                        String target = original.substring(locpos);
+
+                        url[i] = url[i] + target;
+                    }
+                }
+            }
+
+            p.print(url[i]);
+            p.print("\"");
+
+            if (i != len - 1)
+                p.println();
+        }
+        p.println("]\n");
+        // No defaults for extern protos
+    }
+
+    /**
+     * Determine if a field is a MF* or SF*.
+     *
+     * @return true if a MF*
+     */
+    private boolean isMFField(VRMLFieldDeclaration decl) {
+        int ft = decl.getFieldType();
+
+        // All MF* are even currently.  Change to a switch if that
+        // changes.
+        return ft % 2 == 0;
+    }
+
+    /**
+     * Increment the indent level.  This updates the identString.
+     */
+    private void indentUp() {
+        indent++;
+
+        indentString = indentMap.get(indent);
+
+        if (indentString == null) {
+            StringBuilder buff = new StringBuilder(indent * INDENT_STRING.length());
+
+            for(int i=0; i < indent; i++) {
+                buff.append(INDENT_STRING);
+            }
+
+            indentString = buff.toString();
+            indentMap.put(indent, indentString);
+        }
+    }
+
+    /**
+     * Decrement the indent level.  This updates the identString.
+     */
+    private void indentDown() {
+        indent--;
+
+        indentString = indentMap.get(indent);
+
+        if (indentString == null) {
+            StringBuilder buff = new StringBuilder(indent * INDENT_STRING.length());
+
+            for(int i=0; i < indent; i++) {
+                buff.append(INDENT_STRING);
+            }
+
+            indentString = buff.toString();
+        }
+    }
+
+    private void printProtoFieldDecl(VRMLFieldDeclaration decl, int idx,
+        VRMLFieldData val, Map<VRMLNode, String> defMap, Map<Integer, List<ProtoFieldInfo>> isMap, boolean valRequired) {
+
+        p.print(indentString);
+        int access = decl.getAccessType();
+        switch(access) {
+            case FieldConstants.FIELD:
+                p.print("initializeOnly ");
+                break;
+            case FieldConstants.EXPOSEDFIELD:
+                p.print("inputOutput ");
+                break;
+            case FieldConstants.EVENTIN:
+                p.print("inputOnly ");
+                break;
+            case FieldConstants.EVENTOUT:
+                p.print("outputOnly ");
+                break;
+            default:
+                errorReporter.errorReport("Unknown field type in X3DClassicExporter: " +
+                                    access, null);
+        }
+
+        p.print(decl.getFieldTypeString());
+        p.print(" ");
+        p.print(decl.getName());
+        p.print(" ");
+
+        // Print the field value
+
+        VRMLNode node;
+
+        if (val != null) {
+            switch(val.dataType) {
+                case VRMLFieldData.NODE_DATA:
+                    node = val.nodeValue;
+                    if (node == null)
+                        p.println(" NULL");
+                    else
+                        traverse(node, false);
+
+                    break;
+                case VRMLFieldData.NODE_ARRAY_DATA:
+                    p.println("[");
+                    VRMLNode[] nodes = val.nodeArrayValues;
+                    int len = nodes.length;
+
+                    indentUp();
+                    for(int i=0; i < len; i++) {
+                        p.print(indentString);
+                        traverse(nodes[i], false);
+                    }
+
+                    indentDown();
+                    p.print(indentString);
+                    p.println("]");
+                    break;
+                default:
+                    // NULL node is ok as it will never need name conversion
+                    printFieldValue(null, val, decl);
+            }
+        } else {
+            if (valRequired) {
+                // Null is ok as it will never need name conversion
+                printFieldValue(null, val, decl);
+            }
+
+            p.println();
+        }
+    }
+
+    /**
+     * Print a field decl with the value part.
+     */
+    private void printDeclNoValue(VRMLFieldDeclaration decl) {
+        int access = decl.getAccessType();
+        switch(access) {
+            case FieldConstants.FIELD:
+                p.print("initializeOnly ");
+                break;
+            case FieldConstants.EXPOSEDFIELD:
+                p.print("inputOutput ");
+                break;
+            case FieldConstants.EVENTIN:
+                p.print("inputOnly ");
+                break;
+            case FieldConstants.EVENTOUT:
+                p.print("outputOnly ");
+                break;
+            default:
+                errorReporter.errorReport("Unknown field type in X3DClassicExporter: " +
+                                          access, null);
+        }
+
+        p.print(decl.getFieldTypeString());
+        p.print(" ");
+    }
+
+    /**
+     * Print a script field decl including value.
+     *
+     * @param node The script node
+     * @param decl The field decl
+     * @param idx The field index
+     * @param val The field value
+     * @param defMap The current DEF map
+     * @param isMap The current IS map
+     */
+    private void printScriptFieldDecl(VRMLNodeType node,
+        VRMLFieldDeclaration decl, int idx, VRMLFieldData val, Map<VRMLNode, String> defMap,
+        Map<Integer, List<ProtoFieldInfo>> isMap) {
+
+        String is = findIS(node, idx, isMap);
+
+        if (is == null && val != null && (
+            val.dataType == VRMLFieldData.NODE_DATA ||
+            val.dataType == VRMLFieldData.NODE_ARRAY_DATA)) {
+            // Don't print decl yet
+            return;
+        }
+
+        p.print(indentString);
+
+        printDeclNoValue(decl);
+
+        if (is != null) {
+            p.print(decl.getName());
+            p.print(" ");
+            p.print("IS ");
+            p.println(is);
+            return;
+        }
+
+        int access = decl.getAccessType();
+        if (access == FieldConstants.EVENTIN ||
+            access == FieldConstants.EVENTOUT) {
+
+            p.println(decl.getName());
+            return;
+        }
+
+        // Print the field value
+
+        VRMLNode n;
+
+        if (val != null) {
+            switch(val.dataType) {
+                case VRMLFieldData.NODE_DATA:
+                    // ignore
+                    break;
+                case VRMLFieldData.NODE_ARRAY_DATA:
+                    // ignore
+                    break;
+                default:
+                    p.print(decl.getName());
+                    p.print(" ");
+                    printFieldValue(node, val, decl);
+                    p.println();
+            }
+        }
+    }
+
+    /**
+     * Is this field a default value.
+     *
+     * @param node The node
+     * @param decl The field decl
+     * @param i The field index
+     * @param data The value
+     * @param defaultNode The default node to compare to
+     *
+     * @return true if its a default
+     */
+    private boolean isDefault(VRMLNodeType node, VRMLFieldDeclaration decl, int i,
+        VRMLFieldData data, VRMLNodeType defaultNode) {
+
+        VRMLFieldData defaultData;
+
+        try {
+            defaultData = defaultNode.getFieldValue(i);
+        } catch(InvalidFieldException e) {
+//                e.printStackTrace(System.err);
+            StringBuilder buf = new StringBuilder("Can't get field: ");
+            buf.append(decl.getName());
+            buf.append(" for: ");
+            buf.append(node);
+            buf.append(" named: ");
+            buf.append(node.getVRMLNodeName());
+            buf.append("\nIndex: ");
+            buf.append(i);
+
+            errorReporter.errorReport(buf.toString(), null);
+
+            return false;
+        }
+
+        // No value means a proto instance without a value registered
+        if (data == null)
+            return true;
+
+        boolean same = true;
+        int len2;
+
+        switch(data.dataType) {
+            case VRMLFieldData.BOOLEAN_DATA:
+                if (defaultData.booleanValue != data.booleanValue)
+                    same = false;
+                break;
+            case VRMLFieldData.INT_DATA:
+                if (defaultData.intValue != data.intValue)
+                    same = false;
+                break;
+            case VRMLFieldData.LONG_DATA:
+                if (defaultData.longValue != data.longValue)
+                    same = false;
+                break;
+            case VRMLFieldData.FLOAT_DATA:
+                if (defaultData.floatValue != data.floatValue)
+                    same = false;
+                break;
+            case VRMLFieldData.DOUBLE_DATA:
+                if (defaultData.doubleValue != data.doubleValue)
+                    same = false;
+                break;
+            case VRMLFieldData.STRING_DATA:
+                if (defaultData.stringValue == null) {
+                    return false;
+                }
+
+                if (!defaultData.stringValue.equals(data.stringValue))
+                    same = false;
+                break;
+            case VRMLFieldData.NODE_DATA:
+                // ignore
+                break;
+
+            case VRMLFieldData.BOOLEAN_ARRAY_DATA:
+                if (defaultData.booleanArrayValues == null &&
+                    data.booleanArrayValues == null) {
+
+                    break;
+                }
+
+                if (defaultData.booleanArrayValues == null ||
+                    data.booleanArrayValues == null) {
+
+                    same = false;
+                    break;
+                }
+
+                if (defaultData.booleanArrayValues.length != data.booleanArrayValues.length) {
+                    same = false;
+                    break;
+                }
+                len2 = defaultData.booleanArrayValues.length;
+
+                for(int j=0; j < len2; j++) {
+                    if (defaultData.booleanArrayValues[j] != data.booleanArrayValues[j]) {
+                        same = false;
+                        break;
+                    }
+                }
+                break;
+
+            case VRMLFieldData.INT_ARRAY_DATA:
+                if (defaultData.intArrayValues == null &&
+                    data.intArrayValues == null) {
+
+                    break;
+                }
+
+                if (defaultData.intArrayValues == null ||
+                    data.intArrayValues == null) {
+
+                    same = false;
+                    break;
+                }
+
+                if (defaultData.intArrayValues.length != data.intArrayValues.length) {
+                    same = false;
+                    break;
+                }
+                len2 = defaultData.intArrayValues.length;
+
+                for(int j=0; j < len2; j++) {
+                    if (defaultData.intArrayValues[j] != data.intArrayValues[j]) {
+                        same = false;
+                        break;
+                    }
+                }
+
+                break;
+
+            case VRMLFieldData.LONG_ARRAY_DATA:
+                if (defaultData.longArrayValues == null &&
+                    data.longArrayValues == null) {
+
+                    break;
+                }
+
+                if (defaultData.longArrayValues == null ||
+                    data.longArrayValues == null) {
+
+                    same = false;
+                    break;
+                }
+
+                if (defaultData.longArrayValues.length != data.longArrayValues.length) {
+                    same = false;
+                    break;
+                }
+                len2 = defaultData.longArrayValues.length;
+
+                for(int j=0; j < len2; j++) {
+                    if (defaultData.longArrayValues[j] != data.longArrayValues[j]) {
+                        same = false;
+                        break;
+                    }
+                }
+
+                break;
+
+            case VRMLFieldData.FLOAT_ARRAY_DATA:
+                if (defaultData.floatArrayValues == null &&
+                    data.floatArrayValues == null) {
+
+                    break;
+                }
+
+                if (defaultData.floatArrayValues == null ||
+                    data.floatArrayValues == null) {
+
+                    same = false;
+                    break;
+                }
+
+                if (defaultData.floatArrayValues.length != data.floatArrayValues.length) {
+                    same = false;
+                    break;
+                }
+                len2 = defaultData.floatArrayValues.length;
+
+                for(int j=0; j < len2; j++) {
+                    if (defaultData.floatArrayValues[j] != data.floatArrayValues[j]) {
+                        same = false;
+                        break;
+                    }
+                }
+                break;
+
+            case VRMLFieldData.DOUBLE_ARRAY_DATA:
+                if (defaultData.doubleArrayValues == null &&
+                    data.doubleArrayValues == null) {
+
+                    break;
+                }
+
+                if (defaultData.doubleArrayValues == null ||
+                    data.doubleArrayValues == null) {
+
+                    same = false;
+                    break;
+                }
+
+                if (defaultData.doubleArrayValues.length != data.doubleArrayValues.length) {
+                   same = false;
+                   break;
+                }
+
+                len2 = defaultData.doubleArrayValues.length;
+
+                for(int j=0; j < len2; j++) {
+                    if (defaultData.doubleArrayValues[j] != data.doubleArrayValues[j]) {
+                        same = false;
+                        break;
+                    }
+                }
+
+                break;
+
+            case VRMLFieldData.NODE_ARRAY_DATA:
+                //ignore
+                break;
+
+            case VRMLFieldData.STRING_ARRAY_DATA:
+                if (defaultData.stringArrayValues == null &&
+                    data.stringArrayValues == null) {
+
+                    break;
+                }
+
+                if (defaultData.stringArrayValues == null ||
+                    data.stringArrayValues == null) {
+
+                    same = false;
+                    break;
+                }
+
+                if (defaultData.stringArrayValues.length != data.stringArrayValues.length) {
+                    same = false;
+                    break;
+                }
+                len2 = defaultData.stringArrayValues.length;
+
+                for(int j=0; j < len2; j++) {
+                    if (defaultData.stringArrayValues[j] == null && data.stringArrayValues[j] == null)
+                        continue;
+
+                    if (defaultData.stringArrayValues[j] == null ||
+                        data.stringArrayValues[j] == null) {
+
+                        same = false;
+                        break;
+                    }
+
+                    if (!defaultData.stringArrayValues[j].equals(data.stringArrayValues[j])) {
+                        same = false;
+                        break;
+                    }
+                }
+                break;
+        }
+
+        return same;
+    }
+
+    /**
+     * Print a field value.  Ignores Node fields.
+     *
+     * @param node The node.  Used for field remap, null is ok if not desired.
+     * @param data The data to print
+     * @param decl The field declaration
+     */
+    private void printFieldValue(VRMLNodeType node, VRMLFieldData data, VRMLFieldDeclaration decl) {
+        int len2;
+        boolean ismf;
+        int span;
+        int idx;
+
+        if (data == null) {
+            // All MF* are even currently.  Change to a switch if that
+            // changes.
+
+            int ftype = decl.getFieldType();
+
+            if (ftype % 2 == 0) {
+                p.print("[ ]");
+            } else if (ftype == FieldConstants.SFNODE)
+                p.print("NULL");
+            else {
+                // We have a SF without a value field.  Not sure exactly what do here.
+                // I think its illegal except for SFString.  But it might mean default value.
+                // Handle for SFString, leave a message for others
+                if (ftype == FieldConstants.SFSTRING) {
+                    p.print("\"\"");
+                } else {
+                    errorReporter.warningReport("Empty value field for: " + decl, null);
+                }
+            }
+
+            return;
+        }
+
+        if (convertOldContent && node != null) {
+            String fieldKey = node.getVRMLNodeName() + "." + decl.getName();
+            Integer newFieldType = fieldRemap.get(fieldKey);
+
+            if (newFieldType != null) {
+                int newType = newFieldType;
+
+                convertFieldData(newType, data, decl);
+            }
+        }
+
+        switch(data.dataType) {
+            case VRMLFieldData.NODE_ARRAY_DATA:
+                //ignore, handled elsewhere
+                break;
+
+            case VRMLFieldData.NODE_DATA:
+                // ignore, handled elsewhere
+                break;
+
+            case VRMLFieldData.BOOLEAN_DATA:
+                if (data.booleanValue)
+                    p.println("TRUE");
+                else
+                    p.println("FALSE");
+
+                break;
+
+            case VRMLFieldData.INT_DATA:
+                p.println(data.intValue);
+                break;
+
+            case VRMLFieldData.LONG_DATA:
+                p.println(data.longValue);
+                break;
+
+            case VRMLFieldData.FLOAT_DATA:
+                p.println(data.floatValue);
+                break;
+
+            case VRMLFieldData.DOUBLE_DATA:
+                p.println(data.doubleValue);
+                break;
+
+            case VRMLFieldData.STRING_DATA:
+                if (data.stringValue == null) {
+                    p.println("\"\"");
+                } else {
+                    p.print("\"");
+                    p.print(data.stringValue);
+                    p.println("\"");
+                }
+                break;
+
+            case VRMLFieldData.BOOLEAN_ARRAY_DATA:
+                if (data.booleanArrayValues == null)
+                    break;
+
+                p.print("[");
+                len2 = data.numElements;
+                for(int j=0; j < len2 - 1; j++) {
+                    if(data.booleanArrayValues[j]) {
+                        p.print("TRUE,");
+                    } else {
+                        p.print("FALSE,");
+                    }
+                }
+
+                if(data.booleanArrayValues[len2 - 1]) {
+                    p.print("TRUE");
+                } else {
+                    p.print("FALSE");
+                }
+
+                p.println("]");
+                break;
+
+            case VRMLFieldData.INT_ARRAY_DATA:
+                if (data.intArrayValues == null)
+                    break;
+
+                p.print("[");
+                len2 = data.numElements;
+                for(int j=0; j < len2 - 1; j++) {
+                    p.print(data.intArrayValues[j]);
+                    p.print(" ");
+                }
+
+                p.print(data.intArrayValues[len2 - 1]);
+                p.println("]");
+
+                break;
+
+            case VRMLFieldData.LONG_ARRAY_DATA:
+                if (data.longArrayValues == null)
+                    break;
+
+                p.print("[");
+                len2 = data.numElements;
+                for(int j=0; j < len2 - 1; j++) {
+                    p.print(data.longArrayValues[j]);
+                    p.print(" ");
+                }
+
+                p.print(data.longArrayValues[len2 - 1]);
+                p.println("]");
+                break;
+
+            case VRMLFieldData.FLOAT_ARRAY_DATA:
+                if (data.floatArrayValues == null)
+                    break;
+
+                ismf = isMFField(decl);
+
+                StringBuilder sb = new StringBuilder();
+
+                if (ismf) {
+                    sb.append("[");
+                    len2 = data.numElements;
+
+                    if (len2 > 0) {
+                        span = data.floatArrayValues.length / len2;
+                        idx = 0;
+                        for(int j=0; j < len2; j++) {
+                            for(int k=0; k < span; k++) {
+                                DoubleToString.appendFormatted(sb,data.floatArrayValues[idx++],sigDigits);
+                                //p.print(data.floatArrayValue[idx++]);
+                                if (k != span - 1)
+                                    sb.append(" ");
+                            }
+                            if (j != len2 -1) {
+                                sb.append(", ");
+                            }
+                        }
+                    }
+                    sb.append("]\n");
+                    p.print(sb.toString());
+                } else {
+                    len2 = data.floatArrayValues.length;
+                    for(int j=0; j < len2; j++) {
+                        DoubleToString.appendFormatted(sb,data.floatArrayValues[j],sigDigits);
+
+                        //p.print(data.floatArrayValue[j]);
+                        if (j != len2 -1 )
+                            sb.append(" ");
+                    }
+                    sb.append("\n");
+                    p.print(sb.toString());
+                }
+                break;
+
+            case VRMLFieldData.DOUBLE_ARRAY_DATA:
+                if (data.doubleArrayValues == null)
+                    break;
+
+                ismf = isMFField(decl);
+
+                if (ismf) {
+                    p.print("[");
+                    len2 = data.numElements;
+
+                    if (len2 > 0) {
+                        span = data.doubleArrayValues.length / len2;
+                        idx = 0;
+                        for(int j=0; j < len2; j++) {
+                            for(int k=0; k < span; k++) {
+                                p.print(data.doubleArrayValues[idx++]);
+                                if (k != span - 1)
+                                    p.print(" ");
+                            }
+                            if (j != len2 -1) {
+                                p.print(", ");
+                            }
+                        }
+                    }
+                    p.println("]");
+                } else {
+                    len2 = data.doubleArrayValues.length;
+                    for(int j=0; j < len2; j++) {
+                        p.print(data.doubleArrayValues[j]);
+                        if (j != len2 -1 )
+                            p.print(" ");
+                    }
+                    p.println();
+                }
+                break;
+
+            case VRMLFieldData.STRING_ARRAY_DATA:
+                if (data.stringArrayValues == null)
+                    break;
+
+                p.print("[");
+
+				len2 = data.numElements;
+                if (len2 > 0) {
+					for(int j=0; j < len2 - 1; j++) {
+						p.print("\"");
+						p.print(data.stringArrayValues[j]);
+						p.print("\",");
+					}
+					p.print("\"");
+					p.print(data.stringArrayValues[len2 - 1]);
+					p.print("\"");
+				}
+                p.println("]");
+                break;
+
+            default:
+                errorReporter.messageReport("Unhandled case in switch printFieldValue");
+        }
+    }
+
+}
diff --git a/src/java/org/web3d/vrml/export/X3DXMLRetainedExporter.java b/src/java/org/web3d/vrml/export/X3DXMLRetainedExporter.java
index 19ff8656b2bcaec712b8c63f2100af26327a7d00..d42bced2ac96f7672aeb4a0cdb45f1889db6e887 100644
--- a/src/java/org/web3d/vrml/export/X3DXMLRetainedExporter.java
+++ b/src/java/org/web3d/vrml/export/X3DXMLRetainedExporter.java
@@ -1,128 +1,128 @@
-/****************************************************************************
- *                        Web3d.org Copyright (c) 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-package org.web3d.vrml.export;
-
-// External imports
-import java.io.*;
-
-import org.j3d.util.ErrorReporter;
-
-// Local imports
-import org.web3d.vrml.lang.*;
-import org.web3d.vrml.sav.*;
-
-/**
- * X3D XML exporter using a retained Scenegraph.
- *
- * Known Issues:
- *
- *    Proto node fields are copied into instances
- *
- * @author Alan Hudson
- * @version $Revision: 1.30 $
- */
-public class X3DXMLRetainedExporter extends X3DRetainedSAXExporter {
-
-    /** The output stream */
-    private OutputStream os;
-
-    /**
-     * Create a new exporter for the given spec version
-     *
-     * @param os The stream to export the code to
-     * @param major The major version number of this scene
-     * @param minor The minor version number of this scene
-     * @param errorReporter The error reporter to use
-     */
-    public X3DXMLRetainedExporter(OutputStream os, int major, int minor,
-        ErrorReporter errorReporter) {
-
-        super(major, minor, errorReporter, METHOD_STRINGS, 0);
-
-        this.os = os;
-
-        init();
-    }
-
-    /**
-     * Create a new exporter for the given spec version
-     *
-     * @param os The stream to export the code to
-     * @param major The major version number of this scene
-     * @param minor The minor version number of this scene
-     * @param errorReporter The error reporter to use
-     * @param sigDigits The number of significant digits to use in printing floats
-     */
-    public X3DXMLRetainedExporter(OutputStream os, int major, int minor,
-        ErrorReporter errorReporter, int sigDigits) {
-
-        this(os, major, minor, errorReporter);
-        this.sigDigits = sigDigits;
-    }
-
-    /**
-     *  Common initialization routine.
-     */
-    private void init() {
-        encodingTo = ".x3d";
-        printDocType = true;
-        printXML = true;
-
-        stripWhitespace = false;
-    }
-
-    /**
-     * Declaration of the start of the document. The parameters are all of the
-     * values that are declared on the header line of the file after the
-     * <code>#</code> start. The type string contains the representation of
-     * the first few characters of the file after the #. This allows us to
-     * work out if it is VRML97 or the later X3D spec.
-     * <p>
-     * Version numbers change from VRML97 to X3D and aren't logical. In the
-     * first, it is <code>#VRML V2.0</code> and the second is
-     * <code>#X3D V1.0</code> even though this second header represents a
-     * later spec.
-     *
-     * @param uri The URI of the file.
-     * @param url The base URL of the file for resolving relative URIs
-     *    contained in the file
-     * @param encoding The encoding of this document - utf8 or binary
-     * @param type The bytes of the first part of the file header
-     * @param version The VRML version of this document
-     * @param comment Any trailing text on this line. If there is none, this
-     *    is null.
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document
-     * @throws VRMLException The content provided is invalid for this
-     *   part of the document or can't be parsed
-     */
-    @Override
-    public void startDocument(String uri,
-                              String url,
-                              String encoding,
-                              String type,
-                              String version,
-                              String comment)
-
-        throws SAVException, VRMLException{
-
-        super.startDocument(uri, url, encoding, type, version, comment);
-
-
-        try {
-            handler = new SAXPrinter(new OutputStreamWriter(os, "UTF8"),
-                majorVersion, minorVersion, printDocType, printXML);
-        } catch(IOException ioe) {
-            errorReporter.errorReport(ioe.getMessage(), ioe);
-        }
-    }
-}
+/****************************************************************************
+ *                        Web3d.org Copyright (c) 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+package org.web3d.vrml.export;
+
+// External imports
+import java.io.*;
+
+import org.j3d.util.ErrorReporter;
+
+// Local imports
+import org.web3d.vrml.lang.*;
+import org.web3d.vrml.sav.*;
+
+/**
+ * X3D XML exporter using a retained Scenegraph.
+ *
+ * Known Issues:
+ *
+ *    Proto node fields are copied into instances
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.30 $
+ */
+public class X3DXMLRetainedExporter extends X3DRetainedSAXExporter {
+
+    /** The output stream */
+    private OutputStream os;
+
+    /**
+     * Create a new exporter for the given spec version
+     *
+     * @param os The stream to export the code to
+     * @param major The major version number of this scene
+     * @param minor The minor version number of this scene
+     * @param errorReporter The error reporter to use
+     */
+    public X3DXMLRetainedExporter(OutputStream os, int major, int minor,
+        ErrorReporter errorReporter) {
+
+        super(major, minor, errorReporter, METHOD_STRINGS, 0);
+
+        this.os = os;
+
+        init();
+    }
+
+    /**
+     * Create a new exporter for the given spec version
+     *
+     * @param os The stream to export the code to
+     * @param major The major version number of this scene
+     * @param minor The minor version number of this scene
+     * @param errorReporter The error reporter to use
+     * @param sigDigits The number of significant digits to use in printing floats
+     */
+    public X3DXMLRetainedExporter(OutputStream os, int major, int minor,
+        ErrorReporter errorReporter, int sigDigits) {
+
+        this(os, major, minor, errorReporter);
+        this.sigDigits = sigDigits;
+    }
+
+    /**
+     *  Common initialization routine.
+     */
+    private void init() {
+        encodingTo = ".x3d";
+        printDocType = true;
+        printXML = true;
+
+        stripWhitespace = false;
+    }
+
+    /**
+     * Declaration of the start of the document. The parameters are all of the
+     * values that are declared on the header line of the file after the
+     * <code>#</code> start. The type string contains the representation of
+     * the first few characters of the file after the #. This allows us to
+     * work out if it is VRML97 or the later X3D spec.
+     * <p>
+     * Version numbers change from VRML97 to X3D and aren't logical. In the
+     * first, it is <code>#VRML V2.0</code> and the second is
+     * <code>#X3D V1.0</code> even though this second header represents a
+     * later spec.
+     *
+     * @param uri The URI of the file.
+     * @param url The base URL of the file for resolving relative URIs
+     *    contained in the file
+     * @param encoding The encoding of this document - utf8 or binary
+     * @param type The bytes of the first part of the file header
+     * @param version The VRML version of this document
+     * @param comment Any trailing text on this line. If there is none, this
+     *    is null.
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document
+     * @throws VRMLException The content provided is invalid for this
+     *   part of the document or can't be parsed
+     */
+    @Override
+    public void startDocument(String uri,
+                              String url,
+                              String encoding,
+                              String type,
+                              String version,
+                              String comment)
+
+        throws SAVException, VRMLException{
+
+        super.startDocument(uri, url, encoding, type, version, comment);
+
+
+        try {
+            handler = new SAXPrinter(new OutputStreamWriter(os, "UTF8"),
+                majorVersion, minorVersion, printDocType, printXML);
+        } catch(IOException ioe) {
+            errorReporter.errorReport(ioe.getMessage(), ioe);
+        }
+    }
+}
diff --git a/src/java/org/web3d/vrml/export/compressors/BinaryFieldEncoder.java b/src/java/org/web3d/vrml/export/compressors/BinaryFieldEncoder.java
index 21a08237315fdb10ebc82748a2454c385e7ed18b..c33d3bdf08e26b8b51f9dbb06e7b6c9eeb910086 100644
--- a/src/java/org/web3d/vrml/export/compressors/BinaryFieldEncoder.java
+++ b/src/java/org/web3d/vrml/export/compressors/BinaryFieldEncoder.java
@@ -1,528 +1,528 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2005
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.export.compressors;
-
-// External imports
-import java.io.DataOutputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-
-// Local imports
-import org.web3d.vrml.lang.*;
-
-/**
- * A field compressor that just encodes the data in binary form.
- *
- * @author Alan Hudson
- * @version $Revision: 1.7 $
- */
-public class BinaryFieldEncoder implements FieldCompressor, FieldDecompressor {
-    /** The next length to read */
-    private int len;
-
-    /** Can this fieldCompressor support this compression method
-     *
-     * @param fieldType What type of field, defined in FieldConstants.
-     * @param method What method of compression.  0-127 defined by Web3D Consortium.
-     */
-    @Override
-    public boolean canSupport(int fieldType, int method) {
-        // This class can encode all field types
-        return true;
-    }
-
-    /**
-     * Get the length of variable length field.
-     *
-     * @return The length of the upcoming field in number of type units.
-     */
-    @Override
-    public int nextLength(DataInputStream dis) throws IOException {
-        len = dis.readInt();
-        return len;
-    }
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     */
-    @Override
-    public void compress(DataOutputStream dos, int fieldType, int data)
-        throws IOException {
-        dos.writeInt(data);
-    }
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     */
-    @Override
-    public void compress(DataOutputStream dos, int fieldType, int[] data)
-        throws IOException {
-
-        dos.writeInt(data.length);
-        for(int i=0; i < data.length; i++) {
-            dos.writeInt(data[i]);
-        }
-    }
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     */
-    @Override
-    public void compress(DataOutputStream dos, int fieldType, boolean data)
-        throws IOException {
-        dos.writeBoolean(data);
-    }
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     */
-    @Override
-    public void compress(DataOutputStream dos, int fieldType, boolean[] data)
-        throws IOException {
-        dos.writeInt(data.length);
-        for(int i=0; i < data.length; i++) {
-            dos.writeBoolean(data[i]);
-        }
-    }
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     */
-    @Override
-    public void compress(DataOutputStream dos, int fieldType, float data)
-        throws IOException {
-
-        dos.writeFloat(data);
-    }
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     */
-    @Override
-    public void compress(DataOutputStream dos, int fieldType, float[] data)
-        throws IOException {
-
-
-        switch(fieldType) {
-            case FieldConstants.SFCOLOR:
-            case FieldConstants.SFVEC3F:
-            case FieldConstants.SFROTATION:
-            case FieldConstants.SFCOLORRGBA:
-            case FieldConstants.SFVEC2F:
-                break;
-            case FieldConstants.MFCOLOR:
-            case FieldConstants.MFVEC3F:
-            case FieldConstants.MFFLOAT:
-            case FieldConstants.MFROTATION:
-            case FieldConstants.MFCOLORRGBA:
-            case FieldConstants.MFVEC2F:
-                dos.writeInt(data.length);
-                break;
-            default:
-                System.out.println("Unhandled datatype in compress float[]: " + fieldType);
-        }
-
-        for(int i=0; i < data.length; i++) {
-           dos.writeFloat(data[i]);
-        }
-    }
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     */
-    @Override
-    public void compress(DataOutputStream dos, int fieldType, float[][] data)
-        throws IOException {
-        dos.writeInt(data.length * data[0].length);
-        for (float[] data1 : data) {
-            for (int j = 0; j < data[0].length; j++) {
-                dos.writeFloat(data1[j]);
-            }
-        }
-    }
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     */
-    @Override
-    public void compress(DataOutputStream dos, int fieldType, long data)
-        throws IOException {
-        dos.writeLong(data);
-    }
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     */
-    @Override
-    public void compress(DataOutputStream dos, int fieldType, long[] data)
-        throws IOException {
-
-        dos.writeInt(data.length);
-
-        for(int i=0; i < data.length; i++) {
-           dos.writeLong(data[i]);
-        }
-    }
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     */
-    @Override
-    public void compress(DataOutputStream dos, int fieldType, double data)
-        throws IOException {
-        dos.writeDouble(data);
-    }
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     */
-    @Override
-    public void compress(DataOutputStream dos, int fieldType, double[] data)
-        throws IOException {
-
-        dos.writeInt(data.length);
-        for(int i=0; i < data.length; i++) {
-           dos.writeDouble(data[i]);
-        }
-    }
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     */
-    @Override
-    public void compress(DataOutputStream dos, int fieldType, double[][] data)
-        throws IOException {
-        dos.writeInt(data.length * data[0].length);
-        for (double[] data1 : data) {
-            for (int j = 0; j < data[0].length; j++) {
-                dos.writeDouble(data1[j]);
-            }
-        }
-    }
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     */
-    @Override
-    public void compress(DataOutputStream dos, int fieldType, String data)
-        throws IOException {
-
-        dos.writeUTF(data);
-    }
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     */
-    @Override
-    public void compress(DataOutputStream dos, int fieldType, String[] data)
-        throws IOException {
-        dos.writeInt(data.length);
-        for (String data1 : data) {
-            dos.writeUTF(data1);
-        }
-    }
-
-    /**
-     * Decompress this field.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @return data The field data
-     */
-    @Override
-    public int decompressInt(DataInputStream dis, int fieldType)
-        throws IOException {
-
-        return dis.readInt();
-    }
-
-    /**
-     * Decompress this field.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     */
-    @Override
-    public void decompressInt(DataInputStream dis, int fieldType, int[] data)
-        throws IOException {
-
-        for(int i=0; i < len; i++) {
-            data[i] = dis.readInt();
-        }
-    }
-
-    /**
-     * Decompress this field.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @return The field value
-     */
-    @Override
-    public boolean decompressBoolean(DataInputStream dis, int fieldType)
-        throws IOException {
-
-        return dis.readBoolean();
-    }
-
-    /**
-     * Decompress this field. If the array is too small it will be realloacted.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     */
-    @Override
-    public void decompressBoolean(DataInputStream dis, int fieldType, boolean[] data)
-        throws IOException {
-
-        for(int i=0; i < len; i++) {
-            data[i] = dis.readBoolean();
-        }
-    }
-
-    /**
-     * Decompress this field.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @return The field value
-     */
-    @Override
-    public float decompressFloat(DataInputStream dis, int fieldType)
-        throws IOException {
-        return dis.readFloat();
-    }
-
-    /**
-     * Decompress this field.If the array is too small it will be realloacted.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     */
-    @Override
-    public void decompressFloat(DataInputStream dis, int fieldType, float[] data)
-        throws IOException {
-
-        switch(fieldType) {
-            case FieldConstants.SFCOLOR:
-            case FieldConstants.SFVEC3F:
-                len = 3;
-                break;
-            case FieldConstants.SFROTATION:
-            case FieldConstants.SFCOLORRGBA:
-                len = 4;
-                break;
-            case FieldConstants.SFVEC2F:
-                len = 2;
-                break;
-            case FieldConstants.MFCOLOR:
-            case FieldConstants.MFVEC3F:
-            case FieldConstants.MFFLOAT:
-            case FieldConstants.MFROTATION:
-            case FieldConstants.MFCOLORRGBA:
-            case FieldConstants.MFVEC2F:
-                // Should have already been read
-                break;
-            default:
-                System.out.println("Unhandled datatype in compress float[]: " + fieldType);
-        }
-
-        for(int i=0; i < len; i++) {
-            data[i] = dis.readFloat();
-        }
-    }
-
-    /**
-     * Decompress this field. If the array is too small it will be realloacted.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     */
-    @Override
-    public void decompressFloat(DataInputStream dis, int fieldType, float[][] data)
-        throws IOException {
-
-        // TODO: Is it important to keep the original structure here?
-        for(int i=0; i < len; i++) {
-            data[0][i] = dis.readFloat();
-        }
-    }
-
-    /**
-     * Decompress this field.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @return The field value
-     */
-    @Override
-    public long decompressLong(DataInputStream dis, int fieldType)
-        throws IOException {
-
-        return dis.readLong();
-    }
-
-    /**
-     * Decompress this field. If the array is too small it will be realloacted.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     */
-    @Override
-    public void decompressLong(DataInputStream dis, int fieldType, long[] data)
-        throws IOException {
-
-        for(int i=0; i < len; i++) {
-            data[i] = dis.readLong();
-        }
-    }
-
-    /**
-     * Decompress this field.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @return The field value
-     */
-    @Override
-    public double decompressDouble(DataInputStream dis, int fieldType)
-        throws IOException {
-
-        return dis.readDouble();
-    }
-
-    /**
-     * Decompress this field. If the array is too small it will be realloacted.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     */
-    @Override
-    public void decompressDouble(DataInputStream dis, int fieldType, double[] data)
-        throws IOException {
-
-        for(int i=0; i < len; i++) {
-            data[i] = dis.readDouble();
-        }
-    }
-
-    /**
-     * Decompress this field. If the array is too small it will be realloacted.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     */
-    @Override
-    public void decompressDouble(DataInputStream dis, int fieldType, double[][] data)
-        throws IOException {
-
-        // TODO: Is it important to keep the original structure here?
-        for(int i=0; i < len; i++) {
-            data[0][i] = dis.readDouble();
-        }
-    }
-
-    /**
-     * Decompress this field.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @return The field value
-     */
-    @Override
-    public String decompressString(DataInputStream dis, int fieldType)
-        throws IOException {
-
-
-        return dis.readUTF();
-    }
-
-    /**
-     * Decompress this field. If the array is too small it will be realloacted.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     */
-    @Override
-    public void decompressString(DataInputStream dis, int fieldType, String[] data)
-        throws IOException {
-
-        for(int i=0; i < len; i++) {
-            data[i] = dis.readUTF();
-        }
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001 - 2005
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.export.compressors;
+
+// External imports
+import java.io.DataOutputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+
+// Local imports
+import org.web3d.vrml.lang.*;
+
+/**
+ * A field compressor that just encodes the data in binary form.
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.7 $
+ */
+public class BinaryFieldEncoder implements FieldCompressor, FieldDecompressor {
+    /** The next length to read */
+    private int len;
+
+    /** Can this fieldCompressor support this compression method
+     *
+     * @param fieldType What type of field, defined in FieldConstants.
+     * @param method What method of compression.  0-127 defined by Web3D Consortium.
+     */
+    @Override
+    public boolean canSupport(int fieldType, int method) {
+        // This class can encode all field types
+        return true;
+    }
+
+    /**
+     * Get the length of variable length field.
+     *
+     * @return The length of the upcoming field in number of type units.
+     */
+    @Override
+    public int nextLength(DataInputStream dis) throws IOException {
+        len = dis.readInt();
+        return len;
+    }
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     */
+    @Override
+    public void compress(DataOutputStream dos, int fieldType, int data)
+        throws IOException {
+        dos.writeInt(data);
+    }
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     */
+    @Override
+    public void compress(DataOutputStream dos, int fieldType, int[] data)
+        throws IOException {
+
+        dos.writeInt(data.length);
+        for(int i=0; i < data.length; i++) {
+            dos.writeInt(data[i]);
+        }
+    }
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     */
+    @Override
+    public void compress(DataOutputStream dos, int fieldType, boolean data)
+        throws IOException {
+        dos.writeBoolean(data);
+    }
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     */
+    @Override
+    public void compress(DataOutputStream dos, int fieldType, boolean[] data)
+        throws IOException {
+        dos.writeInt(data.length);
+        for(int i=0; i < data.length; i++) {
+            dos.writeBoolean(data[i]);
+        }
+    }
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     */
+    @Override
+    public void compress(DataOutputStream dos, int fieldType, float data)
+        throws IOException {
+
+        dos.writeFloat(data);
+    }
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     */
+    @Override
+    public void compress(DataOutputStream dos, int fieldType, float[] data)
+        throws IOException {
+
+
+        switch(fieldType) {
+            case FieldConstants.SFCOLOR:
+            case FieldConstants.SFVEC3F:
+            case FieldConstants.SFROTATION:
+            case FieldConstants.SFCOLORRGBA:
+            case FieldConstants.SFVEC2F:
+                break;
+            case FieldConstants.MFCOLOR:
+            case FieldConstants.MFVEC3F:
+            case FieldConstants.MFFLOAT:
+            case FieldConstants.MFROTATION:
+            case FieldConstants.MFCOLORRGBA:
+            case FieldConstants.MFVEC2F:
+                dos.writeInt(data.length);
+                break;
+            default:
+                System.out.println("Unhandled datatype in compress float[]: " + fieldType);
+        }
+
+        for(int i=0; i < data.length; i++) {
+           dos.writeFloat(data[i]);
+        }
+    }
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     */
+    @Override
+    public void compress(DataOutputStream dos, int fieldType, float[][] data)
+        throws IOException {
+        dos.writeInt(data.length * data[0].length);
+        for (float[] data1 : data) {
+            for (int j = 0; j < data[0].length; j++) {
+                dos.writeFloat(data1[j]);
+            }
+        }
+    }
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     */
+    @Override
+    public void compress(DataOutputStream dos, int fieldType, long data)
+        throws IOException {
+        dos.writeLong(data);
+    }
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     */
+    @Override
+    public void compress(DataOutputStream dos, int fieldType, long[] data)
+        throws IOException {
+
+        dos.writeInt(data.length);
+
+        for(int i=0; i < data.length; i++) {
+           dos.writeLong(data[i]);
+        }
+    }
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     */
+    @Override
+    public void compress(DataOutputStream dos, int fieldType, double data)
+        throws IOException {
+        dos.writeDouble(data);
+    }
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     */
+    @Override
+    public void compress(DataOutputStream dos, int fieldType, double[] data)
+        throws IOException {
+
+        dos.writeInt(data.length);
+        for(int i=0; i < data.length; i++) {
+           dos.writeDouble(data[i]);
+        }
+    }
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     */
+    @Override
+    public void compress(DataOutputStream dos, int fieldType, double[][] data)
+        throws IOException {
+        dos.writeInt(data.length * data[0].length);
+        for (double[] data1 : data) {
+            for (int j = 0; j < data[0].length; j++) {
+                dos.writeDouble(data1[j]);
+            }
+        }
+    }
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     */
+    @Override
+    public void compress(DataOutputStream dos, int fieldType, String data)
+        throws IOException {
+
+        dos.writeUTF(data);
+    }
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     */
+    @Override
+    public void compress(DataOutputStream dos, int fieldType, String[] data)
+        throws IOException {
+        dos.writeInt(data.length);
+        for (String data1 : data) {
+            dos.writeUTF(data1);
+        }
+    }
+
+    /**
+     * Decompress this field.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @return data The field data
+     */
+    @Override
+    public int decompressInt(DataInputStream dis, int fieldType)
+        throws IOException {
+
+        return dis.readInt();
+    }
+
+    /**
+     * Decompress this field.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     */
+    @Override
+    public void decompressInt(DataInputStream dis, int fieldType, int[] data)
+        throws IOException {
+
+        for(int i=0; i < len; i++) {
+            data[i] = dis.readInt();
+        }
+    }
+
+    /**
+     * Decompress this field.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @return The field value
+     */
+    @Override
+    public boolean decompressBoolean(DataInputStream dis, int fieldType)
+        throws IOException {
+
+        return dis.readBoolean();
+    }
+
+    /**
+     * Decompress this field. If the array is too small it will be realloacted.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     */
+    @Override
+    public void decompressBoolean(DataInputStream dis, int fieldType, boolean[] data)
+        throws IOException {
+
+        for(int i=0; i < len; i++) {
+            data[i] = dis.readBoolean();
+        }
+    }
+
+    /**
+     * Decompress this field.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @return The field value
+     */
+    @Override
+    public float decompressFloat(DataInputStream dis, int fieldType)
+        throws IOException {
+        return dis.readFloat();
+    }
+
+    /**
+     * Decompress this field.If the array is too small it will be realloacted.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     */
+    @Override
+    public void decompressFloat(DataInputStream dis, int fieldType, float[] data)
+        throws IOException {
+
+        switch(fieldType) {
+            case FieldConstants.SFCOLOR:
+            case FieldConstants.SFVEC3F:
+                len = 3;
+                break;
+            case FieldConstants.SFROTATION:
+            case FieldConstants.SFCOLORRGBA:
+                len = 4;
+                break;
+            case FieldConstants.SFVEC2F:
+                len = 2;
+                break;
+            case FieldConstants.MFCOLOR:
+            case FieldConstants.MFVEC3F:
+            case FieldConstants.MFFLOAT:
+            case FieldConstants.MFROTATION:
+            case FieldConstants.MFCOLORRGBA:
+            case FieldConstants.MFVEC2F:
+                // Should have already been read
+                break;
+            default:
+                System.out.println("Unhandled datatype in compress float[]: " + fieldType);
+        }
+
+        for(int i=0; i < len; i++) {
+            data[i] = dis.readFloat();
+        }
+    }
+
+    /**
+     * Decompress this field. If the array is too small it will be realloacted.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     */
+    @Override
+    public void decompressFloat(DataInputStream dis, int fieldType, float[][] data)
+        throws IOException {
+
+        // TODO: Is it important to keep the original structure here?
+        for(int i=0; i < len; i++) {
+            data[0][i] = dis.readFloat();
+        }
+    }
+
+    /**
+     * Decompress this field.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @return The field value
+     */
+    @Override
+    public long decompressLong(DataInputStream dis, int fieldType)
+        throws IOException {
+
+        return dis.readLong();
+    }
+
+    /**
+     * Decompress this field. If the array is too small it will be realloacted.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     */
+    @Override
+    public void decompressLong(DataInputStream dis, int fieldType, long[] data)
+        throws IOException {
+
+        for(int i=0; i < len; i++) {
+            data[i] = dis.readLong();
+        }
+    }
+
+    /**
+     * Decompress this field.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @return The field value
+     */
+    @Override
+    public double decompressDouble(DataInputStream dis, int fieldType)
+        throws IOException {
+
+        return dis.readDouble();
+    }
+
+    /**
+     * Decompress this field. If the array is too small it will be realloacted.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     */
+    @Override
+    public void decompressDouble(DataInputStream dis, int fieldType, double[] data)
+        throws IOException {
+
+        for(int i=0; i < len; i++) {
+            data[i] = dis.readDouble();
+        }
+    }
+
+    /**
+     * Decompress this field. If the array is too small it will be realloacted.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     */
+    @Override
+    public void decompressDouble(DataInputStream dis, int fieldType, double[][] data)
+        throws IOException {
+
+        // TODO: Is it important to keep the original structure here?
+        for(int i=0; i < len; i++) {
+            data[0][i] = dis.readDouble();
+        }
+    }
+
+    /**
+     * Decompress this field.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @return The field value
+     */
+    @Override
+    public String decompressString(DataInputStream dis, int fieldType)
+        throws IOException {
+
+
+        return dis.readUTF();
+    }
+
+    /**
+     * Decompress this field. If the array is too small it will be realloacted.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     */
+    @Override
+    public void decompressString(DataInputStream dis, int fieldType, String[] data)
+        throws IOException {
+
+        for(int i=0; i < len; i++) {
+            data[i] = dis.readUTF();
+        }
+    }
+}
diff --git a/src/java/org/web3d/vrml/export/compressors/BitPacker.java b/src/java/org/web3d/vrml/export/compressors/BitPacker.java
index 5d581ab89bd1d0eb791c092935b7ecc9ec574d64..9cf2c0f4dee393703bde57b2aa4869051cb62118 100644
--- a/src/java/org/web3d/vrml/export/compressors/BitPacker.java
+++ b/src/java/org/web3d/vrml/export/compressors/BitPacker.java
@@ -1,95 +1,95 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-package org.web3d.vrml.export.compressors;
-
-// Standard library imports
-
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-// Application specific imports
-// None
-
-/**
- * Pack a stream of integers of variables bits into a packed form.
- * Loosely copied from Johnathon Blow's "Packing Integers" article.
- *
- * @author Alan Hudson
- * @version $Revision: 1.4 $
- */
-public class BitPacker {
-    
-    private int next_bit_to_write;
-    private byte buffer[];
-
-    /**
-     * Construct a bit packer.
-     *
-     * @param maxLength The maximum length in bytes of the stream to pack.
-     */
-    public BitPacker(int maxLength) {
-        next_bit_to_write = 0;
-        buffer = new byte[maxLength];
-    }
-
-    /**
-     * Get the size of the result.  This will be the number of bytes
-     * used, not the maximum length.
-     * @return
-     */
-    public int size() {
-        return (next_bit_to_write + 7) / 8;
-    }
-
-    /**
-     * Get the result of the packing.  Use size to preallocate the result array.
-     * @param result
-     */
-    public void getResult(byte[] result) {
-        System.arraycopy(buffer, 0, result, 0, (next_bit_to_write + 7) / 8);
-    }
-
-    /**
-     * Pack this value using num_bits.
-     * @param value
-     * @param num_bits
-     */
-    public void pack(int value, int num_bits) {
-        while (num_bits > 0) {
-            int byte_index = (next_bit_to_write / 8);
-            int bit_index =  (next_bit_to_write % 8);
-
-            int src_mask = (1 << (num_bits - 1));
-            byte dest_mask = (byte) (1 << (7 - bit_index));
-
-            if ((value & src_mask) != 0)
-                buffer[byte_index] |= dest_mask;
-
-            next_bit_to_write++;
-            num_bits--;
-        }
-    }
-
-    /**
-     * Write this stream out to a stream.  Only writes
-     * the bytes used, not the maximum size.
-     * @param dos
-     * @throws java.io.IOException
-     */
-    public void writeStream(DataOutputStream dos) throws IOException {
-        int size = size();
-
-        for(int i=0; i < size; i++) {
-            dos.writeByte(buffer[i]);
-        }
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+package org.web3d.vrml.export.compressors;
+
+// Standard library imports
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+// Application specific imports
+// None
+
+/**
+ * Pack a stream of integers of variables bits into a packed form.
+ * Loosely copied from Johnathon Blow's "Packing Integers" article.
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.4 $
+ */
+public class BitPacker {
+    
+    private int next_bit_to_write;
+    private byte buffer[];
+
+    /**
+     * Construct a bit packer.
+     *
+     * @param maxLength The maximum length in bytes of the stream to pack.
+     */
+    public BitPacker(int maxLength) {
+        next_bit_to_write = 0;
+        buffer = new byte[maxLength];
+    }
+
+    /**
+     * Get the size of the result.  This will be the number of bytes
+     * used, not the maximum length.
+     * @return
+     */
+    public int size() {
+        return (next_bit_to_write + 7) / 8;
+    }
+
+    /**
+     * Get the result of the packing.  Use size to preallocate the result array.
+     * @param result
+     */
+    public void getResult(byte[] result) {
+        System.arraycopy(buffer, 0, result, 0, (next_bit_to_write + 7) / 8);
+    }
+
+    /**
+     * Pack this value using num_bits.
+     * @param value
+     * @param num_bits
+     */
+    public void pack(int value, int num_bits) {
+        while (num_bits > 0) {
+            int byte_index = (next_bit_to_write / 8);
+            int bit_index =  (next_bit_to_write % 8);
+
+            int src_mask = (1 << (num_bits - 1));
+            byte dest_mask = (byte) (1 << (7 - bit_index));
+
+            if ((value & src_mask) != 0)
+                buffer[byte_index] |= dest_mask;
+
+            next_bit_to_write++;
+            num_bits--;
+        }
+    }
+
+    /**
+     * Write this stream out to a stream.  Only writes
+     * the bytes used, not the maximum size.
+     * @param dos
+     * @throws java.io.IOException
+     */
+    public void writeStream(DataOutputStream dos) throws IOException {
+        int size = size();
+
+        for(int i=0; i < size; i++) {
+            dos.writeByte(buffer[i]);
+        }
+    }
+}
diff --git a/src/java/org/web3d/vrml/export/compressors/BitUnpacker.java b/src/java/org/web3d/vrml/export/compressors/BitUnpacker.java
index a66169c33bb406b5eac588067e0b8b105d87c78f..d9103cc4d455416d6c489873e9ec05549ad6042b 100644
--- a/src/java/org/web3d/vrml/export/compressors/BitUnpacker.java
+++ b/src/java/org/web3d/vrml/export/compressors/BitUnpacker.java
@@ -1,145 +1,145 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-package org.web3d.vrml.export.compressors;
-
-// Standard library imports
-// None
-
-/**
- * UnPack a stream of integers of variables bits from a packed form.
- * Loosely copied from Johnathon Blow's "Packing Integers" article.
- *
- * @author Alan Hudson
- * @version $Revision: 1.3 $
- */
-public class BitUnpacker {
-    // TODO: Does this need to be a long?
-    /** The number of bits remaing to be read */
-    private int num_bits_remaining;
-
-    /** The buffer to read frame */
-    private byte buffer[];
-
-    /** The next bit to read */
-    private int next_bit_to_read;
-
-    /**
-     * Construct a bit unpacker.
-     *
-     * @param buffer The buffer to decode.
-     */
-    public BitUnpacker(byte[] buffer) {
-        num_bits_remaining = buffer.length * 8;
-        this.buffer = buffer;
-        next_bit_to_read = 0;
-    }
-
-    /**
-     * Unpack a number of bits.
-     * @param num_bits
-     * @return
-     */
-    public int unpack(int num_bits) {
-        int result=0;
-
-        if (num_bits > num_bits_remaining)
-            throw new RuntimeException("Trying to read more bits then are left in BitUnpacker");
-
-        num_bits_remaining -= num_bits;
-
-        int sign_mask;
-
-        if (num_bits < 32)
-            sign_mask = -1 << num_bits;
-        else
-            sign_mask = -1 << 31;
-
-        int byte_index;
-        int bit_index;
-
-        int src_mask;
-        int dest_mask;
-        boolean signed = false;
-        boolean first = true;
-
-        while(num_bits > 0) {
-            byte_index = (next_bit_to_read / 8);
-            bit_index = (next_bit_to_read % 8);
-
-            src_mask = (1 << (7 - bit_index));
-            dest_mask = (1 << (num_bits -1 ));
-
-            if ((buffer[byte_index] & src_mask) != 0) {
-                if (first)
-                    signed = true;
-
-                result |= dest_mask;
-            }
-
-            first = false;
-//System.out.println("src: " + Integer.toBinaryString(src_mask) + " dest: " + Integer.toBinaryString(dest_mask) + " res: " + Integer.toBinaryString(result));
-
-            num_bits--;
-            next_bit_to_read++;
-        }
-
-        if (signed) {
-//System.out.println("signed.  mask: " + Integer.toBinaryString(sign_mask));
-            return result | sign_mask;
-        }
-
-        return result;
-    }
-
-    /**
-     * Set this bit unpacker to a new value.  Resets the
-     * position to the beginning.
-     * @param buffer
-     */
-     public void reset(byte[] buffer) {
-        num_bits_remaining = buffer.length * 8;
-        this.buffer = buffer;
-        next_bit_to_read = 0;
-     }
-
-    /**
-     * Get the number of bits remaining to be processed.
-     *
-     * @return The number of bits left to process.
-     */
-    public long getNumBitsRemaining() {
-        return num_bits_remaining;
-    }
-
-    /**
-     * Small test of unpack/pack routines.
-     * @param args
-     */
-    public static void main(String args[]) {
-        BitPacker bp = new BitPacker(3);
-        byte[] result;
-
-        bp.pack(0,4);
-        bp.pack(82,7);
-        bp.pack(69,7);
-
-        result = new byte[bp.size()];
-        bp.getResult(result);
-
-        BitUnpacker bup = new BitUnpacker(result);
-        int i;
-
-        System.out.println(bup.unpack(4));
-        System.out.println(bup.unpack(7));
-        System.out.println(bup.unpack(7));
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+package org.web3d.vrml.export.compressors;
+
+// Standard library imports
+// None
+
+/**
+ * UnPack a stream of integers of variables bits from a packed form.
+ * Loosely copied from Johnathon Blow's "Packing Integers" article.
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.3 $
+ */
+public class BitUnpacker {
+    // TODO: Does this need to be a long?
+    /** The number of bits remaing to be read */
+    private int num_bits_remaining;
+
+    /** The buffer to read frame */
+    private byte buffer[];
+
+    /** The next bit to read */
+    private int next_bit_to_read;
+
+    /**
+     * Construct a bit unpacker.
+     *
+     * @param buffer The buffer to decode.
+     */
+    public BitUnpacker(byte[] buffer) {
+        num_bits_remaining = buffer.length * 8;
+        this.buffer = buffer;
+        next_bit_to_read = 0;
+    }
+
+    /**
+     * Unpack a number of bits.
+     * @param num_bits
+     * @return
+     */
+    public int unpack(int num_bits) {
+        int result=0;
+
+        if (num_bits > num_bits_remaining)
+            throw new RuntimeException("Trying to read more bits then are left in BitUnpacker");
+
+        num_bits_remaining -= num_bits;
+
+        int sign_mask;
+
+        if (num_bits < 32)
+            sign_mask = -1 << num_bits;
+        else
+            sign_mask = -1 << 31;
+
+        int byte_index;
+        int bit_index;
+
+        int src_mask;
+        int dest_mask;
+        boolean signed = false;
+        boolean first = true;
+
+        while(num_bits > 0) {
+            byte_index = (next_bit_to_read / 8);
+            bit_index = (next_bit_to_read % 8);
+
+            src_mask = (1 << (7 - bit_index));
+            dest_mask = (1 << (num_bits -1 ));
+
+            if ((buffer[byte_index] & src_mask) != 0) {
+                if (first)
+                    signed = true;
+
+                result |= dest_mask;
+            }
+
+            first = false;
+//System.out.println("src: " + Integer.toBinaryString(src_mask) + " dest: " + Integer.toBinaryString(dest_mask) + " res: " + Integer.toBinaryString(result));
+
+            num_bits--;
+            next_bit_to_read++;
+        }
+
+        if (signed) {
+//System.out.println("signed.  mask: " + Integer.toBinaryString(sign_mask));
+            return result | sign_mask;
+        }
+
+        return result;
+    }
+
+    /**
+     * Set this bit unpacker to a new value.  Resets the
+     * position to the beginning.
+     * @param buffer
+     */
+     public void reset(byte[] buffer) {
+        num_bits_remaining = buffer.length * 8;
+        this.buffer = buffer;
+        next_bit_to_read = 0;
+     }
+
+    /**
+     * Get the number of bits remaining to be processed.
+     *
+     * @return The number of bits left to process.
+     */
+    public long getNumBitsRemaining() {
+        return num_bits_remaining;
+    }
+
+    /**
+     * Small test of unpack/pack routines.
+     * @param args
+     */
+    public static void main(String args[]) {
+        BitPacker bp = new BitPacker(3);
+        byte[] result;
+
+        bp.pack(0,4);
+        bp.pack(82,7);
+        bp.pack(69,7);
+
+        result = new byte[bp.size()];
+        bp.getResult(result);
+
+        BitUnpacker bup = new BitUnpacker(result);
+        int i;
+
+        System.out.println(bup.unpack(4));
+        System.out.println(bup.unpack(7));
+        System.out.println(bup.unpack(7));
+    }
+}
diff --git a/src/java/org/web3d/vrml/export/compressors/FieldCompressor.java b/src/java/org/web3d/vrml/export/compressors/FieldCompressor.java
index 1ec918a85a74b53ebdfd2058bc1c7386388ca959..cf740bf26df99bc89937b53fb635c4e61a367adc 100644
--- a/src/java/org/web3d/vrml/export/compressors/FieldCompressor.java
+++ b/src/java/org/web3d/vrml/export/compressors/FieldCompressor.java
@@ -1,191 +1,191 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-package org.web3d.vrml.export.compressors;
-
-// Standard library imports
-
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-// Application specific imports
-// None
-
-/**
- * All classes capable of compressing a field must implement this interface
- *
- * @author Alan Hudson.
- * @version $Revision: 1.3 $
- */
-public interface FieldCompressor {
-
-    /** Can this fieldCompressor support this compression method
-     *
-     * @param fieldType What type of field, defined in FieldConstants.
-     * @param method What method of compression.  0-127 defined by Web3D Consortium.
-     * @return 
-     */
-    boolean canSupport(int fieldType, int method);
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     * @throws java.io.IOException
-     */
-    void compress(DataOutputStream dos, int fieldType, int data)
-        throws IOException;
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     * @throws java.io.IOException
-     */
-    void compress(DataOutputStream dos, int fieldType, int[] data)
-        throws IOException;
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     * @throws java.io.IOException
-     */
-    void compress(DataOutputStream dos, int fieldType, boolean data)
-        throws IOException;
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     * @throws java.io.IOException
-     */
-    void compress(DataOutputStream dos, int fieldType, boolean[] data)
-        throws IOException;
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     * @throws java.io.IOException
-     */
-    void compress(DataOutputStream dos, int fieldType, float data)
-        throws IOException;
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     * @throws java.io.IOException
-     */
-    void compress(DataOutputStream dos, int fieldType, float[] data)
-        throws IOException;
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     * @throws java.io.IOException
-     */
-    void compress(DataOutputStream dos, int fieldType, float[][] data)
-        throws IOException;
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     * @throws java.io.IOException
-     */
-    void compress(DataOutputStream dos, int fieldType, long data)
-        throws IOException;
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     * @throws java.io.IOException
-     */
-    void compress(DataOutputStream dos, int fieldType, long[] data)
-        throws IOException;
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     * @throws java.io.IOException
-     */
-    void compress(DataOutputStream dos, int fieldType, double data)
-        throws IOException;
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     * @throws java.io.IOException
-     */
-    void compress(DataOutputStream dos, int fieldType, double[] data)
-        throws IOException;
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     * @throws java.io.IOException
-     */
-    void compress(DataOutputStream dos, int fieldType, double[][] data)
-        throws IOException;
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     * @throws java.io.IOException
-     */
-    void compress(DataOutputStream dos, int fieldType, String data)
-        throws IOException;
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     * @throws java.io.IOException
-     */
-    void compress(DataOutputStream dos, int fieldType, String[] data)
-        throws IOException;
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+package org.web3d.vrml.export.compressors;
+
+// Standard library imports
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+// Application specific imports
+// None
+
+/**
+ * All classes capable of compressing a field must implement this interface
+ *
+ * @author Alan Hudson.
+ * @version $Revision: 1.3 $
+ */
+public interface FieldCompressor {
+
+    /** Can this fieldCompressor support this compression method
+     *
+     * @param fieldType What type of field, defined in FieldConstants.
+     * @param method What method of compression.  0-127 defined by Web3D Consortium.
+     * @return 
+     */
+    boolean canSupport(int fieldType, int method);
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     * @throws java.io.IOException
+     */
+    void compress(DataOutputStream dos, int fieldType, int data)
+        throws IOException;
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     * @throws java.io.IOException
+     */
+    void compress(DataOutputStream dos, int fieldType, int[] data)
+        throws IOException;
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     * @throws java.io.IOException
+     */
+    void compress(DataOutputStream dos, int fieldType, boolean data)
+        throws IOException;
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     * @throws java.io.IOException
+     */
+    void compress(DataOutputStream dos, int fieldType, boolean[] data)
+        throws IOException;
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     * @throws java.io.IOException
+     */
+    void compress(DataOutputStream dos, int fieldType, float data)
+        throws IOException;
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     * @throws java.io.IOException
+     */
+    void compress(DataOutputStream dos, int fieldType, float[] data)
+        throws IOException;
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     * @throws java.io.IOException
+     */
+    void compress(DataOutputStream dos, int fieldType, float[][] data)
+        throws IOException;
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     * @throws java.io.IOException
+     */
+    void compress(DataOutputStream dos, int fieldType, long data)
+        throws IOException;
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     * @throws java.io.IOException
+     */
+    void compress(DataOutputStream dos, int fieldType, long[] data)
+        throws IOException;
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     * @throws java.io.IOException
+     */
+    void compress(DataOutputStream dos, int fieldType, double data)
+        throws IOException;
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     * @throws java.io.IOException
+     */
+    void compress(DataOutputStream dos, int fieldType, double[] data)
+        throws IOException;
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     * @throws java.io.IOException
+     */
+    void compress(DataOutputStream dos, int fieldType, double[][] data)
+        throws IOException;
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     * @throws java.io.IOException
+     */
+    void compress(DataOutputStream dos, int fieldType, String data)
+        throws IOException;
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     * @throws java.io.IOException
+     */
+    void compress(DataOutputStream dos, int fieldType, String[] data)
+        throws IOException;
+}
diff --git a/src/java/org/web3d/vrml/export/compressors/FieldDecompressor.java b/src/java/org/web3d/vrml/export/compressors/FieldDecompressor.java
index 4a41ea2a87a9d9f2d4685b1b112840dac0a17659..304df7a34a88fc925c7d8df554eb082ba692c604 100644
--- a/src/java/org/web3d/vrml/export/compressors/FieldDecompressor.java
+++ b/src/java/org/web3d/vrml/export/compressors/FieldDecompressor.java
@@ -1,201 +1,201 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.export.compressors;
-
-// External imports
-import java.io.DataInputStream;
-import java.io.IOException;
-
-// Local imports
-// None
-
-/**
- * All classes capable of decompressing a field must implement this interface
- *
- * @author Alan Hudson.
- * @version $Revision: 1.4 $
- */
-public interface FieldDecompressor {
-
-    /**
-     * Can this fieldCompressor support this compression method
-     *
-     * @param fieldType What type of field, defined in FieldConstants.
-     * @param method What method of compression.  0-127 defined by Web3D Consortium.
-     * @return
-     */
-    boolean canSupport(int fieldType, int method);
-
-    /**
-     * Get the length of variable length field.
-     *
-     * @param dis
-     * @return The length of the upcoming field in number of type units.
-     * @throws java.io.IOException
-     */
-    int nextLength(DataInputStream dis) throws IOException;
-
-    /**
-     * Decompress this field.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @return The field value
-     * @throws java.io.IOException
-     */
-    int decompressInt(DataInputStream dis, int fieldType)
-        throws IOException;
-
-    /**
-     * Decompress this field.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data, must be preallocated
-     * @throws java.io.IOException
-     */
-    void decompressInt(DataInputStream dis, int fieldType, int[] data)
-        throws IOException;
-
-    /**
-     * Decompress this field.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @return The field value
-     * @throws java.io.IOException
-     */
-    boolean decompressBoolean(DataInputStream dis, int fieldType)
-        throws IOException;
-
-    /**
-     * Decompress this field.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data, must be preallocated
-     * @throws java.io.IOException
-     */
-    void decompressBoolean(DataInputStream dis, int fieldType, boolean[] data)
-        throws IOException;
-
-    /**
-     * Decompress this field.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @return The field value
-     * @throws java.io.IOException
-     */
-    float decompressFloat(DataInputStream dis, int fieldType)
-        throws IOException;
-
-    /**
-     * Decompress this field.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data, must be preallocated
-     * @throws java.io.IOException
-     */
-    void decompressFloat(DataInputStream dis, int fieldType, float[] data)
-        throws IOException;
-
-    /**
-     * Decompress this field.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data, must be preallocated
-     * @throws java.io.IOException
-     */
-    void decompressFloat(DataInputStream dis, int fieldType, float[][] data)
-        throws IOException;
-
-    /**
-     * Decompress this field.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @return The field value
-     * @throws java.io.IOException
-     */
-    long decompressLong(DataInputStream dis, int fieldType)
-        throws IOException;
-
-    /**
-     * Decompress this field.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data, must be preallocated
-     * @throws java.io.IOException
-     */
-    void decompressLong(DataInputStream dis, int fieldType, long[] data)
-        throws IOException;
-
-    /**
-     * Decompress this field.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @return The field value
-     * @throws java.io.IOException
-     */
-    double decompressDouble(DataInputStream dis, int fieldType)
-        throws IOException;
-
-    /**
-     * Decompress this field.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data, must be preallocated
-     * @throws java.io.IOException
-     */
-    void decompressDouble(DataInputStream dis, int fieldType, double[] data)
-        throws IOException;
-
-    /**
-     * Decompress this field.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data, must be preallocated
-     * @throws java.io.IOException
-     */
-    void decompressDouble(DataInputStream dis, int fieldType, double[][] data)
-        throws IOException;
-
-    /**
-     * Decompress this field.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @return The field value
-     * @throws java.io.IOException
-     */
-    String decompressString(DataInputStream dis, int fieldType)
-        throws IOException;
-
-    /**
-     * Decompress this field.
-     *
-     * @param dis The stream to read from
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data, must be preallocated
-     * @throws java.io.IOException
-     */
-    void decompressString(DataInputStream dis, int fieldType, String[] data)
-        throws IOException;
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.export.compressors;
+
+// External imports
+import java.io.DataInputStream;
+import java.io.IOException;
+
+// Local imports
+// None
+
+/**
+ * All classes capable of decompressing a field must implement this interface
+ *
+ * @author Alan Hudson.
+ * @version $Revision: 1.4 $
+ */
+public interface FieldDecompressor {
+
+    /**
+     * Can this fieldCompressor support this compression method
+     *
+     * @param fieldType What type of field, defined in FieldConstants.
+     * @param method What method of compression.  0-127 defined by Web3D Consortium.
+     * @return
+     */
+    boolean canSupport(int fieldType, int method);
+
+    /**
+     * Get the length of variable length field.
+     *
+     * @param dis
+     * @return The length of the upcoming field in number of type units.
+     * @throws java.io.IOException
+     */
+    int nextLength(DataInputStream dis) throws IOException;
+
+    /**
+     * Decompress this field.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @return The field value
+     * @throws java.io.IOException
+     */
+    int decompressInt(DataInputStream dis, int fieldType)
+        throws IOException;
+
+    /**
+     * Decompress this field.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data, must be preallocated
+     * @throws java.io.IOException
+     */
+    void decompressInt(DataInputStream dis, int fieldType, int[] data)
+        throws IOException;
+
+    /**
+     * Decompress this field.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @return The field value
+     * @throws java.io.IOException
+     */
+    boolean decompressBoolean(DataInputStream dis, int fieldType)
+        throws IOException;
+
+    /**
+     * Decompress this field.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data, must be preallocated
+     * @throws java.io.IOException
+     */
+    void decompressBoolean(DataInputStream dis, int fieldType, boolean[] data)
+        throws IOException;
+
+    /**
+     * Decompress this field.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @return The field value
+     * @throws java.io.IOException
+     */
+    float decompressFloat(DataInputStream dis, int fieldType)
+        throws IOException;
+
+    /**
+     * Decompress this field.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data, must be preallocated
+     * @throws java.io.IOException
+     */
+    void decompressFloat(DataInputStream dis, int fieldType, float[] data)
+        throws IOException;
+
+    /**
+     * Decompress this field.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data, must be preallocated
+     * @throws java.io.IOException
+     */
+    void decompressFloat(DataInputStream dis, int fieldType, float[][] data)
+        throws IOException;
+
+    /**
+     * Decompress this field.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @return The field value
+     * @throws java.io.IOException
+     */
+    long decompressLong(DataInputStream dis, int fieldType)
+        throws IOException;
+
+    /**
+     * Decompress this field.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data, must be preallocated
+     * @throws java.io.IOException
+     */
+    void decompressLong(DataInputStream dis, int fieldType, long[] data)
+        throws IOException;
+
+    /**
+     * Decompress this field.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @return The field value
+     * @throws java.io.IOException
+     */
+    double decompressDouble(DataInputStream dis, int fieldType)
+        throws IOException;
+
+    /**
+     * Decompress this field.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data, must be preallocated
+     * @throws java.io.IOException
+     */
+    void decompressDouble(DataInputStream dis, int fieldType, double[] data)
+        throws IOException;
+
+    /**
+     * Decompress this field.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data, must be preallocated
+     * @throws java.io.IOException
+     */
+    void decompressDouble(DataInputStream dis, int fieldType, double[][] data)
+        throws IOException;
+
+    /**
+     * Decompress this field.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @return The field value
+     * @throws java.io.IOException
+     */
+    String decompressString(DataInputStream dis, int fieldType)
+        throws IOException;
+
+    /**
+     * Decompress this field.
+     *
+     * @param dis The stream to read from
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data, must be preallocated
+     * @throws java.io.IOException
+     */
+    void decompressString(DataInputStream dis, int fieldType, String[] data)
+        throws IOException;
+}
diff --git a/src/java/org/web3d/vrml/export/compressors/FloatPacker.java b/src/java/org/web3d/vrml/export/compressors/FloatPacker.java
index 35a01fd8a287469eb721d37ac5cc5e167d9838fb..d929885f7c6e53736a7d6a0da1308fb9bb76576d 100644
--- a/src/java/org/web3d/vrml/export/compressors/FloatPacker.java
+++ b/src/java/org/web3d/vrml/export/compressors/FloatPacker.java
@@ -1,204 +1,204 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2004-2010
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-package org.web3d.vrml.export.compressors;
-
-/**
- * Compresses float by using quanitization.
- *
- * @author Alan Hudson
- * @version $Revision: 1.6 $
- */
-public class FloatPacker {
-
-    private static final int MANTISSA_BITS_32 = 23;
-    private static final long EXPONENT_BITS_32 = 8;
-    private static final long MANTISSA_MASK_32 = 0x007fffff;
-    private static final long EXPONENT_MASK_32 = 0x7f800000;
-    private static final long SIGN_MASK_32     = 0x80000000;
-    private static final int EXPONENT_BIAS_32 = 127;
-    private static final int SIGN_SHIFT_32    = 31;
-
-    private int exponent_bits, mantissa_bits;
-    private boolean signed;
-    private int sign_mask, mantissa_mask, exponent_mask;
-    private int exponent_bias;
-    private int sign_shift;
-
-    private int exponent_min, exponent_max;
-
-    public FloatPacker(int num_exponent_bits, int num_mantissa_bits) {
-        init(num_exponent_bits, num_mantissa_bits, true);
-    }
-
-    public FloatPacker(int num_exponent_bits, int num_mantissa_bits, boolean signed) {
-        init(num_exponent_bits, num_mantissa_bits, signed);
-    }
-
-    private void init(int num_exponent_bits, int num_mantissa_bits, boolean signed) {
-        this.signed = signed;
-        exponent_bits = num_exponent_bits;
-        mantissa_bits = num_mantissa_bits;
-        exponent_bias = (1 << (exponent_bits - 1)) - 1;
-        sign_shift = exponent_bits + mantissa_bits;
-
-        sign_mask = 1 << sign_shift;
-        exponent_mask = ((1 << exponent_bits) - 1) << mantissa_bits;
-        mantissa_mask = (1 << mantissa_bits) - 1;
-
-        exponent_max = (1 << (exponent_bits - 1)) - 1;
-        exponent_min = -exponent_max - 1;
-
-        if (exponent_bits > EXPONENT_BITS_32) {
-            System.out.println("Too many exponent bits, max: " + EXPONENT_BITS_32);
-            new Exception().printStackTrace(System.err);
-            exponent_bits = (int) EXPONENT_BITS_32;
-        }
-        if (mantissa_bits > MANTISSA_BITS_32) {
-            System.out.println("Too many mantissa bits, max: " + MANTISSA_BITS_32);
-            mantissa_bits = MANTISSA_BITS_32;
-        }
-    }
-
-    public void reinit(int num_exponent_bits, int num_mantissa_bits, boolean signed) {
-        init(num_exponent_bits, num_mantissa_bits, signed);
-    }
-
-    public void reinit(int num_exponent_bits, int num_mantissa_bits) {
-        init(num_exponent_bits, num_mantissa_bits, true);
-    }
-
-    /**
-     * Encode a float.  The return value is the bit representation using
-     * the requested mantissa and exponent bits.  Mask out the result
-     * and save the bits.
-     *
-     * @param f The float to encode
-     * @param rounding Whether to round the result.  Gives better accuracy.
-     * @return
-     */
-    public long encode(float f, boolean rounding) {
-        if (f == 0.0f)
-            return 0;     // IEEE 0 is a special case.
-
-        long src = Float.floatToIntBits(f);
-
-        int mantissa_shift = (MANTISSA_BITS_32 - mantissa_bits);
-
-        // Mask out the mantissa, exponent, and sign fields.
-
-        long mantissa = (src & MANTISSA_MASK_32);
-
-        int exponent = (int) (src & EXPONENT_MASK_32) >> MANTISSA_BITS_32;
-
-        // Subtract the IEEE-754 number's exponent bias, then add our own.
-
-        exponent -= EXPONENT_BIAS_32;
-
-        // Round the mantissa, and bump up the exponent if necessary.
-        if (rounding && mantissa_shift != 0) {
-            int rounding_constant = 1 << (mantissa_shift - 1);
-            int test_bit = 1 << MANTISSA_BITS_32;
-
-            mantissa += rounding_constant;
-
-            if ((mantissa & test_bit) > 0) { // Is this correct change?
-                mantissa = 0;
-                exponent++;  // XXX exponent overflow
-            }
-        }
-
-        // Shift the mantissa to the right, killing the extra precision.
-
-        mantissa >>= mantissa_shift;
-
-        // Deal with the exponent.
-
-//System.out.println("exponent: " + exponent + " " + " binary: " + Integer.toBinaryString(exponent));
-        //printf("  exponent %d, min %d, max %d\n", exponent, exponent_min, exponent_max);
-//        System.out.println("exponent: " + exponent + " min: " + exponent_min + " max: " + exponent_max);
-        if (exponent < exponent_min) {
-            if (exponent < exponent_min - 1)
-                return 0;
-            exponent = exponent_min;
-            System.out.println("***Clamping to min exponent: " + exponent + " max: " + exponent_min + " number: " + f);
-        }
-
-        if (exponent > exponent_max) {
-            System.out.println("***Clamping to max exponent: " + exponent + " max: " + exponent_max + " number: " + f);
-            exponent = exponent_max;
-        }
-
-        exponent = (exponent - exponent_min);
-
-//System.out.println("exponent shifted: " + exponent);
-        // Put the pieces back together.
-
-        long result;
-        if (signed) {
-            long sign     = (src >> SIGN_SHIFT_32);
-
-//System.out.println("sign shift: " + sign_shift + " sign: " + sign + " exp: " + Integer.toBinaryString(exponent) + " mant: " + Long.toBinaryString(mantissa));
-            result = (sign << sign_shift) | (exponent << mantissa_bits)
-                       | (mantissa);
-        } else {
-            result = (exponent << mantissa_bits) | (mantissa);
-        }
-
-        return result;
-    }
-
-    /**
-     * Decodes a bit representation to a float value.
-     *
-     * @param src The source bits
-     * @param signed
-     * @return The float value
-     */
-    public float decode(long src, boolean signed) {
-        if (src == 0)
-            return 0.0f;
-
-        // Mask out the mantissa, exponent, and sign fields.
-
-        long mantissa = (src & mantissa_mask);
-        int exponent = (int) (src & exponent_mask) >> mantissa_bits;
-
-//System.out.println("sign shift: " + sign_shift + " sign: " + sign + " exp: " + Integer.toBinaryString(exponent) + " mant: " + Long.toBinaryString(mantissa));
-
-        // Subtract our exponent bias, then add IEEE-754's.
-
-        exponent += exponent_min;
-
-//System.out.println("exp: " + exponent);
-        exponent += EXPONENT_BIAS_32;
-
-        // Adjust the mantissa.
-
-        mantissa <<= (MANTISSA_BITS_32 - mantissa_bits);
-
-        // Assemble the pieces.
-
-        long result;
-
-        if (signed) {
-            long sign  = (src >> sign_shift);
-
-            result = (sign << SIGN_SHIFT_32) | (exponent << MANTISSA_BITS_32)
-                   | (mantissa);
-        } else {
-            result = (exponent << MANTISSA_BITS_32)
-                   | (mantissa);
-        }
-
-        return Float.intBitsToFloat((int)result);
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2004-2010
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+package org.web3d.vrml.export.compressors;
+
+/**
+ * Compresses float by using quanitization.
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.6 $
+ */
+public class FloatPacker {
+
+    private static final int MANTISSA_BITS_32 = 23;
+    private static final long EXPONENT_BITS_32 = 8;
+    private static final long MANTISSA_MASK_32 = 0x007fffff;
+    private static final long EXPONENT_MASK_32 = 0x7f800000;
+    private static final long SIGN_MASK_32     = 0x80000000;
+    private static final int EXPONENT_BIAS_32 = 127;
+    private static final int SIGN_SHIFT_32    = 31;
+
+    private int exponent_bits, mantissa_bits;
+    private boolean signed;
+    private int sign_mask, mantissa_mask, exponent_mask;
+    private int exponent_bias;
+    private int sign_shift;
+
+    private int exponent_min, exponent_max;
+
+    public FloatPacker(int num_exponent_bits, int num_mantissa_bits) {
+        init(num_exponent_bits, num_mantissa_bits, true);
+    }
+
+    public FloatPacker(int num_exponent_bits, int num_mantissa_bits, boolean signed) {
+        init(num_exponent_bits, num_mantissa_bits, signed);
+    }
+
+    private void init(int num_exponent_bits, int num_mantissa_bits, boolean signed) {
+        this.signed = signed;
+        exponent_bits = num_exponent_bits;
+        mantissa_bits = num_mantissa_bits;
+        exponent_bias = (1 << (exponent_bits - 1)) - 1;
+        sign_shift = exponent_bits + mantissa_bits;
+
+        sign_mask = 1 << sign_shift;
+        exponent_mask = ((1 << exponent_bits) - 1) << mantissa_bits;
+        mantissa_mask = (1 << mantissa_bits) - 1;
+
+        exponent_max = (1 << (exponent_bits - 1)) - 1;
+        exponent_min = -exponent_max - 1;
+
+        if (exponent_bits > EXPONENT_BITS_32) {
+            System.out.println("Too many exponent bits, max: " + EXPONENT_BITS_32);
+            new Exception().printStackTrace(System.err);
+            exponent_bits = (int) EXPONENT_BITS_32;
+        }
+        if (mantissa_bits > MANTISSA_BITS_32) {
+            System.out.println("Too many mantissa bits, max: " + MANTISSA_BITS_32);
+            mantissa_bits = MANTISSA_BITS_32;
+        }
+    }
+
+    public void reinit(int num_exponent_bits, int num_mantissa_bits, boolean signed) {
+        init(num_exponent_bits, num_mantissa_bits, signed);
+    }
+
+    public void reinit(int num_exponent_bits, int num_mantissa_bits) {
+        init(num_exponent_bits, num_mantissa_bits, true);
+    }
+
+    /**
+     * Encode a float.  The return value is the bit representation using
+     * the requested mantissa and exponent bits.  Mask out the result
+     * and save the bits.
+     *
+     * @param f The float to encode
+     * @param rounding Whether to round the result.  Gives better accuracy.
+     * @return
+     */
+    public long encode(float f, boolean rounding) {
+        if (f == 0.0f)
+            return 0;     // IEEE 0 is a special case.
+
+        long src = Float.floatToIntBits(f);
+
+        int mantissa_shift = (MANTISSA_BITS_32 - mantissa_bits);
+
+        // Mask out the mantissa, exponent, and sign fields.
+
+        long mantissa = (src & MANTISSA_MASK_32);
+
+        int exponent = (int) (src & EXPONENT_MASK_32) >> MANTISSA_BITS_32;
+
+        // Subtract the IEEE-754 number's exponent bias, then add our own.
+
+        exponent -= EXPONENT_BIAS_32;
+
+        // Round the mantissa, and bump up the exponent if necessary.
+        if (rounding && mantissa_shift != 0) {
+            int rounding_constant = 1 << (mantissa_shift - 1);
+            int test_bit = 1 << MANTISSA_BITS_32;
+
+            mantissa += rounding_constant;
+
+            if ((mantissa & test_bit) > 0) { // Is this correct change?
+                mantissa = 0;
+                exponent++;  // XXX exponent overflow
+            }
+        }
+
+        // Shift the mantissa to the right, killing the extra precision.
+
+        mantissa >>= mantissa_shift;
+
+        // Deal with the exponent.
+
+//System.out.println("exponent: " + exponent + " " + " binary: " + Integer.toBinaryString(exponent));
+        //printf("  exponent %d, min %d, max %d\n", exponent, exponent_min, exponent_max);
+//        System.out.println("exponent: " + exponent + " min: " + exponent_min + " max: " + exponent_max);
+        if (exponent < exponent_min) {
+            if (exponent < exponent_min - 1)
+                return 0;
+            exponent = exponent_min;
+            System.out.println("***Clamping to min exponent: " + exponent + " max: " + exponent_min + " number: " + f);
+        }
+
+        if (exponent > exponent_max) {
+            System.out.println("***Clamping to max exponent: " + exponent + " max: " + exponent_max + " number: " + f);
+            exponent = exponent_max;
+        }
+
+        exponent = (exponent - exponent_min);
+
+//System.out.println("exponent shifted: " + exponent);
+        // Put the pieces back together.
+
+        long result;
+        if (signed) {
+            long sign     = (src >> SIGN_SHIFT_32);
+
+//System.out.println("sign shift: " + sign_shift + " sign: " + sign + " exp: " + Integer.toBinaryString(exponent) + " mant: " + Long.toBinaryString(mantissa));
+            result = (sign << sign_shift) | (exponent << mantissa_bits)
+                       | (mantissa);
+        } else {
+            result = (exponent << mantissa_bits) | (mantissa);
+        }
+
+        return result;
+    }
+
+    /**
+     * Decodes a bit representation to a float value.
+     *
+     * @param src The source bits
+     * @param signed
+     * @return The float value
+     */
+    public float decode(long src, boolean signed) {
+        if (src == 0)
+            return 0.0f;
+
+        // Mask out the mantissa, exponent, and sign fields.
+
+        long mantissa = (src & mantissa_mask);
+        int exponent = (int) (src & exponent_mask) >> mantissa_bits;
+
+//System.out.println("sign shift: " + sign_shift + " sign: " + sign + " exp: " + Integer.toBinaryString(exponent) + " mant: " + Long.toBinaryString(mantissa));
+
+        // Subtract our exponent bias, then add IEEE-754's.
+
+        exponent += exponent_min;
+
+//System.out.println("exp: " + exponent);
+        exponent += EXPONENT_BIAS_32;
+
+        // Adjust the mantissa.
+
+        mantissa <<= (MANTISSA_BITS_32 - mantissa_bits);
+
+        // Assemble the pieces.
+
+        long result;
+
+        if (signed) {
+            long sign  = (src >> sign_shift);
+
+            result = (sign << SIGN_SHIFT_32) | (exponent << MANTISSA_BITS_32)
+                   | (mantissa);
+        } else {
+            result = (exponent << MANTISSA_BITS_32)
+                   | (mantissa);
+        }
+
+        return Float.intBitsToFloat((int)result);
+    }
+}
diff --git a/src/java/org/web3d/vrml/export/compressors/GeometryHeader.java b/src/java/org/web3d/vrml/export/compressors/GeometryHeader.java
index d67e44e7db140c54cf1672049900c0bb73987861..9bc5959812bdba5b913c0f512dc2312ca5905159 100644
--- a/src/java/org/web3d/vrml/export/compressors/GeometryHeader.java
+++ b/src/java/org/web3d/vrml/export/compressors/GeometryHeader.java
@@ -1,146 +1,146 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2004 - 2005
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.export.compressors;
-
-/**
- * Header for compressed geometry.
- *
- * @author Alan Hudson
- */
-public class GeometryHeader {
-
-    // Uniform scale applied to model
-    private float scale;
-
-    // The original bounds
-    private float[] bounds;
-
-    // Does this model contain normals
-    private boolean hasNormals;
-
-    // Does this model contain colors
-    private boolean hasColors;
-
-    // Does this model contain coordinates
-    private boolean hasCoordinates;
-
-    // Does this model contain textureCoordinates
-    private boolean hasTexCoords;
-
-    public GeometryHeader() {
-        bounds = new float[3];
-    }
-
-    public GeometryHeader(float scale, float[] bounds,
-        boolean hasCoordinates, boolean hasNormals, boolean hasColors,
-        boolean hasTexCoords) {
-
-        this.scale = scale;
-        this.bounds = bounds;
-        this.hasCoordinates = hasCoordinates;
-        this.hasNormals = hasNormals;
-        this.hasColors = hasColors;
-        this.hasTexCoords = hasTexCoords;
-    }
-
-    /**
-     * Get the size of the header in ints.  Right now this
-     * must be int aligned.
-     *
-     * @return The size in bytes
-     */
-    public static int getSize() {
-        return 4 + 3 * 4 + 1;
-    }
-
-    /**
-     * Encode this header into a buffer.
-     *
-     * @param buffer The buffer to encode to
-     * @param start The starting index to encode to
-     */
-    public void encode(int[] buffer, int start) {
-        buffer[start++] = Float.floatToIntBits(scale);
-        buffer[start++] = Float.floatToIntBits(bounds[0]);
-        buffer[start++] = Float.floatToIntBits(bounds[1]);
-        buffer[start++] = Float.floatToIntBits(bounds[2]);
-
-        // Encode flags all in one int
-        buffer[start++] = (hasCoordinates ? 1 : 0) << 3 |
-           (hasNormals ? 1 : 0) << 2 |
-           (hasColors ? 1 : 0) << 1 |
-           (hasTexCoords ? 1 : 0);
-System.out.println("Encoded flags: " + buffer[start - 1]);
-    }
-
-    /**
-     * Decode this header from a buffer.
-     *
-     * @param buffer The buffer to decode from
-     * @param start The starting index to decode from
-     */
-    public void decode(int[] buffer, int start) {
-        scale = Float.intBitsToFloat(buffer[start++]);
-        bounds[0] = Float.intBitsToFloat(buffer[start++]);
-        bounds[1] = Float.intBitsToFloat(buffer[start++]);
-        bounds[2] = Float.intBitsToFloat(buffer[start++]);
-
-        int flags = buffer[start++];
-System.out.println("Decoded flags: " + buffer[flags]);
-
-        hasCoordinates = ((flags & (1 << 3)) > 0);
-        hasNormals = ((flags & (1 << 2)) > 0);
-        hasColors = ((flags & (1 << 1)) > 0);
-        hasTexCoords = ((flags & (1)) > 0);
-    }
-
-    /**
-     * Does this model contain normals.
-     *
-     * @return Does it contain normals
-     */
-    public boolean hasNormals() {
-        return hasNormals;
-    }
-
-    public float[] getBounds() {
-        return bounds;
-    }
-
-    public float getScale() {
-        return scale;
-    }
-
-    @Override
-   public String toString() {
-        StringBuilder buf = new StringBuilder("Geometry Header: scale: ");
-        buf.append(Float.toString(scale));
-        buf.append(" bounds: (");
-        buf.append(Float.toString(bounds[0]));
-        buf.append(' ');
-        buf.append(Float.toString(bounds[1]));
-        buf.append(' ');
-        buf.append(Float.toString(bounds[2]));
-        buf.append(")");
-        buf.append(" hasCoords: ");
-        buf.append(hasCoordinates);
-        buf.append(" hasNormals: ");
-        buf.append(hasNormals);
-        buf.append(" hasColors: ");
-        buf.append(hasColors);
-        buf.append(" hasTexCoords: ");
-        buf.append(hasTexCoords);
-
-        return buf.toString();
-    }
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2004 - 2005
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.export.compressors;
+
+/**
+ * Header for compressed geometry.
+ *
+ * @author Alan Hudson
+ */
+public class GeometryHeader {
+
+    // Uniform scale applied to model
+    private float scale;
+
+    // The original bounds
+    private float[] bounds;
+
+    // Does this model contain normals
+    private boolean hasNormals;
+
+    // Does this model contain colors
+    private boolean hasColors;
+
+    // Does this model contain coordinates
+    private boolean hasCoordinates;
+
+    // Does this model contain textureCoordinates
+    private boolean hasTexCoords;
+
+    public GeometryHeader() {
+        bounds = new float[3];
+    }
+
+    public GeometryHeader(float scale, float[] bounds,
+        boolean hasCoordinates, boolean hasNormals, boolean hasColors,
+        boolean hasTexCoords) {
+
+        this.scale = scale;
+        this.bounds = bounds;
+        this.hasCoordinates = hasCoordinates;
+        this.hasNormals = hasNormals;
+        this.hasColors = hasColors;
+        this.hasTexCoords = hasTexCoords;
+    }
+
+    /**
+     * Get the size of the header in ints.  Right now this
+     * must be int aligned.
+     *
+     * @return The size in bytes
+     */
+    public static int getSize() {
+        return 4 + 3 * 4 + 1;
+    }
+
+    /**
+     * Encode this header into a buffer.
+     *
+     * @param buffer The buffer to encode to
+     * @param start The starting index to encode to
+     */
+    public void encode(int[] buffer, int start) {
+        buffer[start++] = Float.floatToIntBits(scale);
+        buffer[start++] = Float.floatToIntBits(bounds[0]);
+        buffer[start++] = Float.floatToIntBits(bounds[1]);
+        buffer[start++] = Float.floatToIntBits(bounds[2]);
+
+        // Encode flags all in one int
+        buffer[start++] = (hasCoordinates ? 1 : 0) << 3 |
+           (hasNormals ? 1 : 0) << 2 |
+           (hasColors ? 1 : 0) << 1 |
+           (hasTexCoords ? 1 : 0);
+System.out.println("Encoded flags: " + buffer[start - 1]);
+    }
+
+    /**
+     * Decode this header from a buffer.
+     *
+     * @param buffer The buffer to decode from
+     * @param start The starting index to decode from
+     */
+    public void decode(int[] buffer, int start) {
+        scale = Float.intBitsToFloat(buffer[start++]);
+        bounds[0] = Float.intBitsToFloat(buffer[start++]);
+        bounds[1] = Float.intBitsToFloat(buffer[start++]);
+        bounds[2] = Float.intBitsToFloat(buffer[start++]);
+
+        int flags = buffer[start++];
+System.out.println("Decoded flags: " + buffer[flags]);
+
+        hasCoordinates = ((flags & (1 << 3)) > 0);
+        hasNormals = ((flags & (1 << 2)) > 0);
+        hasColors = ((flags & (1 << 1)) > 0);
+        hasTexCoords = ((flags & (1)) > 0);
+    }
+
+    /**
+     * Does this model contain normals.
+     *
+     * @return Does it contain normals
+     */
+    public boolean hasNormals() {
+        return hasNormals;
+    }
+
+    public float[] getBounds() {
+        return bounds;
+    }
+
+    public float getScale() {
+        return scale;
+    }
+
+    @Override
+   public String toString() {
+        StringBuilder buf = new StringBuilder("Geometry Header: scale: ");
+        buf.append(Float.toString(scale));
+        buf.append(" bounds: (");
+        buf.append(Float.toString(bounds[0]));
+        buf.append(' ');
+        buf.append(Float.toString(bounds[1]));
+        buf.append(' ');
+        buf.append(Float.toString(bounds[2]));
+        buf.append(")");
+        buf.append(" hasCoords: ");
+        buf.append(hasCoordinates);
+        buf.append(" hasNormals: ");
+        buf.append(hasNormals);
+        buf.append(" hasColors: ");
+        buf.append(hasColors);
+        buf.append(" hasTexCoords: ");
+        buf.append(hasTexCoords);
+
+        return buf.toString();
+    }
 }
\ No newline at end of file
diff --git a/src/java/org/web3d/vrml/export/compressors/HuffmanNode.java b/src/java/org/web3d/vrml/export/compressors/HuffmanNode.java
index 91e175f5aa78ec83f3c03375d691a2d3ed54825e..c61616806b29d465edcadf411b89e046a049d756 100644
--- a/src/java/org/web3d/vrml/export/compressors/HuffmanNode.java
+++ b/src/java/org/web3d/vrml/export/compressors/HuffmanNode.java
@@ -1,88 +1,88 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001-2004
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-package org.web3d.vrml.export.compressors;
-
-import java.io.IOException;
-import java.util.* ;
-
-/**
- * Prototype Huffman node.  Borrowed original impl from Sun HuffmanNode, need to decide
- * if copyright still stands for heavily modified code.
- * @version $Revision: 1.2 $
- */
-public class HuffmanNode {
-    
-    public int tag, tagLength;
-    protected int frequency;
-    protected HuffmanNode child0, child1;
-
-    public void addCount() {
-        frequency++ ;
-    }
-
-    /**
-     * Write the data for this node out to a stream.
-     *
-     * @param packer The place to write the bits
-     * @param len The number of bits to use
-     * @throws java.io.IOException
-     */
-    public void writeData(BitPacker packer, int len) throws IOException {
-        // No data for this node
-        System.out.println("Writing untyped Huffman node?");
-    }
-
-    void addChildren(HuffmanNode child0, HuffmanNode child1) {
-        this.child0 = child0 ;
-        this.child1 = child1 ;
-        this.frequency = child0.frequency + child1.frequency ;
-    }
-
-    void collectLeaves(int tag, int tagLength, Collection<HuffmanNode> collection) {
-        if (child0 == null) {
-            this.tag = tag;
-            this.tagLength = tagLength;
-            collection.add(this);
-        } else {
-            child0.collectLeaves((tag << 1), tagLength + 1, collection);
-            child1.collectLeaves((tag << 1) | 1, tagLength + 1, collection);
-        }
-    }
-
-    /**
-     * Sorts nodes in ascending order by frequency.
-     */
-    static class FrequencyComparator implements Comparator<HuffmanNode> {
-        @Override
-        public final int compare(HuffmanNode o1, HuffmanNode o2) {
-            return o1.frequency - o2.frequency;
-        }
-    }
-
-    /**
-     * Sorts nodes in descending order by tag bit length.
-     */
-    static class TagLengthComparator implements Comparator<HuffmanNode> {
-        @Override
-        public final int compare(HuffmanNode o1, HuffmanNode o2) {
-            return o2.tagLength - o1.tagLength;
-        }
-    }
-
-    static FrequencyComparator frequencyComparator = new FrequencyComparator();
-    static TagLengthComparator tagLengthComparator = new TagLengthComparator();
-
-    @Override
-    public String toString() {
-        return "HN." + hashCode() + " freq: " + frequency;
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001-2004
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+package org.web3d.vrml.export.compressors;
+
+import java.io.IOException;
+import java.util.* ;
+
+/**
+ * Prototype Huffman node.  Borrowed original impl from Sun HuffmanNode, need to decide
+ * if copyright still stands for heavily modified code.
+ * @version $Revision: 1.2 $
+ */
+public class HuffmanNode {
+    
+    public int tag, tagLength;
+    protected int frequency;
+    protected HuffmanNode child0, child1;
+
+    public void addCount() {
+        frequency++ ;
+    }
+
+    /**
+     * Write the data for this node out to a stream.
+     *
+     * @param packer The place to write the bits
+     * @param len The number of bits to use
+     * @throws java.io.IOException
+     */
+    public void writeData(BitPacker packer, int len) throws IOException {
+        // No data for this node
+        System.out.println("Writing untyped Huffman node?");
+    }
+
+    void addChildren(HuffmanNode child0, HuffmanNode child1) {
+        this.child0 = child0 ;
+        this.child1 = child1 ;
+        this.frequency = child0.frequency + child1.frequency ;
+    }
+
+    void collectLeaves(int tag, int tagLength, Collection<HuffmanNode> collection) {
+        if (child0 == null) {
+            this.tag = tag;
+            this.tagLength = tagLength;
+            collection.add(this);
+        } else {
+            child0.collectLeaves((tag << 1), tagLength + 1, collection);
+            child1.collectLeaves((tag << 1) | 1, tagLength + 1, collection);
+        }
+    }
+
+    /**
+     * Sorts nodes in ascending order by frequency.
+     */
+    static class FrequencyComparator implements Comparator<HuffmanNode> {
+        @Override
+        public final int compare(HuffmanNode o1, HuffmanNode o2) {
+            return o1.frequency - o2.frequency;
+        }
+    }
+
+    /**
+     * Sorts nodes in descending order by tag bit length.
+     */
+    static class TagLengthComparator implements Comparator<HuffmanNode> {
+        @Override
+        public final int compare(HuffmanNode o1, HuffmanNode o2) {
+            return o2.tagLength - o1.tagLength;
+        }
+    }
+
+    static FrequencyComparator frequencyComparator = new FrequencyComparator();
+    static TagLengthComparator tagLengthComparator = new TagLengthComparator();
+
+    @Override
+    public String toString() {
+        return "HN." + hashCode() + " freq: " + frequency;
+    }
+}
diff --git a/src/java/org/web3d/vrml/export/compressors/IndexedFaceSetCompressor.java b/src/java/org/web3d/vrml/export/compressors/IndexedFaceSetCompressor.java
index 260eaee71cd807aa09bab36936d6ffdb90acbf30..fca83391320b83ede382d3e9cb8a5bc65782c537 100644
--- a/src/java/org/web3d/vrml/export/compressors/IndexedFaceSetCompressor.java
+++ b/src/java/org/web3d/vrml/export/compressors/IndexedFaceSetCompressor.java
@@ -1,446 +1,446 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2005
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.export.compressors;
-
-// External imports
-import java.io.IOException;
-import java.io.DataOutputStream;
-
-// Local imports
-import org.web3d.vrml.sav.*;
-
-import org.web3d.vrml.lang.VRMLException;
-import org.web3d.vrml.nodes.VRMLNodeType;
-import org.web3d.vrml.parser.VRMLFieldReader;
-import org.web3d.vrml.renderer.norender.nodes.geom3d.NRIndexedFaceSet;
-
-/**
- * A node compressor for IndexedFaceSet nodes.
- *
- * Index fields will be compressed using delta encoding and by removing -1 if the
- * faces are all the same size..
- *
- * This will use the Java3D compression utilities only if the Coordinate
- * node is not USED.
- *
- * @author Alan Hudson.
- * @version $Revision: 1.5 $
- */
-//public class IndexedFaceSetCompressor implements SceneGraphCompressor {
-public class IndexedFaceSetCompressor implements NodeCompressor {
-
-    private DataOutputStream dos;
-    private VRMLFieldReader fieldParser;
-    private VRMLNodeType node;
-    private int currentField;
-    private int vfCcw;
-    private int vfColorIndex;
-    private int vfColorPerVertex;
-    private int vfConvex;
-    private int vfCoordIndex;
-    private int vfCreaseAngle;
-    private int vfNormalIndex;
-    private int vfNormalPerVertex;
-    private int vfSolid;
-    private int vfTexCoordIndex;
-
-    public IndexedFaceSetCompressor() {
-        node = new NRIndexedFaceSet();
-        vfCcw = node.getFieldIndex("ccw");
-        vfColorIndex = node.getFieldIndex("colorIndex");
-        vfColorPerVertex = node.getFieldIndex("colorPerVertex");
-        vfConvex = node.getFieldIndex("convex");
-        vfCoordIndex = node.getFieldIndex("coordIndex");
-        vfCreaseAngle = node.getFieldIndex("creaseAngle");
-        vfNormalIndex = node.getFieldIndex("normalIndex");
-        vfNormalPerVertex = node.getFieldIndex("normalPerVertex");
-        vfSolid = node.getFieldIndex("solid");
-        vfTexCoordIndex = node.getFieldIndex("texCoordIndex");
-    }
-
-    /**
-     * Reinitialize this class for a new instance.
-     *
-     * @param dos The output stream to use.
-     * @param vfr The field parser to use.
-     */
-    public void reinit(DataOutputStream dos, VRMLFieldReader vfr) {
-        this.dos = dos;
-        fieldParser = vfr;
-    }
-
-    /**
-     * Can this NodeCompressor support this compression method
-     *
-     * @param nodeNumber What node, constant defined by Web3D Consortium
-     * @param method What method of compression.  0-127 defined by Web3D Consortium.
-     * @return
-     */
-    public boolean canSupport(int nodeNumber, int method) {
-        // TODO: get a real value
-        return true;
-    }
-
-    /**
-     * Set the document locator that can be used by the implementing code to
-     * find out information about the current line information. This method
-     * is called by the parser to your code to give you a locator to work with.
-     * If this has not been set by the time <code>startDocument()</code> has
-     * been called, you can assume that you will not have one available.
-     *
-     * @param loc The locator instance to use
-     */
-    public void setDocumentLocator(Locator loc) {
-    }
-
-    /**
-     * Declaration of the start of the document. The parameters are all of the
-     * values that are declared on the header line of the file after the
-     * <code>#</code> start. The type string contains the representation of
-     * the first few characters of the file after the #. This allows us to
-     * work out if it is VRML97 or the later X3D spec.
-     * <p>
-     * Version numbers change from VRML97 to X3D and aren't logical. In the
-     * first, it is <code>#VRML V2.0</code> and the second is
-     * <code>#X3D V1.0</code> even though this second header represents a
-     * later spec.
-     *
-     * @param url The base URL of the file for resolving relative URIs
-     *    contained in the file
-     * @param encoding The encoding of this document - utf8 or binary
-     * @param type The bytes of the first part of the file header
-     * @param version The full VRML version string of this document
-     * @param comment Any trailing text on this line. If there is none, this
-     *    is null.
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void startDocument(String url,
-                              String encoding,
-                              String type,
-                              String version,
-                              String comment)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * A profile declaration has been found in the code. IAW the X3D
-     * specification, this method will only ever be called once in the lifetime
-     * of the parser for this document. The name is the name of the profile
-     * for the document to use.
-     *
-     * @param profileName The name of the profile to use
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void profileDecl(String profileName)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * A component declaration has been found in the code. There may be zero
-     * or more component declarations in the file, appearing just after the
-     * profile declaration. The textual information after the COMPONENT keyword
-     * is left unparsed and presented through this call. It is up to the user
-     * application to parse the component information.
-     *
-     * @param componentName The name of the component to use
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void componentDecl(String componentName)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * A META declaration has been found in the code. There may be zero
-     * or more meta declarations in the file, appearing just after the
-     * component declaration. Each meta declaration has a key and value
-     * strings. No information is to be implied from this. It is for extra
-     * data only.
-     *
-     * @param key The value of the key string
-     * @param value The value of the value string
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void metaDecl(String key, String value)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * An IMPORT declaration has been found in the document. All three
-     * parameters will always be provided, regardless of whether the AS keyword
-     * has been used or not. The parser implementation will automatically set
-     * the local import name as needed.
-     *
-     * @param inline The name of the inline DEF nodes
-     * @param exported The exported name from the inlined file
-     * @param imported The local name to use for the exported name
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void importDecl(String inline, String exported, String imported)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * An EXPORT declaration has been found in the document. Both paramters
-     * will always be provided regardless of whether the AS keyword has been
-     * used. The parser implementation will automatically set the exported
-     * name as needed.
-     *
-     * @param defName The DEF name of the nodes to be exported
-     * @param exported The name to be exported as
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void exportDecl(String defName, String exported)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * Declaration of the end of the document. There will be no further parsing
-     * and hence events after this.
-     *
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void endDocument() throws SAVException, VRMLException {
-    }
-
-    /**
-     * Notification of the start of a node. This is the opening statement of a
-     * node and it's DEF name. USE declarations are handled in a separate
-     * method.
-     *
-     * @param name The name of the node that we are about to parse
-     * @param defName The string associated with the DEF name. Null if not
-     *   given for this node.
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void startNode(String name, String defName)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * Notification of the end of a node declaration.
-     *
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void endNode() throws SAVException, VRMLException {
-    }
-
-    /**
-     * Notification of a field declaration. This notification is only called
-     * if it is a standard node. If the node is a script or PROTO declaration
-     * then the {@link ScriptHandler} or {@link ProtoHandler} methods are
-     * used.
-     *
-     * @param name The name of the field declared
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void startField(String name) throws SAVException, VRMLException {
-        currentField = node.getFieldIndex(name);
-        try {
-            dos.writeByte(currentField);
-        } catch(IOException ioe) {
-            ioe.printStackTrace(System.err);
-        }
-    }
-
-    /**
-     * The value of a normal field. This is a string that represents the entire
-     * value of the field. MFStrings will have to be parsed. This is a
-     * terminating call for startField as well. The next call will either be
-     * another <code>startField()</code> or <code>endNode()</code>.
-     * <p>
-     * If this field is an SFNode with a USE declaration you will have the
-     * {@link #useDecl(String)} method called rather than this method. If the
-     * SFNode is empty the value returned here will be "NULL".
-     * <p>
-     * There are times where we have an MFField that is declared in the file
-     * to be empty. To signify this case, this method will be called with a
-     * parameter value of null. A lot of the time this is because we can't
-     * really determine if the incoming node is an MFNode or not.
-     *
-     * @param value The value of this field
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void fieldValue(String value) throws SAVException, VRMLException {
-        try {
-        if (currentField == vfCcw || currentField == vfColorPerVertex ||
-            currentField == vfConvex || currentField == vfNormalPerVertex ||
-            currentField == vfSolid) {
-
-            boolean bval = fieldParser.SFBool(value);
-            dos.writeBoolean(bval);
-        } else if (currentField == vfCreaseAngle) {
-            float fval = fieldParser.SFFloat(value);
-            dos.writeFloat(fval);
-        } else if (currentField == vfColorIndex || currentField == vfNormalIndex ||
-                   currentField == vfTexCoordIndex) {
-
-            int[] ival = fieldParser.MFInt32(value);
-            // Scan for fixed sized polys of 3 or 4 vertices
-            int cnt=0;
-            int size=-1;
-            boolean fixed=true;
-            for(int i=0; i < ival.length; i++) {
-                if (ival[i] == -1) {
-                    if (size != -1 && cnt != size) {
-                        fixed = false;
-                        break;
-                    }
-                    size = cnt;
-                    cnt = 0;
-                } else {
-                    cnt++;
-                }
-            }
-
-            int lastMarker;
-            if (ival[ival.length -1] == -1)
-                lastMarker = 0;
-            else
-                lastMarker = -1;
-
-            if (size == -1)
-                size = cnt;
-            // Check the last as it might not have a -1
-            if (lastMarker != 0 && cnt != size) {
-                fixed = false;
-                System.out.println("last face not fixed:  cnt:" + cnt + " size: " + size);
-            }
-
-            if (fixed) {
-                // Maybe convert to 2 bits(0-4?)
-                dos.writeByte(size);
-                int numElements = (int) Math.ceil(ival.length / (size + 1));
-                int[] strippedVals = new int[numElements * size];
-                int pos=0;
-                for(int i=0; i < ival.length / size + lastMarker; i++) {
-                    if (i % (size - 1) != 0) {
-                        strippedVals[pos++] = ival[i];
-                    }
-                }
-                CompressionTools.compressIntArrayDeltaHuffman(dos, strippedVals);
-            } else {
-                System.out.println("not fixed IFS");
-                dos.writeByte(0);
-                CompressionTools.compressIntArrayDeltaHuffman(dos,ival);
-            }
-        }
-        } catch (IOException ioe) {
-            ioe.printStackTrace(System.err);
-        }
-    }
-
-    /**
-     * The value of an MFField where the underlying parser knows about how the
-     * values are broken up. The parser is not required to support this
-     * callback, but implementors of this interface should understand it. The
-     * most likely time we will have this method called is for MFString or
-     * URL lists. If called, it is guaranteed to split the strings along the
-     * SF node type boundaries.
-     *
-     * @param values The list of string representing the values
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void fieldValue(String[] values) throws SAVException, VRMLException {
-    }
-
-    /**
-     * The field value is a USE for the given node name. This is a
-     * terminating call for startField as well. The next call will either be
-     * another <code>startField()</code> or <code>endNode()</code>.
-     *
-     * @param defName The name of the DEF string to use
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void useDecl(String defName) throws SAVException, VRMLException {
-    }
-
-    /**
-     * Notification of the end of a field declaration. This is called only at
-     * the end of an MFNode declaration. All other fields are terminated by
-     * either {@link #useDecl(String)} or {@link #fieldValue(String)}. This
-     * will only ever be called if there have been nodes declared. If no nodes
-     * have been declared (ie "[]") then you will get a
-     * <code>fieldValue()</code>. call with the parameter value of null.
-     *
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void endField() throws SAVException, VRMLException {
-    }
-
-    @Override
-    public int[] compress(VRMLNodeType node) {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public void decompress(int[] data) {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public boolean handleData(String nodeName, String fieldName) {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public void fillData(String nodeName, BinaryContentHandler ch) {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public String getEncoderMetadata() {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001 - 2005
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.export.compressors;
+
+// External imports
+import java.io.IOException;
+import java.io.DataOutputStream;
+
+// Local imports
+import org.web3d.vrml.sav.*;
+
+import org.web3d.vrml.lang.VRMLException;
+import org.web3d.vrml.nodes.VRMLNodeType;
+import org.web3d.vrml.parser.VRMLFieldReader;
+import org.web3d.vrml.renderer.norender.nodes.geom3d.NRIndexedFaceSet;
+
+/**
+ * A node compressor for IndexedFaceSet nodes.
+ *
+ * Index fields will be compressed using delta encoding and by removing -1 if the
+ * faces are all the same size..
+ *
+ * This will use the Java3D compression utilities only if the Coordinate
+ * node is not USED.
+ *
+ * @author Alan Hudson.
+ * @version $Revision: 1.5 $
+ */
+//public class IndexedFaceSetCompressor implements SceneGraphCompressor {
+public class IndexedFaceSetCompressor implements NodeCompressor {
+
+    private DataOutputStream dos;
+    private VRMLFieldReader fieldParser;
+    private VRMLNodeType node;
+    private int currentField;
+    private int vfCcw;
+    private int vfColorIndex;
+    private int vfColorPerVertex;
+    private int vfConvex;
+    private int vfCoordIndex;
+    private int vfCreaseAngle;
+    private int vfNormalIndex;
+    private int vfNormalPerVertex;
+    private int vfSolid;
+    private int vfTexCoordIndex;
+
+    public IndexedFaceSetCompressor() {
+        node = new NRIndexedFaceSet();
+        vfCcw = node.getFieldIndex("ccw");
+        vfColorIndex = node.getFieldIndex("colorIndex");
+        vfColorPerVertex = node.getFieldIndex("colorPerVertex");
+        vfConvex = node.getFieldIndex("convex");
+        vfCoordIndex = node.getFieldIndex("coordIndex");
+        vfCreaseAngle = node.getFieldIndex("creaseAngle");
+        vfNormalIndex = node.getFieldIndex("normalIndex");
+        vfNormalPerVertex = node.getFieldIndex("normalPerVertex");
+        vfSolid = node.getFieldIndex("solid");
+        vfTexCoordIndex = node.getFieldIndex("texCoordIndex");
+    }
+
+    /**
+     * Reinitialize this class for a new instance.
+     *
+     * @param dos The output stream to use.
+     * @param vfr The field parser to use.
+     */
+    public void reinit(DataOutputStream dos, VRMLFieldReader vfr) {
+        this.dos = dos;
+        fieldParser = vfr;
+    }
+
+    /**
+     * Can this NodeCompressor support this compression method
+     *
+     * @param nodeNumber What node, constant defined by Web3D Consortium
+     * @param method What method of compression.  0-127 defined by Web3D Consortium.
+     * @return
+     */
+    public boolean canSupport(int nodeNumber, int method) {
+        // TODO: get a real value
+        return true;
+    }
+
+    /**
+     * Set the document locator that can be used by the implementing code to
+     * find out information about the current line information. This method
+     * is called by the parser to your code to give you a locator to work with.
+     * If this has not been set by the time <code>startDocument()</code> has
+     * been called, you can assume that you will not have one available.
+     *
+     * @param loc The locator instance to use
+     */
+    public void setDocumentLocator(Locator loc) {
+    }
+
+    /**
+     * Declaration of the start of the document. The parameters are all of the
+     * values that are declared on the header line of the file after the
+     * <code>#</code> start. The type string contains the representation of
+     * the first few characters of the file after the #. This allows us to
+     * work out if it is VRML97 or the later X3D spec.
+     * <p>
+     * Version numbers change from VRML97 to X3D and aren't logical. In the
+     * first, it is <code>#VRML V2.0</code> and the second is
+     * <code>#X3D V1.0</code> even though this second header represents a
+     * later spec.
+     *
+     * @param url The base URL of the file for resolving relative URIs
+     *    contained in the file
+     * @param encoding The encoding of this document - utf8 or binary
+     * @param type The bytes of the first part of the file header
+     * @param version The full VRML version string of this document
+     * @param comment Any trailing text on this line. If there is none, this
+     *    is null.
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void startDocument(String url,
+                              String encoding,
+                              String type,
+                              String version,
+                              String comment)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * A profile declaration has been found in the code. IAW the X3D
+     * specification, this method will only ever be called once in the lifetime
+     * of the parser for this document. The name is the name of the profile
+     * for the document to use.
+     *
+     * @param profileName The name of the profile to use
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void profileDecl(String profileName)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * A component declaration has been found in the code. There may be zero
+     * or more component declarations in the file, appearing just after the
+     * profile declaration. The textual information after the COMPONENT keyword
+     * is left unparsed and presented through this call. It is up to the user
+     * application to parse the component information.
+     *
+     * @param componentName The name of the component to use
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void componentDecl(String componentName)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * A META declaration has been found in the code. There may be zero
+     * or more meta declarations in the file, appearing just after the
+     * component declaration. Each meta declaration has a key and value
+     * strings. No information is to be implied from this. It is for extra
+     * data only.
+     *
+     * @param key The value of the key string
+     * @param value The value of the value string
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void metaDecl(String key, String value)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * An IMPORT declaration has been found in the document. All three
+     * parameters will always be provided, regardless of whether the AS keyword
+     * has been used or not. The parser implementation will automatically set
+     * the local import name as needed.
+     *
+     * @param inline The name of the inline DEF nodes
+     * @param exported The exported name from the inlined file
+     * @param imported The local name to use for the exported name
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void importDecl(String inline, String exported, String imported)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * An EXPORT declaration has been found in the document. Both paramters
+     * will always be provided regardless of whether the AS keyword has been
+     * used. The parser implementation will automatically set the exported
+     * name as needed.
+     *
+     * @param defName The DEF name of the nodes to be exported
+     * @param exported The name to be exported as
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void exportDecl(String defName, String exported)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * Declaration of the end of the document. There will be no further parsing
+     * and hence events after this.
+     *
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void endDocument() throws SAVException, VRMLException {
+    }
+
+    /**
+     * Notification of the start of a node. This is the opening statement of a
+     * node and it's DEF name. USE declarations are handled in a separate
+     * method.
+     *
+     * @param name The name of the node that we are about to parse
+     * @param defName The string associated with the DEF name. Null if not
+     *   given for this node.
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void startNode(String name, String defName)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * Notification of the end of a node declaration.
+     *
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void endNode() throws SAVException, VRMLException {
+    }
+
+    /**
+     * Notification of a field declaration. This notification is only called
+     * if it is a standard node. If the node is a script or PROTO declaration
+     * then the {@link ScriptHandler} or {@link ProtoHandler} methods are
+     * used.
+     *
+     * @param name The name of the field declared
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void startField(String name) throws SAVException, VRMLException {
+        currentField = node.getFieldIndex(name);
+        try {
+            dos.writeByte(currentField);
+        } catch(IOException ioe) {
+            ioe.printStackTrace(System.err);
+        }
+    }
+
+    /**
+     * The value of a normal field. This is a string that represents the entire
+     * value of the field. MFStrings will have to be parsed. This is a
+     * terminating call for startField as well. The next call will either be
+     * another <code>startField()</code> or <code>endNode()</code>.
+     * <p>
+     * If this field is an SFNode with a USE declaration you will have the
+     * {@link #useDecl(String)} method called rather than this method. If the
+     * SFNode is empty the value returned here will be "NULL".
+     * <p>
+     * There are times where we have an MFField that is declared in the file
+     * to be empty. To signify this case, this method will be called with a
+     * parameter value of null. A lot of the time this is because we can't
+     * really determine if the incoming node is an MFNode or not.
+     *
+     * @param value The value of this field
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void fieldValue(String value) throws SAVException, VRMLException {
+        try {
+        if (currentField == vfCcw || currentField == vfColorPerVertex ||
+            currentField == vfConvex || currentField == vfNormalPerVertex ||
+            currentField == vfSolid) {
+
+            boolean bval = fieldParser.SFBool(value);
+            dos.writeBoolean(bval);
+        } else if (currentField == vfCreaseAngle) {
+            float fval = fieldParser.SFFloat(value);
+            dos.writeFloat(fval);
+        } else if (currentField == vfColorIndex || currentField == vfNormalIndex ||
+                   currentField == vfTexCoordIndex) {
+
+            int[] ival = fieldParser.MFInt32(value);
+            // Scan for fixed sized polys of 3 or 4 vertices
+            int cnt=0;
+            int size=-1;
+            boolean fixed=true;
+            for(int i=0; i < ival.length; i++) {
+                if (ival[i] == -1) {
+                    if (size != -1 && cnt != size) {
+                        fixed = false;
+                        break;
+                    }
+                    size = cnt;
+                    cnt = 0;
+                } else {
+                    cnt++;
+                }
+            }
+
+            int lastMarker;
+            if (ival[ival.length -1] == -1)
+                lastMarker = 0;
+            else
+                lastMarker = -1;
+
+            if (size == -1)
+                size = cnt;
+            // Check the last as it might not have a -1
+            if (lastMarker != 0 && cnt != size) {
+                fixed = false;
+                System.out.println("last face not fixed:  cnt:" + cnt + " size: " + size);
+            }
+
+            if (fixed) {
+                // Maybe convert to 2 bits(0-4?)
+                dos.writeByte(size);
+                int numElements = (int) Math.ceil(ival.length / (size + 1));
+                int[] strippedVals = new int[numElements * size];
+                int pos=0;
+                for(int i=0; i < ival.length / size + lastMarker; i++) {
+                    if (i % (size - 1) != 0) {
+                        strippedVals[pos++] = ival[i];
+                    }
+                }
+                CompressionTools.compressIntArrayDeltaHuffman(dos, strippedVals);
+            } else {
+                System.out.println("not fixed IFS");
+                dos.writeByte(0);
+                CompressionTools.compressIntArrayDeltaHuffman(dos,ival);
+            }
+        }
+        } catch (IOException ioe) {
+            ioe.printStackTrace(System.err);
+        }
+    }
+
+    /**
+     * The value of an MFField where the underlying parser knows about how the
+     * values are broken up. The parser is not required to support this
+     * callback, but implementors of this interface should understand it. The
+     * most likely time we will have this method called is for MFString or
+     * URL lists. If called, it is guaranteed to split the strings along the
+     * SF node type boundaries.
+     *
+     * @param values The list of string representing the values
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void fieldValue(String[] values) throws SAVException, VRMLException {
+    }
+
+    /**
+     * The field value is a USE for the given node name. This is a
+     * terminating call for startField as well. The next call will either be
+     * another <code>startField()</code> or <code>endNode()</code>.
+     *
+     * @param defName The name of the DEF string to use
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void useDecl(String defName) throws SAVException, VRMLException {
+    }
+
+    /**
+     * Notification of the end of a field declaration. This is called only at
+     * the end of an MFNode declaration. All other fields are terminated by
+     * either {@link #useDecl(String)} or {@link #fieldValue(String)}. This
+     * will only ever be called if there have been nodes declared. If no nodes
+     * have been declared (ie "[]") then you will get a
+     * <code>fieldValue()</code>. call with the parameter value of null.
+     *
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void endField() throws SAVException, VRMLException {
+    }
+
+    @Override
+    public int[] compress(VRMLNodeType node) {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public void decompress(int[] data) {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public boolean handleData(String nodeName, String fieldName) {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public void fillData(String nodeName, BinaryContentHandler ch) {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public String getEncoderMetadata() {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+}
diff --git a/src/java/org/web3d/vrml/export/compressors/NodeCompressor.java b/src/java/org/web3d/vrml/export/compressors/NodeCompressor.java
index ae33a6619952bb6a69b6089b235210a2a7e5ec8c..8e4d342210107368bb113910a1658d5bf92994ad 100644
--- a/src/java/org/web3d/vrml/export/compressors/NodeCompressor.java
+++ b/src/java/org/web3d/vrml/export/compressors/NodeCompressor.java
@@ -1,57 +1,57 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.export.compressors;
-
-import org.web3d.vrml.nodes.*;
-import org.web3d.vrml.sav.*;
-
-public interface NodeCompressor {
-    /**
-     * Compress the given Node.
-     *
-     * @param node The geometry to compress
-     * @return An int array for the geometry
-     */
-    int[] compress(VRMLNodeType node);
-
-    /**
-     * Decompress the data.
-     *
-     * @param data The compressed data
-     */
-    void decompress(int[] data);
-
-    /**
-     * Checks whether this compressors handles this data.  If not then
-     * the data should be written to the stream.
-     *
-     * @param nodeName the node
-     * @param fieldName the field
-     * @return true if data should be written to the stream
-     */
-    boolean handleData(String nodeName, String fieldName);
-
-    /**
-     * Fill in the data handled by the compressor.
-     *
-     * @param nodeName The nodeName
-     * @param ch The handler to write to
-     */
-    void fillData(String nodeName, BinaryContentHandler ch);
-
-    /** Get any metadata the encoder would like to write to the file.
-     *
-     *  @return The metadata in X3D XML encoding
-     */
-    String getEncoderMetadata();
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.export.compressors;
+
+import org.web3d.vrml.nodes.*;
+import org.web3d.vrml.sav.*;
+
+public interface NodeCompressor {
+    /**
+     * Compress the given Node.
+     *
+     * @param node The geometry to compress
+     * @return An int array for the geometry
+     */
+    int[] compress(VRMLNodeType node);
+
+    /**
+     * Decompress the data.
+     *
+     * @param data The compressed data
+     */
+    void decompress(int[] data);
+
+    /**
+     * Checks whether this compressors handles this data.  If not then
+     * the data should be written to the stream.
+     *
+     * @param nodeName the node
+     * @param fieldName the field
+     * @return true if data should be written to the stream
+     */
+    boolean handleData(String nodeName, String fieldName);
+
+    /**
+     * Fill in the data handled by the compressor.
+     *
+     * @param nodeName The nodeName
+     * @param ch The handler to write to
+     */
+    void fillData(String nodeName, BinaryContentHandler ch);
+
+    /** Get any metadata the encoder would like to write to the file.
+     *
+     *  @return The metadata in X3D XML encoding
+     */
+    String getEncoderMetadata();
 }
\ No newline at end of file
diff --git a/src/java/org/web3d/vrml/export/compressors/NormalCompressor.java b/src/java/org/web3d/vrml/export/compressors/NormalCompressor.java
index 586696db982f76ea07f017ccd4b088c0d5beec01..b9c7b137d1ee2d9b4df62e7bb4dc448cdd540779 100644
--- a/src/java/org/web3d/vrml/export/compressors/NormalCompressor.java
+++ b/src/java/org/web3d/vrml/export/compressors/NormalCompressor.java
@@ -1,549 +1,549 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2005
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.export.compressors;
-
-// External imports
-//import javax.media.j3d.*;
-
-//import com.sun.j3d.utils.compression.*;
-
-import java.io.IOException;
-import java.io.DataOutputStream;
-
-import javax.vecmath.Vector3f;
-
-// Local imports
-import org.web3d.vrml.lang.VRMLException;
-import org.web3d.vrml.nodes.VRMLNodeType;
-import org.web3d.vrml.sav.*;
-import org.web3d.vrml.parser.VRMLFieldReader;
-
-/**
- * A node compressor for Normal nodes.  Implements the normal compression
- * method devised by the Java3D team.
- *
- * IPR Warning: This method has patents on it(Sun Microsystems).  We are trying to secure a
- * royalty free license for X3D implementations.
- *
- * @author Alan Hudson.
- * @version $Revision: 1.6 $
- */
-public class NormalCompressor implements SceneGraphCompressor {
-    private DataOutputStream dos;
-    private VRMLFieldReader fieldParser;
-
-    /**
-     * Reinitialize this class for a new instance.
-     *
-     * @param dos The output stream to use.
-     * @param vfr The field parser to use.
-     */
-    public void reinit(DataOutputStream dos, VRMLFieldReader vfr) {
-        this.dos = dos;
-        fieldParser = vfr;
-    }
-
-    /**
-     * Can this NodeCompressor support this compression method
-     *
-     * @param nodeNumber What node, constant defined by Web3D Consortium
-     * @param method What method of compression.  0-127 defined by Web3D Consortium.
-     * @return
-     */
-    public boolean canSupport(int nodeNumber, int method) {
-        // TODO: get a real value
-        return true;
-    }
-
-    /**
-     * Set the document locator that can be used by the implementing code to
-     * find out information about the current line information. This method
-     * is called by the parser to your code to give you a locator to work with.
-     * If this has not been set by the time <code>startDocument()</code> has
-     * been called, you can assume that you will not have one available.
-     *
-     * @param loc The locator instance to use
-     */
-    public void setDocumentLocator(Locator loc) {
-    }
-
-    /**
-     * Declaration of the start of the document. The parameters are all of the
-     * values that are declared on the header line of the file after the
-     * <code>#</code> start. The type string contains the representation of
-     * the first few characters of the file after the #. This allows us to
-     * work out if it is VRML97 or the later X3D spec.
-     * <p>
-     * Version numbers change from VRML97 to X3D and aren't logical. In the
-     * first, it is <code>#VRML V2.0</code> and the second is
-     * <code>#X3D V1.0</code> even though this second header represents a
-     * later spec.
-     *
-     * @param url The base URL of the file for resolving relative URIs
-     *    contained in the file
-     * @param encoding The encoding of this document - utf8 or binary
-     * @param type The bytes of the first part of the file header
-     * @param version The full VRML version string of this document
-     * @param comment Any trailing text on this line. If there is none, this
-     *    is null.
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void startDocument(String url,
-                              String encoding,
-                              String type,
-                              String version,
-                              String comment)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * A profile declaration has been found in the code. IAW the X3D
-     * specification, this method will only ever be called once in the lifetime
-     * of the parser for this document. The name is the name of the profile
-     * for the document to use.
-     *
-     * @param profileName The name of the profile to use
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void profileDecl(String profileName)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * A component declaration has been found in the code. There may be zero
-     * or more component declarations in the file, appearing just after the
-     * profile declaration. The textual information after the COMPONENT keyword
-     * is left unparsed and presented through this call. It is up to the user
-     * application to parse the component information.
-     *
-     * @param componentName The name of the component to use
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void componentDecl(String componentName)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * A META declaration has been found in the code. There may be zero
-     * or more meta declarations in the file, appearing just after the
-     * component declaration. Each meta declaration has a key and value
-     * strings. No information is to be implied from this. It is for extra
-     * data only.
-     *
-     * @param key The value of the key string
-     * @param value The value of the value string
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void metaDecl(String key, String value)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * An IMPORT declaration has been found in the document. All three
-     * parameters will always be provided, regardless of whether the AS keyword
-     * has been used or not. The parser implementation will automatically set
-     * the local import name as needed.
-     *
-     * @param inline The name of the inline DEF nodes
-     * @param exported The exported name from the inlined file
-     * @param imported The local name to use for the exported name
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void importDecl(String inline, String exported, String imported)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * An EXPORT declaration has been found in the document. Both paramters
-     * will always be provided regardless of whether the AS keyword has been
-     * used. The parser implementation will automatically set the exported
-     * name as needed.
-     *
-     * @param defName The DEF name of the nodes to be exported
-     * @param exported The name to be exported as
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void exportDecl(String defName, String exported)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * Declaration of the end of the document. There will be no further parsing
-     * and hence events after this.
-     *
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void endDocument() throws SAVException, VRMLException {
-    }
-
-    /**
-     * Notification of the start of a node. This is the opening statement of a
-     * node and it's DEF name. USE declarations are handled in a separate
-     * method.
-     *
-     * @param name The name of the node that we are about to parse
-     * @param defName The string associated with the DEF name. Null if not
-     *   given for this node.
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void startNode(String name, String defName)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * Notification of the end of a node declaration.
-     *
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void endNode() throws SAVException, VRMLException {
-    }
-
-    /**
-     * Notification of a field declaration. This notification is only called
-     * if it is a standard node. If the node is a script or PROTO declaration
-     * then the {@link ScriptHandler} or {@link ProtoHandler} methods are
-     * used.
-     *
-     * @param name The name of the field declared
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void startField(String name) throws SAVException, VRMLException {
-
-    }
-
-    /**
-     * The value of a normal field. This is a string that represents the entire
-     * value of the field. MFStrings will have to be parsed. This is a
-     * terminating call for startField as well. The next call will either be
-     * another <code>startField()</code> or <code>endNode()</code>.
-     * <p>
-     * If this field is an SFNode with a USE declaration you will have the
-     * {@link #useDecl(String)} method called rather than this method. If the
-     * SFNode is empty the value returned here will be "NULL".
-     * <p>
-     * There are times where we have an MFField that is declared in the file
-     * to be empty. To signify this case, this method will be called with a
-     * parameter value of null. A lot of the time this is because we can't
-     * really determine if the incoming node is an MFNode or not.
-     *
-     * @param value The value of this field
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void fieldValue(String value) throws SAVException, VRMLException {
-        float[] fval = fieldParser.MFVec3f(value);
-
-        writeVector(fval, fval.length);
-    }
-
-    /**
-     * The value of an MFField where the underlying parser knows about how the
-     * values are broken up. The parser is not required to support this
-     * callback, but implementors of this interface should understand it. The
-     * most likely time we will have this method called is for MFString or
-     * URL lists. If called, it is guaranteed to split the strings along the
-     * SF node type boundaries.
-     *
-     * @param values The list of string representing the values
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void fieldValue(String[] values) throws SAVException, VRMLException {
-    }
-
-    /**
-     * The field value is a USE for the given node name. This is a
-     * terminating call for startField as well. The next call will either be
-     * another <code>startField()</code> or <code>endNode()</code>.
-     *
-     * @param defName The name of the DEF string to use
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void useDecl(String defName) throws SAVException, VRMLException {
-    }
-
-    /**
-     * Notification of the end of a field declaration. This is called only at
-     * the end of an MFNode declaration. All other fields are terminated by
-     * either {@link #useDecl(String)} or {@link #fieldValue(String)}. This
-     * will only ever be called if there have been nodes declared. If no nodes
-     * have been declared (ie "[]") then you will get a
-     * <code>fieldValue()</code>. call with the parameter value of null.
-     *
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void endField() throws SAVException, VRMLException {
-    }
-
-    /**
-     * Set the value of the field at the given index as an integer. This would
-     * be used to set SFInt32 field types.
-     *
-     * @param value The new value to use for the node
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void fieldValue(int value)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * Set the value of the field at the given index as an array of integers.
-     * This would be used to set MFInt32 field types.
-     *
-     * @param value The new value to use for the node
-     * @param len The number of valid entries in the value array
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void fieldValue(int[] value, int len)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * Set the value of the field at the given index as an boolean. This would
-     * be used to set SFBool field types.
-     *
-     * @param value The new value to use for the node
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void fieldValue(boolean value)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * Set the value of the field at the given index as an array of boolean.
-     * This would be used to set MFBool field types.
-     *
-     * @param value The new value to use for the node
-     * @param len The number of valid entries in the value array
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void fieldValue(boolean[] value, int len)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * Set the value of the field at the given index as a float. This would
-     * be used to set SFFloat field types.
-     *
-     * @param value The new value to use for the node
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void fieldValue(float value)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * Set the value of the field at the given index as an array of floats.
-     * This would be used to set MFFloat, SFVec2f, SFVec3f and SFRotation
-     * field types.
-     *
-     * @param value The new value to use for the node
-     * @param len The number of valid entries in the value array
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void fieldValue(float[] value, int len)
-        throws SAVException, VRMLException {
-
-        writeVector(value, len);
-    }
-
-    /**
-     * Set the value of the field at the given index as an long. This would
-     * be used to set SFTime field types.
-     *
-     * @param value The new value to use for the node
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void fieldValue(long value)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * Set the value of the field at the given index as an array of longs.
-     * This would be used to set MFTime field types.
-     *
-     * @param value The new value to use for the node
-     * @param len The number of valid entries in the value array
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void fieldValue(long[] value, int len)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * Set the value of the field at the given index as an double. This would
-     * be used to set SFDouble field types.
-     *
-     * @param value The new value to use for the node
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void fieldValue(double value)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * Set the value of the field at the given index as an array of doubles.
-     * This would be used to set MFDouble, SFVec2d and SFVec3d field types.
-     *
-     * @param value The new value to use for the node
-     * @param len The number of valid entries in the value array
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void fieldValue(double[] value, int len)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * Set the value of the field at the given index as an array of strings.
-     * This would be used to set MFString field types.
-     *
-     * @param value The new value to use for the node
-     * @param len The number of valid entries in the value array
-     * @throws SAVException This call is taken at the wrong time in the
-     *   structure of the document.
-     * @throws VRMLException This call is taken at the wrong time in the
-     *   structure of the document.
-     */
-    public void fieldValue(String[] value, int len)
-        throws SAVException, VRMLException {
-    }
-
-    /**
-     * Write out the point field.
-     */
-    private void writeVector(float[] fval, int len) {
-System.out.println("Writing Vector Original size: " + len * 4);
-        try {
-            CompressionTools.compressFloatArray(dos, false, 3, fval);
-
-//            CompressionStream cs = new CompressionStream(CompressedGeometryHeader.TRIANGLE_BUFFER,GeometryArray.NORMALS);
-
-            Vector3f norm = new Vector3f();
-
-            for(int i=0; i < len;) {
-                norm.x = fval[i++];
-                norm.y = fval[i++];
-                norm.z = fval[i++];
-
-//                cs.addNormal(norm);
-            }
-
-//            GeometryCompressor cg = new GeometryCompressor();
-//            CompressedGeometry geom;
-
-//            geom = cg.compress(cs);
-//            byte[] buff = new byte[geom.getByteCount()];
-//            geom.getCompressedGeometry(buff);
-
-//            dos.writeInt(buff.length);
-//            dos.write(buff);
-        } catch(IOException ioe) {
-            ioe.printStackTrace(System.err);
-        }
-    }
-
-    @Override
-    public int[] compress(VRMLNodeType node) {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public void decompress(int[] data) {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public boolean handleData(String nodeName, String fieldName) {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public void fillData(String nodeName, BinaryContentHandler ch) {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-
-    @Override
-    public String getEncoderMetadata() {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001 - 2005
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.export.compressors;
+
+// External imports
+//import javax.media.j3d.*;
+
+//import com.sun.j3d.utils.compression.*;
+
+import java.io.IOException;
+import java.io.DataOutputStream;
+
+import javax.vecmath.Vector3f;
+
+// Local imports
+import org.web3d.vrml.lang.VRMLException;
+import org.web3d.vrml.nodes.VRMLNodeType;
+import org.web3d.vrml.sav.*;
+import org.web3d.vrml.parser.VRMLFieldReader;
+
+/**
+ * A node compressor for Normal nodes.  Implements the normal compression
+ * method devised by the Java3D team.
+ *
+ * IPR Warning: This method has patents on it(Sun Microsystems).  We are trying to secure a
+ * royalty free license for X3D implementations.
+ *
+ * @author Alan Hudson.
+ * @version $Revision: 1.6 $
+ */
+public class NormalCompressor implements SceneGraphCompressor {
+    private DataOutputStream dos;
+    private VRMLFieldReader fieldParser;
+
+    /**
+     * Reinitialize this class for a new instance.
+     *
+     * @param dos The output stream to use.
+     * @param vfr The field parser to use.
+     */
+    public void reinit(DataOutputStream dos, VRMLFieldReader vfr) {
+        this.dos = dos;
+        fieldParser = vfr;
+    }
+
+    /**
+     * Can this NodeCompressor support this compression method
+     *
+     * @param nodeNumber What node, constant defined by Web3D Consortium
+     * @param method What method of compression.  0-127 defined by Web3D Consortium.
+     * @return
+     */
+    public boolean canSupport(int nodeNumber, int method) {
+        // TODO: get a real value
+        return true;
+    }
+
+    /**
+     * Set the document locator that can be used by the implementing code to
+     * find out information about the current line information. This method
+     * is called by the parser to your code to give you a locator to work with.
+     * If this has not been set by the time <code>startDocument()</code> has
+     * been called, you can assume that you will not have one available.
+     *
+     * @param loc The locator instance to use
+     */
+    public void setDocumentLocator(Locator loc) {
+    }
+
+    /**
+     * Declaration of the start of the document. The parameters are all of the
+     * values that are declared on the header line of the file after the
+     * <code>#</code> start. The type string contains the representation of
+     * the first few characters of the file after the #. This allows us to
+     * work out if it is VRML97 or the later X3D spec.
+     * <p>
+     * Version numbers change from VRML97 to X3D and aren't logical. In the
+     * first, it is <code>#VRML V2.0</code> and the second is
+     * <code>#X3D V1.0</code> even though this second header represents a
+     * later spec.
+     *
+     * @param url The base URL of the file for resolving relative URIs
+     *    contained in the file
+     * @param encoding The encoding of this document - utf8 or binary
+     * @param type The bytes of the first part of the file header
+     * @param version The full VRML version string of this document
+     * @param comment Any trailing text on this line. If there is none, this
+     *    is null.
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void startDocument(String url,
+                              String encoding,
+                              String type,
+                              String version,
+                              String comment)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * A profile declaration has been found in the code. IAW the X3D
+     * specification, this method will only ever be called once in the lifetime
+     * of the parser for this document. The name is the name of the profile
+     * for the document to use.
+     *
+     * @param profileName The name of the profile to use
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void profileDecl(String profileName)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * A component declaration has been found in the code. There may be zero
+     * or more component declarations in the file, appearing just after the
+     * profile declaration. The textual information after the COMPONENT keyword
+     * is left unparsed and presented through this call. It is up to the user
+     * application to parse the component information.
+     *
+     * @param componentName The name of the component to use
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void componentDecl(String componentName)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * A META declaration has been found in the code. There may be zero
+     * or more meta declarations in the file, appearing just after the
+     * component declaration. Each meta declaration has a key and value
+     * strings. No information is to be implied from this. It is for extra
+     * data only.
+     *
+     * @param key The value of the key string
+     * @param value The value of the value string
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void metaDecl(String key, String value)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * An IMPORT declaration has been found in the document. All three
+     * parameters will always be provided, regardless of whether the AS keyword
+     * has been used or not. The parser implementation will automatically set
+     * the local import name as needed.
+     *
+     * @param inline The name of the inline DEF nodes
+     * @param exported The exported name from the inlined file
+     * @param imported The local name to use for the exported name
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void importDecl(String inline, String exported, String imported)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * An EXPORT declaration has been found in the document. Both paramters
+     * will always be provided regardless of whether the AS keyword has been
+     * used. The parser implementation will automatically set the exported
+     * name as needed.
+     *
+     * @param defName The DEF name of the nodes to be exported
+     * @param exported The name to be exported as
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void exportDecl(String defName, String exported)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * Declaration of the end of the document. There will be no further parsing
+     * and hence events after this.
+     *
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void endDocument() throws SAVException, VRMLException {
+    }
+
+    /**
+     * Notification of the start of a node. This is the opening statement of a
+     * node and it's DEF name. USE declarations are handled in a separate
+     * method.
+     *
+     * @param name The name of the node that we are about to parse
+     * @param defName The string associated with the DEF name. Null if not
+     *   given for this node.
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void startNode(String name, String defName)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * Notification of the end of a node declaration.
+     *
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void endNode() throws SAVException, VRMLException {
+    }
+
+    /**
+     * Notification of a field declaration. This notification is only called
+     * if it is a standard node. If the node is a script or PROTO declaration
+     * then the {@link ScriptHandler} or {@link ProtoHandler} methods are
+     * used.
+     *
+     * @param name The name of the field declared
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void startField(String name) throws SAVException, VRMLException {
+
+    }
+
+    /**
+     * The value of a normal field. This is a string that represents the entire
+     * value of the field. MFStrings will have to be parsed. This is a
+     * terminating call for startField as well. The next call will either be
+     * another <code>startField()</code> or <code>endNode()</code>.
+     * <p>
+     * If this field is an SFNode with a USE declaration you will have the
+     * {@link #useDecl(String)} method called rather than this method. If the
+     * SFNode is empty the value returned here will be "NULL".
+     * <p>
+     * There are times where we have an MFField that is declared in the file
+     * to be empty. To signify this case, this method will be called with a
+     * parameter value of null. A lot of the time this is because we can't
+     * really determine if the incoming node is an MFNode or not.
+     *
+     * @param value The value of this field
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void fieldValue(String value) throws SAVException, VRMLException {
+        float[] fval = fieldParser.MFVec3f(value);
+
+        writeVector(fval, fval.length);
+    }
+
+    /**
+     * The value of an MFField where the underlying parser knows about how the
+     * values are broken up. The parser is not required to support this
+     * callback, but implementors of this interface should understand it. The
+     * most likely time we will have this method called is for MFString or
+     * URL lists. If called, it is guaranteed to split the strings along the
+     * SF node type boundaries.
+     *
+     * @param values The list of string representing the values
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void fieldValue(String[] values) throws SAVException, VRMLException {
+    }
+
+    /**
+     * The field value is a USE for the given node name. This is a
+     * terminating call for startField as well. The next call will either be
+     * another <code>startField()</code> or <code>endNode()</code>.
+     *
+     * @param defName The name of the DEF string to use
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void useDecl(String defName) throws SAVException, VRMLException {
+    }
+
+    /**
+     * Notification of the end of a field declaration. This is called only at
+     * the end of an MFNode declaration. All other fields are terminated by
+     * either {@link #useDecl(String)} or {@link #fieldValue(String)}. This
+     * will only ever be called if there have been nodes declared. If no nodes
+     * have been declared (ie "[]") then you will get a
+     * <code>fieldValue()</code>. call with the parameter value of null.
+     *
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void endField() throws SAVException, VRMLException {
+    }
+
+    /**
+     * Set the value of the field at the given index as an integer. This would
+     * be used to set SFInt32 field types.
+     *
+     * @param value The new value to use for the node
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void fieldValue(int value)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * Set the value of the field at the given index as an array of integers.
+     * This would be used to set MFInt32 field types.
+     *
+     * @param value The new value to use for the node
+     * @param len The number of valid entries in the value array
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void fieldValue(int[] value, int len)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * Set the value of the field at the given index as an boolean. This would
+     * be used to set SFBool field types.
+     *
+     * @param value The new value to use for the node
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void fieldValue(boolean value)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * Set the value of the field at the given index as an array of boolean.
+     * This would be used to set MFBool field types.
+     *
+     * @param value The new value to use for the node
+     * @param len The number of valid entries in the value array
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void fieldValue(boolean[] value, int len)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * Set the value of the field at the given index as a float. This would
+     * be used to set SFFloat field types.
+     *
+     * @param value The new value to use for the node
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void fieldValue(float value)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * Set the value of the field at the given index as an array of floats.
+     * This would be used to set MFFloat, SFVec2f, SFVec3f and SFRotation
+     * field types.
+     *
+     * @param value The new value to use for the node
+     * @param len The number of valid entries in the value array
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void fieldValue(float[] value, int len)
+        throws SAVException, VRMLException {
+
+        writeVector(value, len);
+    }
+
+    /**
+     * Set the value of the field at the given index as an long. This would
+     * be used to set SFTime field types.
+     *
+     * @param value The new value to use for the node
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void fieldValue(long value)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * Set the value of the field at the given index as an array of longs.
+     * This would be used to set MFTime field types.
+     *
+     * @param value The new value to use for the node
+     * @param len The number of valid entries in the value array
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void fieldValue(long[] value, int len)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * Set the value of the field at the given index as an double. This would
+     * be used to set SFDouble field types.
+     *
+     * @param value The new value to use for the node
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void fieldValue(double value)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * Set the value of the field at the given index as an array of doubles.
+     * This would be used to set MFDouble, SFVec2d and SFVec3d field types.
+     *
+     * @param value The new value to use for the node
+     * @param len The number of valid entries in the value array
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void fieldValue(double[] value, int len)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * Set the value of the field at the given index as an array of strings.
+     * This would be used to set MFString field types.
+     *
+     * @param value The new value to use for the node
+     * @param len The number of valid entries in the value array
+     * @throws SAVException This call is taken at the wrong time in the
+     *   structure of the document.
+     * @throws VRMLException This call is taken at the wrong time in the
+     *   structure of the document.
+     */
+    public void fieldValue(String[] value, int len)
+        throws SAVException, VRMLException {
+    }
+
+    /**
+     * Write out the point field.
+     */
+    private void writeVector(float[] fval, int len) {
+System.out.println("Writing Vector Original size: " + len * 4);
+        try {
+            CompressionTools.compressFloatArray(dos, false, 3, fval);
+
+//            CompressionStream cs = new CompressionStream(CompressedGeometryHeader.TRIANGLE_BUFFER,GeometryArray.NORMALS);
+
+            Vector3f norm = new Vector3f();
+
+            for(int i=0; i < len;) {
+                norm.x = fval[i++];
+                norm.y = fval[i++];
+                norm.z = fval[i++];
+
+//                cs.addNormal(norm);
+            }
+
+//            GeometryCompressor cg = new GeometryCompressor();
+//            CompressedGeometry geom;
+
+//            geom = cg.compress(cs);
+//            byte[] buff = new byte[geom.getByteCount()];
+//            geom.getCompressedGeometry(buff);
+
+//            dos.writeInt(buff.length);
+//            dos.write(buff);
+        } catch(IOException ioe) {
+            ioe.printStackTrace(System.err);
+        }
+    }
+
+    @Override
+    public int[] compress(VRMLNodeType node) {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public void decompress(int[] data) {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public boolean handleData(String nodeName, String fieldName) {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public void fillData(String nodeName, BinaryContentHandler ch) {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public String getEncoderMetadata() {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+}
diff --git a/src/java/org/web3d/vrml/export/compressors/RangeCompressor.java b/src/java/org/web3d/vrml/export/compressors/RangeCompressor.java
index adfdcdb6ec29aa4253d90839771c847248dc555b..cd80f050b36507e86292453e92bb7839efbe2c50 100644
--- a/src/java/org/web3d/vrml/export/compressors/RangeCompressor.java
+++ b/src/java/org/web3d/vrml/export/compressors/RangeCompressor.java
@@ -1,78 +1,78 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-package org.web3d.vrml.export.compressors;
-
-// Standard library imports
-
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-// Application specific imports
-import org.web3d.vrml.lang.*;
-
-/**
- * A FieldCompressor that works by compressing the range of data.  Floats are
- * converted to ints before range compression.
- *
- * @author Alan Hudson
- * @version $Revision: 1.4 $
- */
-public class RangeCompressor extends BinaryFieldEncoder {
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     * @throws java.io.IOException
-     */
-    @Override
-    public void compress(DataOutputStream dos, int fieldType, int[] data)
-        throws IOException {
-
-        CompressionTools.rangeCompressIntArray(dos,false,1,data);
-    }
-
-    /**
-     * Compress this field and deposit the output to the bitstream
-     *
-     * @param dos The stream to output the result
-     * @param fieldType The type of field to compress from FieldConstants.
-     * @param data The field data
-     * @throws java.io.IOException
-     */
-    @Override
-    public void compress(DataOutputStream dos, int fieldType, float[] data)
-        throws IOException {
-        switch(fieldType) {
-            case FieldConstants.SFCOLOR:
-            case FieldConstants.SFVEC3F:
-            case FieldConstants.SFROTATION:
-            case FieldConstants.SFCOLORRGBA:
-            case FieldConstants.SFVEC2F:
-                for(int i=0; i < data.length; i++) {
-                   dos.writeFloat(data[i]);
-                }
-                break;
-            case FieldConstants.MFCOLOR:
-            case FieldConstants.MFVEC3F:
-            case FieldConstants.MFFLOAT:
-            case FieldConstants.MFROTATION:
-            case FieldConstants.MFCOLORRGBA:
-            case FieldConstants.MFVEC2F:
-                CompressionTools.compressFloatArray(dos, false,1,data);
-                break;
-            default:
-                System.out.println("Unhandled datatype in compress float[]: " + fieldType);
-        }
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+package org.web3d.vrml.export.compressors;
+
+// Standard library imports
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+// Application specific imports
+import org.web3d.vrml.lang.*;
+
+/**
+ * A FieldCompressor that works by compressing the range of data.  Floats are
+ * converted to ints before range compression.
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.4 $
+ */
+public class RangeCompressor extends BinaryFieldEncoder {
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     * @throws java.io.IOException
+     */
+    @Override
+    public void compress(DataOutputStream dos, int fieldType, int[] data)
+        throws IOException {
+
+        CompressionTools.rangeCompressIntArray(dos,false,1,data);
+    }
+
+    /**
+     * Compress this field and deposit the output to the bitstream
+     *
+     * @param dos The stream to output the result
+     * @param fieldType The type of field to compress from FieldConstants.
+     * @param data The field data
+     * @throws java.io.IOException
+     */
+    @Override
+    public void compress(DataOutputStream dos, int fieldType, float[] data)
+        throws IOException {
+        switch(fieldType) {
+            case FieldConstants.SFCOLOR:
+            case FieldConstants.SFVEC3F:
+            case FieldConstants.SFROTATION:
+            case FieldConstants.SFCOLORRGBA:
+            case FieldConstants.SFVEC2F:
+                for(int i=0; i < data.length; i++) {
+                   dos.writeFloat(data[i]);
+                }
+                break;
+            case FieldConstants.MFCOLOR:
+            case FieldConstants.MFVEC3F:
+            case FieldConstants.MFFLOAT:
+            case FieldConstants.MFROTATION:
+            case FieldConstants.MFCOLORRGBA:
+            case FieldConstants.MFVEC2F:
+                CompressionTools.compressFloatArray(dos, false,1,data);
+                break;
+            default:
+                System.out.println("Unhandled datatype in compress float[]: " + fieldType);
+        }
+    }
+}
diff --git a/src/java/org/web3d/vrml/lang/AbstractScene.java b/src/java/org/web3d/vrml/lang/AbstractScene.java
index e10dae0a5f679faa9b0c62f20a1e56ad8419d440..db1d772af6ea06cfe65c7fe91ee86f17f22d5742 100644
--- a/src/java/org/web3d/vrml/lang/AbstractScene.java
+++ b/src/java/org/web3d/vrml/lang/AbstractScene.java
@@ -26,6 +26,8 @@ import org.j3d.util.IntHashMap;
 
 /**
  * Abstract implementation of the {@link BasicScene} interface.
+ * <p>
+ *
  *
  * @author Justin Couch
  * @version $Revision: 1.16 $
diff --git a/src/java/org/web3d/vrml/lang/FieldException.java b/src/java/org/web3d/vrml/lang/FieldException.java
index 9be61c51562c07c2c11270ebb18a52142b55598c..19f5915342b4bb53f436ce9c12c7fab13c566abe 100644
--- a/src/java/org/web3d/vrml/lang/FieldException.java
+++ b/src/java/org/web3d/vrml/lang/FieldException.java
@@ -20,6 +20,7 @@ package org.web3d.vrml.lang;
 
 /**
  * Superclass of all exceptions describing errors in fields.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/lang/InvalidFieldConnectionException.java b/src/java/org/web3d/vrml/lang/InvalidFieldConnectionException.java
index f80b6621b3e08babe62c54d8a54569497003f32d..2c9aa369cce82bce3288ba3a505852e77271968f 100644
--- a/src/java/org/web3d/vrml/lang/InvalidFieldConnectionException.java
+++ b/src/java/org/web3d/vrml/lang/InvalidFieldConnectionException.java
@@ -21,6 +21,8 @@ package org.web3d.vrml.lang;
 /**
  * Exception when the file attempts to make a connection such as a ROUTE or
  * IS between two incompatible or undefined fields and/or nodes.
+ *  <p>
+ *
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/lang/InvalidFieldTypeException.java b/src/java/org/web3d/vrml/lang/InvalidFieldTypeException.java
index a06f8fa69c7b94036419f0f55486d92ef6c1d66a..18ca3ced2fc3cb6888c916b6ed39e47df8a431dd 100644
--- a/src/java/org/web3d/vrml/lang/InvalidFieldTypeException.java
+++ b/src/java/org/web3d/vrml/lang/InvalidFieldTypeException.java
@@ -21,6 +21,7 @@ package org.web3d.vrml.lang;
 /**
  * Error when the type of the field does not match, such as for routes,
  * scripting or internal manipulation.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/lang/InvalidNodeTypeException.java b/src/java/org/web3d/vrml/lang/InvalidNodeTypeException.java
index 0035825fb6492f2beb9698c050de50c9c1d8db79..629212d8ff32c5df870b9be7f1b508ed03bc497e 100644
--- a/src/java/org/web3d/vrml/lang/InvalidNodeTypeException.java
+++ b/src/java/org/web3d/vrml/lang/InvalidNodeTypeException.java
@@ -20,6 +20,7 @@ package org.web3d.vrml.lang;
 
 /**
  * Superclass of all exceptions relating to node errors.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/lang/NodeException.java b/src/java/org/web3d/vrml/lang/NodeException.java
index 70f7159a5bd57386ebdcee53fd87701ef0fbadd4..d033c9cf0b1a375be82b43f23858305597d61284 100644
--- a/src/java/org/web3d/vrml/lang/NodeException.java
+++ b/src/java/org/web3d/vrml/lang/NodeException.java
@@ -20,6 +20,7 @@ package org.web3d.vrml.lang;
 
 /**
  * Superclass of all exceptions relating to node errors.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/lang/TextureConstants.java b/src/java/org/web3d/vrml/lang/TextureConstants.java
index 191c29d3a3ea79345beb5b824a2cb70a12def228..2bb8b373da79208a837dac835ff9bff2e70e3150 100644
--- a/src/java/org/web3d/vrml/lang/TextureConstants.java
+++ b/src/java/org/web3d/vrml/lang/TextureConstants.java
@@ -14,6 +14,7 @@ package org.web3d.vrml.lang;
 
 /**
  * Listing of type constants for textures.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/lang/VRMLException.java b/src/java/org/web3d/vrml/lang/VRMLException.java
index 042f3f612245a12bfd20815c0cb78e5eb811ec1e..b497f4bc019051769a4547b707beab135ff6d67b 100644
--- a/src/java/org/web3d/vrml/lang/VRMLException.java
+++ b/src/java/org/web3d/vrml/lang/VRMLException.java
@@ -21,6 +21,7 @@ package org.web3d.vrml.lang;
 /**
  * Superclass of all exceptions provided by this package and for all of the
  * VRML implementation.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/nodes/FrameStateManager.java b/src/java/org/web3d/vrml/nodes/FrameStateManager.java
index a1af51fc3f17a244a996cf28be573057bd3168ee..8e4c45e30d28d22ca82483d0818a5d8918aa285e 100644
--- a/src/java/org/web3d/vrml/nodes/FrameStateManager.java
+++ b/src/java/org/web3d/vrml/nodes/FrameStateManager.java
@@ -27,6 +27,7 @@ import org.web3d.vrml.lang.VRMLNodeTemplate;
 /**
  * A representation of a manager that handles the current frame state and
  * the listeners that wish to know about it.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.11 $
diff --git a/src/java/org/web3d/vrml/nodes/ImportNodeProxy.java b/src/java/org/web3d/vrml/nodes/ImportNodeProxy.java
index 27c7e85b82efe7e3a9d95ebe88f14c30936874b6..dd09f5a54432876d597949b4604a3740fe6ecf54 100644
--- a/src/java/org/web3d/vrml/nodes/ImportNodeProxy.java
+++ b/src/java/org/web3d/vrml/nodes/ImportNodeProxy.java
@@ -32,6 +32,7 @@ import org.web3d.vrml.lang.VRMLFieldDeclaration;
 
 /**
  * A proxy node representation for allowing processing of X3D imports.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.7 $
diff --git a/src/java/org/web3d/vrml/nodes/LayerListener.java b/src/java/org/web3d/vrml/nodes/LayerListener.java
index 58f045d81545fb2850992fcb84a1d654f847a954..86b53532f2b4e4139102f8730c8a5fc6734c9924 100644
--- a/src/java/org/web3d/vrml/nodes/LayerListener.java
+++ b/src/java/org/web3d/vrml/nodes/LayerListener.java
@@ -20,6 +20,7 @@ package org.web3d.vrml.nodes;
 
 /**
  * A listener for changes in layer state.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/nodes/LocalColorsListener.java b/src/java/org/web3d/vrml/nodes/LocalColorsListener.java
index 659972759bb862ab3bffc18c3137eda1ba2df8b0..e2b5d30ba12df4a4f833acc714524e689a82af4e 100644
--- a/src/java/org/web3d/vrml/nodes/LocalColorsListener.java
+++ b/src/java/org/web3d/vrml/nodes/LocalColorsListener.java
@@ -20,9 +20,10 @@ package org.web3d.vrml.nodes;
 
 /**
  * A listener for changes in local color state.
- * 
+ * <p>
  * Local color states whether a geometry node has color per vertex/face information
  * that overrides the diffuse component of the Material node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/nodes/MaterialColorListener.java b/src/java/org/web3d/vrml/nodes/MaterialColorListener.java
index e39e968b977be4fd49a484acb7f6d6e4bfb06015..1b2ac29ca83fdb309b26c446b6ef3ff8ad7d566f 100644
--- a/src/java/org/web3d/vrml/nodes/MaterialColorListener.java
+++ b/src/java/org/web3d/vrml/nodes/MaterialColorListener.java
@@ -19,17 +19,15 @@ package org.web3d.vrml.nodes;
 // none
 
 /**
- * <p>
  * A listener for changes in color values from the material node that are used
  * in a more global manner in the internal rendering structure.
- * </p>
- *
  * <p>
+ *
  * Some nodes, like lines and points need to pass some of the material colour
  * values back to the geometry for use there when there is no lighting. This
  * listener instance is typically implemented by the shape node, but passed
  * down to the material through the appearance.
- * </p>
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/nodes/MaterialColorListenerMulticaster.java b/src/java/org/web3d/vrml/nodes/MaterialColorListenerMulticaster.java
index 0307cbee5e24accf8c85cf3f03801fd38b6877b6..4111c759c5ddd3a4dcaf44d4b0d347f97734cc23 100644
--- a/src/java/org/web3d/vrml/nodes/MaterialColorListenerMulticaster.java
+++ b/src/java/org/web3d/vrml/nodes/MaterialColorListenerMulticaster.java
@@ -1,233 +1,233 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.nodes;
-
-// External imports
-// none
-
-// Local imports
-import org.j3d.util.DefaultErrorReporter;
-import org.j3d.util.ErrorReporter;
-
-/**
- * A class which implements efficient and thread-safe multi-cast event
- * dispatching for the events defined in this package.
- * <p>
- *
- * This class will manage an immutable structure consisting of a chain of
- * event listeners and will dispatch events to those listeners.  Because
- * the structure is immutable, it is safe to use this API to add/remove
- * listeners during the process of an event dispatch operation.
- * <p>
- *
- * An example of how this class could be used to implement a new
- * component which fires "action" events:
- *
- * <pre><code>
- * public myComponent extends Component {
- *   MaterialColorListener nodeListener = null;
- *
- *   public void addNodeListener(MaterialColorListener l) {
- *     nodeListener = MaterialColorListenerMulticaster.add(nodeListener, l);
- *   }
- *
- *   public void removeNodeListener(MaterialColorListener l) {
- *     nodeListener = MaterialColorListenerMulticaster.remove(nodeListener, l);
- *   }
- *
- *   public void fireColorChanged(float[] color) {
- *     if(nodeListener != null) {
- *       nodeListener.emissiveColorChanged(color);
- *   }
- * }
- * </code></pre>
- *
- * @author  Justin Couch
- * @version $Revision: 1.1 $
- */
-public class MaterialColorListenerMulticaster
-    implements MaterialColorListener {
-
-    /** Error message when the user code barfs */
-    private static final String EMISSIVE_ERROR_MSG =
-        "Error sending emissive changed notification to: ";
-
-    /** The node listeners in use by this class */
-    private final MaterialColorListener a, b;
-
-    /** Reporter instance for handing out errors */
-    private static ErrorReporter errorReporter =
-        DefaultErrorReporter.getDefaultReporter();
-
-    /**
-     * Creates an event multicaster instance which chains listener-a
-     * with listener-b. Input parameters <code>a</code> and <code>b</code>
-     * should not be <code>null</code>, though implementations may vary in
-     * choosing whether or not to throw <code>NullPointerException</code>
-     * in that case.
-     * @param a listener-a
-     * @param b listener-b
-     */
-    public MaterialColorListenerMulticaster(MaterialColorListener a,
-                                            MaterialColorListener b) {
-        this.a = a;
-        this.b = b;
-    }
-
-    /**
-     * Removes a listener from this multicaster and returns the
-     * resulting multicast listener.
-     * @param oldl the listener to be removed
-     * @return 
-     */
-    public MaterialColorListener remove(MaterialColorListener oldl) {
-
-        if(oldl == a)
-            return b;
-
-        if(oldl == b)
-            return a;
-
-        MaterialColorListener a2 = removeInternal(a, oldl);
-        MaterialColorListener b2 = removeInternal(b, oldl);
-
-        if (a2 == a && b2 == b) {
-            return this;  // it's not here
-        }
-
-        return addInternal(a2, b2);
-    }
-
-    /**
-     * Register an error reporter with the engine so that any errors generated
-     * by the loading of script code can be reported in a nice, pretty fashion.
-     * Setting a value of null will clear the currently set reporter. If one
-     * is already set, the new value replaces the old.
-     *
-     * @param reporter The instance to use or null
-     */
-    public static void setErrorReporter(ErrorReporter reporter) {
-        errorReporter = reporter;
-
-        // Reset the default only if we are not shutting down the system.
-        if(reporter == null)
-            errorReporter = DefaultErrorReporter.getDefaultReporter();
-    }
-
-    /**
-     * Adds input-method-listener-a with input-method-listener-b and
-     * returns the resulting multicast listener.
-     * @param a input-method-listener-a
-     * @param b input-method-listener-b
-     * @return 
-     */
-    public static MaterialColorListener add(MaterialColorListener a,
-                                            MaterialColorListener b) {
-        return addInternal(a, b);
-    }
-
-    /**
-     * Removes the old component-listener from component-listener-l and
-     * returns the resulting multicast listener.
-     * @param l component-listener-l
-     * @param oldl the component-listener being removed
-     * @return 
-     */
-    public static MaterialColorListener remove(MaterialColorListener l,
-                                               MaterialColorListener oldl) {
-        return removeInternal(l, oldl);
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by MaterialColorListener
-    //----------------------------------------------------------
-
-    /**
-     * Send a emissiveColor change notification.
-     *
-     * @param color The new color value to use
-     */
-    @Override
-    public void emissiveColorChanged(float[] color) {
-        try {
-            a.emissiveColorChanged(color);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(EMISSIVE_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println("Unknown BAAAAD error: " + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.emissiveColorChanged(color);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(EMISSIVE_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println("Unknown BAAAAD error: " + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-
-    //----------------------------------------------------------
-    // Local Methods
-    //----------------------------------------------------------
-
-    /**
-     * Returns the resulting multicast listener from adding listener-a
-     * and listener-b together.
-     * If listener-a is null, it returns listener-b;
-     * If listener-b is null, it returns listener-a
-     * If neither are null, then it creates and returns
-     * a new MaterialColorMulticaster instance which chains a with b.
-     * @param a event listener-a
-     * @param b event listener-b
-     */
-    private static MaterialColorListener addInternal(MaterialColorListener a,
-                                                     MaterialColorListener b) {
-        if(a == null)
-            return b;
-
-        if(b == null)
-            return a;
-
-        return new MaterialColorListenerMulticaster(a, b);
-    }
-
-    /**
-     * Returns the resulting multicast listener after removing the
-     * old listener from listener-l.
-     * If listener-l equals the old listener OR listener-l is null,
-     * returns null.
-     * Else if listener-l is an instance of MaterialColorMulticaster,
-     * then it removes the old listener from it.
-     * Else, returns listener l.
-     * @param l the listener being removed from
-     * @param oldl the listener being removed
-     */
-    private static MaterialColorListener removeInternal(MaterialColorListener l,
-                                                        MaterialColorListener oldl) {
-        if (l == oldl || l == null) {
-            return null;
-        } else if (l instanceof MaterialColorListenerMulticaster) {
-            return ((MaterialColorListenerMulticaster)l).remove(oldl);
-        } else {
-            return l;   // it's not here
-        }
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.nodes;
+
+// External imports
+// none
+
+// Local imports
+import org.j3d.util.DefaultErrorReporter;
+import org.j3d.util.ErrorReporter;
+
+/**
+ * A class which implements efficient and thread-safe multi-cast event
+ * dispatching for the events defined in this package.
+ * <p>
+ *
+ * This class will manage an immutable structure consisting of a chain of
+ * event listeners and will dispatch events to those listeners.  Because
+ * the structure is immutable, it is safe to use this API to add/remove
+ * listeners during the process of an event dispatch operation.
+ * <p>
+ *
+ * An example of how this class could be used to implement a new
+ * component which fires "action" events:
+ *
+ * <pre><code>
+ * public myComponent extends Component {
+ *   MaterialColorListener nodeListener = null;
+ *
+ *   public void addNodeListener(MaterialColorListener l) {
+ *     nodeListener = MaterialColorListenerMulticaster.add(nodeListener, l);
+ *   }
+ *
+ *   public void removeNodeListener(MaterialColorListener l) {
+ *     nodeListener = MaterialColorListenerMulticaster.remove(nodeListener, l);
+ *   }
+ *
+ *   public void fireColorChanged(float[] color) {
+ *     if(nodeListener != null) {
+ *       nodeListener.emissiveColorChanged(color);
+ *   }
+ * }
+ * </code></pre>
+ *
+ * @author  Justin Couch
+ * @version $Revision: 1.1 $
+ */
+public class MaterialColorListenerMulticaster
+    implements MaterialColorListener {
+
+    /** Error message when the user code barfs */
+    private static final String EMISSIVE_ERROR_MSG =
+        "Error sending emissive changed notification to: ";
+
+    /** The node listeners in use by this class */
+    private final MaterialColorListener a, b;
+
+    /** Reporter instance for handing out errors */
+    private static ErrorReporter errorReporter =
+        DefaultErrorReporter.getDefaultReporter();
+
+    /**
+     * Creates an event multicaster instance which chains listener-a
+     * with listener-b. Input parameters <code>a</code> and <code>b</code>
+     * should not be <code>null</code>, though implementations may vary in
+     * choosing whether or not to throw <code>NullPointerException</code>
+     * in that case.
+     * @param a listener-a
+     * @param b listener-b
+     */
+    public MaterialColorListenerMulticaster(MaterialColorListener a,
+                                            MaterialColorListener b) {
+        this.a = a;
+        this.b = b;
+    }
+
+    /**
+     * Removes a listener from this multicaster and returns the
+     * resulting multicast listener.
+     * @param oldl the listener to be removed
+     * @return 
+     */
+    public MaterialColorListener remove(MaterialColorListener oldl) {
+
+        if(oldl == a)
+            return b;
+
+        if(oldl == b)
+            return a;
+
+        MaterialColorListener a2 = removeInternal(a, oldl);
+        MaterialColorListener b2 = removeInternal(b, oldl);
+
+        if (a2 == a && b2 == b) {
+            return this;  // it's not here
+        }
+
+        return addInternal(a2, b2);
+    }
+
+    /**
+     * Register an error reporter with the engine so that any errors generated
+     * by the loading of script code can be reported in a nice, pretty fashion.
+     * Setting a value of null will clear the currently set reporter. If one
+     * is already set, the new value replaces the old.
+     *
+     * @param reporter The instance to use or null
+     */
+    public static void setErrorReporter(ErrorReporter reporter) {
+        errorReporter = reporter;
+
+        // Reset the default only if we are not shutting down the system.
+        if(reporter == null)
+            errorReporter = DefaultErrorReporter.getDefaultReporter();
+    }
+
+    /**
+     * Adds input-method-listener-a with input-method-listener-b and
+     * returns the resulting multicast listener.
+     * @param a input-method-listener-a
+     * @param b input-method-listener-b
+     * @return 
+     */
+    public static MaterialColorListener add(MaterialColorListener a,
+                                            MaterialColorListener b) {
+        return addInternal(a, b);
+    }
+
+    /**
+     * Removes the old component-listener from component-listener-l and
+     * returns the resulting multicast listener.
+     * @param l component-listener-l
+     * @param oldl the component-listener being removed
+     * @return 
+     */
+    public static MaterialColorListener remove(MaterialColorListener l,
+                                               MaterialColorListener oldl) {
+        return removeInternal(l, oldl);
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by MaterialColorListener
+    //----------------------------------------------------------
+
+    /**
+     * Send a emissiveColor change notification.
+     *
+     * @param color The new color value to use
+     */
+    @Override
+    public void emissiveColorChanged(float[] color) {
+        try {
+            a.emissiveColorChanged(color);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(EMISSIVE_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println("Unknown BAAAAD error: " + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.emissiveColorChanged(color);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(EMISSIVE_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println("Unknown BAAAAD error: " + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+
+    //----------------------------------------------------------
+    // Local Methods
+    //----------------------------------------------------------
+
+    /**
+     * Returns the resulting multicast listener from adding listener-a
+     * and listener-b together.
+     * If listener-a is null, it returns listener-b;
+     * If listener-b is null, it returns listener-a
+     * If neither are null, then it creates and returns
+     * a new MaterialColorMulticaster instance which chains a with b.
+     * @param a event listener-a
+     * @param b event listener-b
+     */
+    private static MaterialColorListener addInternal(MaterialColorListener a,
+                                                     MaterialColorListener b) {
+        if(a == null)
+            return b;
+
+        if(b == null)
+            return a;
+
+        return new MaterialColorListenerMulticaster(a, b);
+    }
+
+    /**
+     * Returns the resulting multicast listener after removing the
+     * old listener from listener-l.
+     * If listener-l equals the old listener OR listener-l is null,
+     * returns null.
+     * Else if listener-l is an instance of MaterialColorMulticaster,
+     * then it removes the old listener from it.
+     * Else, returns listener l.
+     * @param l the listener being removed from
+     * @param oldl the listener being removed
+     */
+    private static MaterialColorListener removeInternal(MaterialColorListener l,
+                                                        MaterialColorListener oldl) {
+        if (l == oldl || l == null) {
+            return null;
+        } else if (l instanceof MaterialColorListenerMulticaster) {
+            return ((MaterialColorListenerMulticaster)l).remove(oldl);
+        } else {
+            return l;   // it's not here
+        }
+    }
+}
diff --git a/src/java/org/web3d/vrml/nodes/NetworkRoleListener.java b/src/java/org/web3d/vrml/nodes/NetworkRoleListener.java
index 910f73f8d1eb0ee64a9a190d64ac71e2bf0003ff..01b2c4420d8caf72117231556f77f758db4a3ae2 100644
--- a/src/java/org/web3d/vrml/nodes/NetworkRoleListener.java
+++ b/src/java/org/web3d/vrml/nodes/NetworkRoleListener.java
@@ -1,36 +1,36 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2004
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-package org.web3d.vrml.nodes;
-
-// Standard imports
-// none
-
-// Application specific imports
-// none
-
-/**
- * Notification that a network node has changed roles.  Roles
- * are defined in VRMLNetworkInterfaceNodeType.
- *
- * @author Alan Hudson
- * @version $Revision: 1.1 $
- */
-public interface NetworkRoleListener {
-    
-    /**
-     * The role of this node has changed.
-     *
-     * @param newRole The new role, reader, writer, inactive.
-     * @param node The node which changed roles.
-     */
-    void roleChanged(int newRole, Object node);
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2004
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+package org.web3d.vrml.nodes;
+
+// Standard imports
+// none
+
+// Application specific imports
+// none
+
+/**
+ * Notification that a network node has changed roles.  Roles
+ * are defined in VRMLNetworkInterfaceNodeType.
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.1 $
+ */
+public interface NetworkRoleListener {
+    
+    /**
+     * The role of this node has changed.
+     *
+     * @param newRole The new role, reader, writer, inactive.
+     * @param node The node which changed roles.
+     */
+    void roleChanged(int newRole, Object node);
+}
diff --git a/src/java/org/web3d/vrml/nodes/TexCoordGenModeListener.java b/src/java/org/web3d/vrml/nodes/TexCoordGenModeListener.java
index 4c879d77e85020635ace0cdd82cbc1da3e7f1df1..9c21af89ae079f34194744d27924345d34ef786e 100644
--- a/src/java/org/web3d/vrml/nodes/TexCoordGenModeListener.java
+++ b/src/java/org/web3d/vrml/nodes/TexCoordGenModeListener.java
@@ -20,6 +20,7 @@ package org.web3d.vrml.nodes;
 
 /**
  * A listener for changes in Texture Coordinate Mode changes.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/nodes/VRMLAppearanceChildNodeType.java b/src/java/org/web3d/vrml/nodes/VRMLAppearanceChildNodeType.java
index 08f1eacaefd4c163985d69f1a9422ea4263a1152..6a44aeafe35b6c044a6c9649c39d99a8788e10a6 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLAppearanceChildNodeType.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLAppearanceChildNodeType.java
@@ -13,6 +13,7 @@ package org.web3d.vrml.nodes;
 
 /**
  * Nodes which can appear in an appearance field of an Appearance Node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.6 $
diff --git a/src/java/org/web3d/vrml/nodes/VRMLBoundedNodeType.java b/src/java/org/web3d/vrml/nodes/VRMLBoundedNodeType.java
index 93752629dc497f7f3573ec777f7bd044d5093cc8..e7331454d07a95fde61a3ff132e309a175b64a19 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLBoundedNodeType.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLBoundedNodeType.java
@@ -18,6 +18,7 @@ package org.web3d.vrml.nodes;
 
 /**
  * Indicates that a node contains a bounding box field.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.9 $
diff --git a/src/java/org/web3d/vrml/nodes/VRMLClock.java b/src/java/org/web3d/vrml/nodes/VRMLClock.java
index 78d87d3f48b8abe7ce7615f1a7e52bc011b53bfb..fe372b6b78a4bf61a101e6a66510f6f19930dbfc 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLClock.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLClock.java
@@ -14,6 +14,7 @@ package org.web3d.vrml.nodes;
 /**
  * Abstract representation of the System clock for various informational
  * purposes.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/nodes/VRMLDragSensorNodeType.java b/src/java/org/web3d/vrml/nodes/VRMLDragSensorNodeType.java
index 33b05af20e76dd5b4a040b72b72e0908bbd30c64..9733d02cd3933f725e9bbb28b458b4fa673e1e9f 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLDragSensorNodeType.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLDragSensorNodeType.java
@@ -19,6 +19,7 @@ package org.web3d.vrml.nodes;
 
 /**
  * A sensor that is driven by pointing device dragging.
+ * <p>
  *
  * @author Alan Hudson, Justin Couch
  * @version $Revision: 1.8 $
diff --git a/src/java/org/web3d/vrml/nodes/VRMLEnvironmentTextureNodeType.java b/src/java/org/web3d/vrml/nodes/VRMLEnvironmentTextureNodeType.java
index 2057cf9e6a9b7ad074c94871ea9c76b917364bfa..2be8d5ebc33899a92e64eded2563f87fc71ab696 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLEnvironmentTextureNodeType.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLEnvironmentTextureNodeType.java
@@ -13,6 +13,7 @@ package org.web3d.vrml.nodes;
 
 /**
  * Specifies a texture for environment mapping - typically cubic.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/nodes/VRMLEnvironmentalSensorNodeType.java b/src/java/org/web3d/vrml/nodes/VRMLEnvironmentalSensorNodeType.java
index d6db55ee9fe2b3dc99365a21b67cd6eb4ae8fc18..ac43745e0442596f42611aa83f2faf365c12853b 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLEnvironmentalSensorNodeType.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLEnvironmentalSensorNodeType.java
@@ -13,6 +13,7 @@ package org.web3d.vrml.nodes;
 
 /**
  * Sensors triggered by environmental effects such as mouse or movement.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.4 $
diff --git a/src/java/org/web3d/vrml/nodes/VRMLExternProtoDeclare.java b/src/java/org/web3d/vrml/nodes/VRMLExternProtoDeclare.java
index 178b25932d793849d9d9f8d9a6019204ab826f34..cdc62b2c1b9efbf44dc08936d0dc861021690e03 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLExternProtoDeclare.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLExternProtoDeclare.java
@@ -21,6 +21,7 @@ import org.web3d.vrml.lang.VRMLNodeTemplate;
 /**
  * VRMLExternProtoDeclare is a node interface, used by implementations of VRML's
  * ExternProtoDeclare node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.10 $
diff --git a/src/java/org/web3d/vrml/nodes/VRMLGeometricPropertyNodeType.java b/src/java/org/web3d/vrml/nodes/VRMLGeometricPropertyNodeType.java
index 86a7e33ade8d1d2e2a2b6a5000a01a95e3fda5dc..b85c03386febf14639e194d64aa1dd0800361f83 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLGeometricPropertyNodeType.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLGeometricPropertyNodeType.java
@@ -13,7 +13,7 @@ package org.web3d.vrml.nodes;
 
 /**
  * A property of a geometric object such as color, coordinate, normal.
- * 
+ * <p>
  * @author Alan Hudson
  * @version $Revision: 1.7 $
  */
diff --git a/src/java/org/web3d/vrml/nodes/VRMLGroupingNodeType.java b/src/java/org/web3d/vrml/nodes/VRMLGroupingNodeType.java
index d6429d0508bb7882ea4c6ca27b4563f6e4e3b980..caebea21274e4a4eb286b769485e88eb89f89b4a 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLGroupingNodeType.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLGroupingNodeType.java
@@ -13,6 +13,7 @@ package org.web3d.vrml.nodes;
 
 /**
  * A node which can contain other nodes.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.10 $
diff --git a/src/java/org/web3d/vrml/nodes/VRMLInlineNodeType.java b/src/java/org/web3d/vrml/nodes/VRMLInlineNodeType.java
index 3a179b28b6fe7ee430fea9e027f8e536a90fb7ca..9c528def71f00668fbb799b7df184822327f50f6 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLInlineNodeType.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLInlineNodeType.java
@@ -20,6 +20,7 @@ import org.web3d.vrml.lang.VRMLNode;
 
 /**
  * Denotes a node type that supports inlining content from external files.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.7 $
diff --git a/src/java/org/web3d/vrml/nodes/VRMLMaterialNodeType.java b/src/java/org/web3d/vrml/nodes/VRMLMaterialNodeType.java
index 05b2b31ef7fdd197b67e8440ca1dcf723be51501..8d0fab3bf2877f11ff9cc3184920d86cb8ad1e5b 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLMaterialNodeType.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLMaterialNodeType.java
@@ -20,8 +20,9 @@ import org.web3d.vrml.lang.InvalidFieldValueException;
 
 /**
  * Node specifies colour properties for associated geometry.
- * 
- * Defines methods needed for standard VRML lighting model equations.
+ * <p>
+ * Defines methods needed for standard VRML lighting model equations
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.10 $
diff --git a/src/java/org/web3d/vrml/nodes/VRMLNBodySensorNodeType.java b/src/java/org/web3d/vrml/nodes/VRMLNBodySensorNodeType.java
index 70c7bb67df6d41f5939e9491725e05f265660e79..a71aaed2cb6f2e019ee4a40165aa2b499424da41 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLNBodySensorNodeType.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLNBodySensorNodeType.java
@@ -20,9 +20,11 @@ import org.j3d.util.IntHashMap;
 
 /**
  * A sensor for reporting nBody collisions back to the X3D scene graph.
+ * <p>
  *
  * See the specification definition at
  * http://www.xj3d.org/extensions/rigid_physics.html
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/nodes/VRMLNetworkInterfaceNodeType.java b/src/java/org/web3d/vrml/nodes/VRMLNetworkInterfaceNodeType.java
index 0fc52810377cdda64e46f1c328f395b6c1e916fd..9713a96b68a8d870929e876d0ee98fde22b1ee24 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLNetworkInterfaceNodeType.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLNetworkInterfaceNodeType.java
@@ -20,6 +20,7 @@ package org.web3d.vrml.nodes;
 
 /**
  * Representation of a node that issue or receive network data.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.4 $
diff --git a/src/java/org/web3d/vrml/nodes/VRMLNormalNodeType.java b/src/java/org/web3d/vrml/nodes/VRMLNormalNodeType.java
index e2c9314f791cb444a38d2a2f145627b2d631692a..f1210a477c30ac0bea2d201053691201dbe7a2d3 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLNormalNodeType.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLNormalNodeType.java
@@ -13,6 +13,7 @@ package org.web3d.vrml.nodes;
 
 /**
  * Defines a set of 3D surface normals.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.8 $
diff --git a/src/java/org/web3d/vrml/nodes/VRMLPointPropertiesNodeType.java b/src/java/org/web3d/vrml/nodes/VRMLPointPropertiesNodeType.java
index dc2bf8ded50b9785b9ef91b42a538a11173539a5..49f15c81f3fc0b0dec0ec08768b7d8b3e8648255 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLPointPropertiesNodeType.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLPointPropertiesNodeType.java
@@ -1,50 +1,50 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.nodes;
-
-// External imports
-// None
-
-// Local imports
-import org.web3d.vrml.lang.InvalidFieldValueException;
-
-/**
- * Node specifies point properties for point set.
- */
-public interface VRMLPointPropertiesNodeType extends VRMLAppearanceChildNodeType {
-
-    /** Constant used to set the fog type to disabled. */
-    int DISABLE_COLOR_MODE = 0;
-
-    /** Constant used to set the color mode to texture mode. */
-    int TEXTURE_COLOR_MODE = 1;
-
-    /** Constant used to set the color mode to point mode. */
-    int POINT_COLOR_MODE = 2;
-
-    /** Constant used to set the color mode to point and texture mode. */
-    int TEXTURE_AND_POINT_COLOR_MODE = 3;
-
-    /**
-     * Accessor method to set a new value for field colorMode.
-     * @param newColorMode The new value of colorMode
-     */
-    void setColorMode (String newColorMode)
-        throws InvalidFieldValueException;
-
-    /**
-     * Accessor method to get current value of field colorMode.
-     * @return The current value of colorMode
-     */
-    int getColorMode();
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.nodes;
+
+// External imports
+// None
+
+// Local imports
+import org.web3d.vrml.lang.InvalidFieldValueException;
+
+/**
+ * Node specifies point properties for point set.
+ */
+public interface VRMLPointPropertiesNodeType extends VRMLAppearanceChildNodeType {
+
+    /** Constant used to set the fog type to disabled. */
+    int DISABLE_COLOR_MODE = 0;
+
+    /** Constant used to set the color mode to texture mode. */
+    int TEXTURE_COLOR_MODE = 1;
+
+    /** Constant used to set the color mode to point mode. */
+    int POINT_COLOR_MODE = 2;
+
+    /** Constant used to set the color mode to point and texture mode. */
+    int TEXTURE_AND_POINT_COLOR_MODE = 3;
+
+    /**
+     * Accessor method to set a new value for field colorMode.
+     * @param newColorMode The new value of colorMode
+     */
+    void setColorMode (String newColorMode)
+        throws InvalidFieldValueException;
+
+    /**
+     * Accessor method to get current value of field colorMode.
+     * @return The current value of colorMode
+     */
+    int getColorMode();
+}
diff --git a/src/java/org/web3d/vrml/nodes/VRMLPointingDeviceSensorNodeType.java b/src/java/org/web3d/vrml/nodes/VRMLPointingDeviceSensorNodeType.java
index 5444a986f26de494eb20e4f08417e0e7f489f3f8..08fd4882b307b5d6dcae668b2bec7630069bdc3e 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLPointingDeviceSensorNodeType.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLPointingDeviceSensorNodeType.java
@@ -20,7 +20,7 @@ package org.web3d.vrml.nodes;
 
 /**
  * A sensor driven by a pointing device.
- * 
+ * <p>
  * @author Alan Hudson
  * @version $Revision: 1.11 $
  */
diff --git a/src/java/org/web3d/vrml/nodes/VRMLProductStructureChildNodeType.java b/src/java/org/web3d/vrml/nodes/VRMLProductStructureChildNodeType.java
index 4aecc542c04478b6d01c5fcaeac92f6f97fdbda3..3f35eec4e267a363d31eb6556621889d5c6e4c86 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLProductStructureChildNodeType.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLProductStructureChildNodeType.java
@@ -13,6 +13,7 @@ package org.web3d.vrml.nodes;
 
 /**
  * Nodes which can appear in an appearance field of an Appearance Node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/nodes/VRMLSurfaceLayoutNodeType.java b/src/java/org/web3d/vrml/nodes/VRMLSurfaceLayoutNodeType.java
index c3468c4d534b6235fd5ba42033b655d05a54cdf8..58a33fda3875075aa1cc426222bd273005c4f755 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLSurfaceLayoutNodeType.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLSurfaceLayoutNodeType.java
@@ -18,21 +18,20 @@ package org.web3d.vrml.nodes;
 import org.web3d.vrml.lang.InvalidFieldValueException;
 
 /**
- * <p>
  * A grouping node that collects together and provides layout information for
  * items on a surface.
- * </p>
  * <p>
+ *
  * When the instance is given nodes to manage, it should manage it until told
  * not to. Any time that the window size changes, the relationship should
  * recalculate the on-screen position and notify the overlay items of their
  * new pixel coordinates.
- * </p>
  * <p>
+ *
  * It is legal for a layout node to also contain other layout nodes in a
  * nested fashion. An implementation should be aware of this and make sure
  * it handles nested layouts correctly.
- * </p>
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/nodes/VRMLSurfaceMaterialNodeType.java b/src/java/org/web3d/vrml/nodes/VRMLSurfaceMaterialNodeType.java
index b61694b4d98b182f6d25be5d213c4fd7e00d3115..6bf910bb4fe1a38b5a4cb7429b11a52a3b682b7b 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLSurfaceMaterialNodeType.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLSurfaceMaterialNodeType.java
@@ -14,7 +14,7 @@ package org.web3d.vrml.nodes;
 /**
  * Node specifies surface material properties for associated geometry
  * These can be for any sense, Visual, Aural, Haptic...
- * 
+ * <p>
  * @author Alan Hudson
  * @version $Revision: 1.2 $
  */
diff --git a/src/java/org/web3d/vrml/nodes/VRMLTerrainSource.java b/src/java/org/web3d/vrml/nodes/VRMLTerrainSource.java
index 23d54d28d8ecc5c92e3ee9d50966cafd512045ba..6376b641e1c952da4343bfb7f4cb2cb1933faf83 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLTerrainSource.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLTerrainSource.java
@@ -20,6 +20,7 @@ package org.web3d.vrml.nodes;
 
 /**
  * Representation of a node that supplies terrain data.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/nodes/VRMLTextureNodeType.java b/src/java/org/web3d/vrml/nodes/VRMLTextureNodeType.java
index 9f432b9a29b1e7a3a6b1c7e8fa3443932266b105..874787945a46692709c6ed7435bc3f7e41c1b8ed 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLTextureNodeType.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLTextureNodeType.java
@@ -13,6 +13,7 @@ package org.web3d.vrml.nodes;
 
 /**
  * Base interface for all texture types for associated geometry.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/nodes/VRMLTextureProperties2DNodeType.java b/src/java/org/web3d/vrml/nodes/VRMLTextureProperties2DNodeType.java
index ac0a45b9c7dadd4d12ab0c615efee7ec7d788666..abfd7ee76b1155c717937cda1f19d95563978fff 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLTextureProperties2DNodeType.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLTextureProperties2DNodeType.java
@@ -17,6 +17,7 @@ package org.web3d.vrml.nodes;
 
 /**
  * VRML representation of 2D texture properties.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/nodes/VRMLTimeListener.java b/src/java/org/web3d/vrml/nodes/VRMLTimeListener.java
index cdeec7559e966288ea2994bf66438c1e51aa28df..0579946a707781a07f5c554a66b63cf5c4c2330c 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLTimeListener.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLTimeListener.java
@@ -14,6 +14,7 @@ package org.web3d.vrml.nodes;
 /**
  * Interface for System clock ticks so that we can drive things like
  * routes, TimeSensors etc.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/nodes/VRMLUrlListener.java b/src/java/org/web3d/vrml/nodes/VRMLUrlListener.java
index 0a59fc4567e8378934893d4230bf3a6b67f3403c..523ad9e0b80ca4bd1dffa309ebd246df28d8e355 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLUrlListener.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLUrlListener.java
@@ -19,6 +19,7 @@ package org.web3d.vrml.nodes;
 
 /**
  * An listener for changes in a nodes URL content.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/nodes/VRMLViewDependentNodeType.java b/src/java/org/web3d/vrml/nodes/VRMLViewDependentNodeType.java
index 37b99b40efcae162f1d1843aca7f8f9bb0df005f..88d6ed59b67f28753cd740a43d3e3c6e9b140089 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLViewDependentNodeType.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLViewDependentNodeType.java
@@ -20,6 +20,7 @@ package org.web3d.vrml.nodes;
 /**
  * Marker interface that defines a node that has its rendered state generated
  * relative to the viewpoint, possibly every frame.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/nodes/VRMLVisualMaterialNodeType.java b/src/java/org/web3d/vrml/nodes/VRMLVisualMaterialNodeType.java
index e05ef5dc080c1206a738a4a07f57f3ea52664554..e96f8d9ec012389cb0f035913ad4a4d622243704 100644
--- a/src/java/org/web3d/vrml/nodes/VRMLVisualMaterialNodeType.java
+++ b/src/java/org/web3d/vrml/nodes/VRMLVisualMaterialNodeType.java
@@ -13,7 +13,8 @@ package org.web3d.vrml.nodes;
 
 /**
  * Node specifies visual surface material properties for associated geometry.
- * 
+ * <p>
+ *
  * @author Alan Hudson
  * @version $Revision: 1.3 $
  */
diff --git a/src/java/org/web3d/vrml/nodes/ViewpointListener.java b/src/java/org/web3d/vrml/nodes/ViewpointListener.java
index d1333e1c065e637c80406aed3d8f8f1b7c039f38..4552ecff827e21af1ecc8cd7e5bb6e81241b1133 100644
--- a/src/java/org/web3d/vrml/nodes/ViewpointListener.java
+++ b/src/java/org/web3d/vrml/nodes/ViewpointListener.java
@@ -1,41 +1,42 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.nodes;
-
-// Standard imports
-
-// Application specific imports
-
-/**
- * Notification that a viewpoints parameters have changed.  This currently
- * notifies on changes of centerOfRotation and fieldOfView.
- *
- * @author Alan Hudson
- * @version $Revision: 1.1 $
- */
-public interface ViewpointListener {
-
-    /**
-     * The center of rotation has changed.
-     *
-     * @param val The new value
-     */
-    void centerOfRotationChanged(float[] val);
-
-    /**
-     * The field of view has changed.
-     *
-     * @param val The new value
-     */
-    void fieldOfViewChanged(float[] val);
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.nodes;
+
+// Standard imports
+
+// Application specific imports
+
+/**
+ * Notification that a viewpoints parameters have changed.  This currently
+ * notifies on changes of centerOfRotation and fieldOfView.
+ * <p>
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.1 $
+ */
+public interface ViewpointListener {
+
+    /**
+     * The center of rotation has changed.
+     *
+     * @param val The new value
+     */
+    void centerOfRotationChanged(float[] val);
+
+    /**
+     * The field of view has changed.
+     *
+     * @param val The new value
+     */
+    void fieldOfViewChanged(float[] val);
+}
diff --git a/src/java/org/web3d/vrml/nodes/proto/ProtoROUTE.java b/src/java/org/web3d/vrml/nodes/proto/ProtoROUTE.java
index 248e77f46e3d7e29ebe8325ab66c67b1bd9b9a59..4f8366b942a94d7c4e31df78b5923c7de7e2d628 100644
--- a/src/java/org/web3d/vrml/nodes/proto/ProtoROUTE.java
+++ b/src/java/org/web3d/vrml/nodes/proto/ProtoROUTE.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.nodes.VRMLNodeType;
 
 /**
  * Internal Proto handler representation of a ROUTE.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/parser/VRMLParserFactory.java b/src/java/org/web3d/vrml/parser/VRMLParserFactory.java
index 7926e78d6c36ef9a1de1e66211f6f0974fc76960..2d2aeecbf7ff5eacaf45b93f80e8e0d18643f9ef 100644
--- a/src/java/org/web3d/vrml/parser/VRMLParserFactory.java
+++ b/src/java/org/web3d/vrml/parser/VRMLParserFactory.java
@@ -25,11 +25,9 @@ import org.web3d.vrml.sav.VRMLReader;
 import org.web3d.vrml.sav.SAVNotSupportedException;
 
 /**
- * <p>
  * Representation of a parser factory for VRML content.
- * </p>
- *
  * <p>
+ *
  * This is the representation of a basic VRML parser. An parser implementation
  * would extend this instance to provide a specific parser. The implementation
  * class is specified by defining a system property
@@ -46,20 +44,16 @@ import org.web3d.vrml.sav.SAVNotSupportedException;
  * re-read the property and create an instance of the class. This allows you
  * to create different parser instances for each call within the one JVM
  * instance. If no property is defined then the default implementation is used.
- * </p>
  * <p>
  * All factories are required to support the feature name "VRML-utf8". The
  * version is the VRML specification version supported in the UTF8 encoding
  * (it is also possible the binary version may use this, but definitely not
  * XML encoding).
- * </p>
  * <p>
  *
  * The following a standard properties that may be required of all factories
  * and readers
- * </p>
- * <table>
- * <caption>standard properties that may be required of all factories and readers</caption>
+ * <table summary="standard properties that may be required of all factories and readers">
  * <tr><th>Name</th><th>Values</th><th>Default</th><th>Description</th></tr>
  * <tr><td>Required-Version</td>
  *     <td>"2.0", "3.0"</td>
diff --git a/src/java/org/web3d/vrml/renderer/CRExternProtoBuilder.java b/src/java/org/web3d/vrml/renderer/CRExternProtoBuilder.java
index 2d9027f2e9396a3bef4587034cc4fddcf7c737f0..e6465728cb129786177afe5cd66fec669087aa24 100644
--- a/src/java/org/web3d/vrml/renderer/CRExternProtoBuilder.java
+++ b/src/java/org/web3d/vrml/renderer/CRExternProtoBuilder.java
@@ -31,9 +31,11 @@ import org.web3d.vrml.nodes.proto.PrototypeDecl;
 
 /**
  * A SAV interface for dealing with building a single extern proto.
+ * <p>
  *
  * The builder is designed to create a single proto. However, that single proto
  * may well have nested protos as part of it, so we must deal with that too.
+ * <p>
  *
  * @author Alan Hudson, Justin Couch
  * @version $Revision: 1.14 $
diff --git a/src/java/org/web3d/vrml/renderer/CRROUTE.java b/src/java/org/web3d/vrml/renderer/CRROUTE.java
index d7d996dbc951a117eaaf6311e82a7c4ff35fb35f..b81175c2908f8674fe0559fb30edd9e919f64043 100644
--- a/src/java/org/web3d/vrml/renderer/CRROUTE.java
+++ b/src/java/org/web3d/vrml/renderer/CRROUTE.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.nodes.VRMLNodeType;
 
 /**
  * A common ROUTE implementation for all renderers.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.4 $
diff --git a/src/java/org/web3d/vrml/renderer/DefaultNodeFactory.java b/src/java/org/web3d/vrml/renderer/DefaultNodeFactory.java
index 9da14a9797f3fba63924d9019bece010b1dbf003..9f01e8a5ebc28b7e3815c7e3ada7c4018e3752a5 100644
--- a/src/java/org/web3d/vrml/renderer/DefaultNodeFactory.java
+++ b/src/java/org/web3d/vrml/renderer/DefaultNodeFactory.java
@@ -19,18 +19,23 @@ import java.lang.reflect.InvocationTargetException;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.*;
+
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.FactoryConfigurationError;
 import javax.xml.parsers.ParserConfigurationException;
+
 import org.j3d.util.DefaultErrorReporter;
 import org.j3d.util.ErrorReporter;
 import org.j3d.util.HashSet;
+
 import org.w3c.dom.*;
+import org.xml.sax.SAXException;
+
+// Local imports
 import org.web3d.vrml.lang.*;
 import org.web3d.vrml.nodes.VRMLNodeType;
 import org.web3d.vrml.nodes.VRMLProtoInstance;
-import org.xml.sax.SAXException;
 
 /**
  * Implementation of the {@link org.web3d.vrml.lang.VRMLNodeFactory}
@@ -120,11 +125,11 @@ public class DefaultNodeFactory
 
     /** Message string when there is no component information defined */
     private static final String NO_COMP_DEF_MSG =
-        "There is no definition information for component ";
+        "There is no definition information for the component ";
 
     /** Message when string the component definition file not found */
     private static final String NO_COMP_FILE_MSG =
-        "Could not find  definition file for component ";
+        "Could not find the definition file for the component ";
 
     /** Message when string the profile definition file not found */
     private static final String NO_PROF_FILE_MSG =
@@ -1385,9 +1390,7 @@ public class DefaultNodeFactory
         throws UnsupportedProfileException {
 
         if(invalidProfiles.contains(name))
-        {
-            throw new UnsupportedProfileException("X3D-Edit support not found for node " + name + "\n" + NO_PROF_FILE_MSG + name);
-        }
+            throw new UnsupportedProfileException(NO_PROF_FILE_MSG + name);
 
         ProfileInfo ret_val = null;
 
@@ -1396,7 +1399,7 @@ public class DefaultNodeFactory
 
         if(is == null) {
             invalidProfiles.add(name);
-            throw new UnsupportedProfileException("X3D-Edit support not found for node " + name + "\n" + NO_PROF_FILE_MSG + name);
+            throw new UnsupportedProfileException(NO_PROF_FILE_MSG + name);
         }
 
         Document doc_root = null;
diff --git a/src/java/org/web3d/vrml/renderer/common/browser/OverlayWrapper.java b/src/java/org/web3d/vrml/renderer/common/browser/OverlayWrapper.java
index f4a4ff35a702887b65497bcc6f40420c97892ecd..a965497fb8be0bc77fb6e626c2fc8bd384e1f8f2 100644
--- a/src/java/org/web3d/vrml/renderer/common/browser/OverlayWrapper.java
+++ b/src/java/org/web3d/vrml/renderer/common/browser/OverlayWrapper.java
@@ -25,6 +25,7 @@ import org.web3d.vrml.nodes.VRMLSurfaceNodeType;
 /**
  * Simple utility class that interfaces between the drawing component and the
  * overlay node types to pass resize information.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/common/input/dis/DISConnectionHandler.java b/src/java/org/web3d/vrml/renderer/common/input/dis/DISConnectionHandler.java
index a7d805ffab0b9de351f02ce47e47a5c4daf04e80..3e98c04072afe265dbe84ad5dc98bf5da2b4b817 100644
--- a/src/java/org/web3d/vrml/renderer/common/input/dis/DISConnectionHandler.java
+++ b/src/java/org/web3d/vrml/renderer/common/input/dis/DISConnectionHandler.java
@@ -64,35 +64,35 @@ public class DISConnectionHandler implements PduListener {
 
     Thread readThread;
 
-    private final int port;
+    private int port;
 
-    private final String group;
+    private String group;
 
     int cnt;
 
-    private final LinkedList liveList;
+    private LinkedList liveList;
 
     // Scratch id to avoid gc
-    private final DISId disId;
+    private DISId disId;
 
     // Scratch translation field
-    private final float[] translation;
+    private float[] translation;
 
     // Scratch rotation field
-    private final float[] rotation;
+    private float[] rotation;
 
-    private final float[] dRorientation;
+    private float[] dRorientation;
 
     private Quat4f quaternion = null;
 
     /** The node to ID mapping */
-    private final Map<DISId, NodeMapEntry> nodeMap;
+    private Map<DISId, NodeMapEntry> nodeMap;
 
     /** The list of managers */
-    private final List<VRMLDISNodeType> managerList;
+    private List<VRMLDISNodeType> managerList;
 
     /** The Entities we've placed on the addedEntities */
-    private final Set<DISId> notifiedSet;
+    private Set<DISId> notifiedSet;
 
     /**
      * @param nodeMap
@@ -117,7 +117,6 @@ public class DISConnectionHandler implements PduListener {
         quaternion = new Quat4f();
 
         writer = new DisThreadedNetworkInterface(this.group, this.port);
-        writer.setVerbose(false);
         writer.addListener(DISConnectionHandler.this);
     }
 
diff --git a/src/java/org/web3d/vrml/renderer/common/input/dis/DISConnectionId.java b/src/java/org/web3d/vrml/renderer/common/input/dis/DISConnectionId.java
index c545ff8d47bde0abfe1024b13b092b7d04e7c129..efab44db04d8d4224cfd3ea9798a8797a6b37e3d 100644
--- a/src/java/org/web3d/vrml/renderer/common/input/dis/DISConnectionId.java
+++ b/src/java/org/web3d/vrml/renderer/common/input/dis/DISConnectionId.java
@@ -19,6 +19,7 @@ package org.web3d.vrml.renderer.common.input.dis;
  * DIS connections, address and port
  *
  * Implements hashcode and equals.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.4 $
diff --git a/src/java/org/web3d/vrml/renderer/common/input/dis/DISId.java b/src/java/org/web3d/vrml/renderer/common/input/dis/DISId.java
index 91acf3472483302420ef8b9ad60059a5c9b3e8c4..d7946a8ca8d02b363c8acd9cd7dbf8627748f2db 100644
--- a/src/java/org/web3d/vrml/renderer/common/input/dis/DISId.java
+++ b/src/java/org/web3d/vrml/renderer/common/input/dis/DISId.java
@@ -19,6 +19,7 @@ package org.web3d.vrml.renderer.common.input.dis;
  * DIS packets, SiteID, ApplicationID, and EntityID.
  *
  * Implements hashcode and equals.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/renderer/common/input/dis/DISProtocolHandler.java b/src/java/org/web3d/vrml/renderer/common/input/dis/DISProtocolHandler.java
index f450cbb827ee1db8be7e51e20ea190e892b3fb92..53dd5de191e5b15d7c5a14de305594771712088c 100644
--- a/src/java/org/web3d/vrml/renderer/common/input/dis/DISProtocolHandler.java
+++ b/src/java/org/web3d/vrml/renderer/common/input/dis/DISProtocolHandler.java
@@ -56,10 +56,7 @@ public class DISProtocolHandler
 
     /** The amount of time between heartbeats.   */
     private static final int HEARTBEAT_CHECK_TIME = 4500;
-    
-    /** Dead Reckoning tolerance */
-    private static final float DR_TOLERANCE = 0.0001f;
-    
+
     /**
      * The default order.
      */
@@ -74,41 +71,54 @@ public class DISProtocolHandler
     private ErrorReporter errorReporter;
 
     /** A map of open connections.  Only open one per address/port */
-    private final Map<DISConnectionId, DISConnectionHandler> connections;
+    private Map<DISConnectionId, DISConnectionHandler> connections;
 
     /** A map of DIS nodes wrappers and their unique ID's  */
-    private final Map<DISId, NodeMapEntry> nodeMap;
+    private Map<DISId, NodeMapEntry> nodeMap;
 
     /** A map of DIS nodes wrappers and their unique ID's  */
-    private final Map<DISId, WriterMapEntry> writerMap;
+    private Map<DISId, WriterMapEntry> writerMap;
 
     /** Live list variables */
-    private final LinkedList liveList;
+    private LinkedList liveList;
 
     /** Nodes which want to write to the network */
-    private final LinkedList writerList;
+    private LinkedList writerList;
 
     /** The last time we checked for inactive pdus */
     private long lastCheck;
 
+    /** The last time we checked for heartbeats */
+    private long lastHeartCheck;
+
     /** The list of managers */
-    private final List<VRMLDISNodeType> managerList;
+    private List<VRMLDISNodeType> managerList;
 
     /** The Entities we've placed on the addedEntities */
-    private final Set<DISId> notifiedSet;
+    private Set<DISId> notifiedSet;
 
     // Scratch vars to avoid gc.  Do not store DISId as a Map id, clone it
-    private final DISId disId;
+    private DISId disId;
 
     float[] tempPositionArray;
 
-    private final float[] rotation;
+    float[] tempPositionArray2;
+
+    float[] goalOrientation;
 
+    private Quat4f quaternion = null;
+
+    private float[] rotation;
+
+    private float[] currOrientation;
+
+    private float[] positionArray;
+    
     /** For ESPDU timestamps */
-    private final DisTime disTime;
+    private DisTime disTime;
 
     /** Whether we should smooth the DIS traffic */
-//    private boolean smooth = true;
+    private boolean smooth = true;
 
     /** The default dead reckon position value */
     protected static final boolean DEFAULT_DEADRECKON_POSITION = true;
@@ -133,15 +143,12 @@ public class DISProtocolHandler
     // Scratch matrixes for smoothing
     Matrix3d rotationMatrix;
 
-    /** yaw (heading) */
-    Matrix3d phiMat;
-    
-    /** pitch */
-    Matrix3d thetaMat;
-    
-    /** roll */
     Matrix3d psiMat;
 
+    Matrix3d thetaMat;
+
+    Matrix3d phiMat;
+
     Quat4d rotationQuat;
 
     Vector3d translationVec;
@@ -167,7 +174,7 @@ public class DISProtocolHandler
      * routing.
      */
     public DISProtocolHandler() {
-        DISProtocolHandler.this.setErrorReporter(DefaultErrorReporter.getDefaultReporter());
+        errorReporter = DefaultErrorReporter.getDefaultReporter();
 
         connections = new HashMap<>();
         nodeMap = Collections.synchronizedMap(new HashMap<>());
@@ -179,8 +186,13 @@ public class DISProtocolHandler
         notifiedSet = Collections.synchronizedSet(new java.util.HashSet<>());
         disId = new DISId(0, 0, 0);
         tempPositionArray = new float[3];
+        tempPositionArray2 = new float[3];
+        goalOrientation = new float[3];
 
         rotation = new float[4];
+        quaternion  = new Quat4f();
+        positionArray = new float[3];
+        currOrientation = new float[3];
 
         rotationMatrix = new Matrix3d();
         psiMat = new Matrix3d();
@@ -256,32 +268,38 @@ public class DISProtocolHandler
 
 //System.out.println("***Real Pos: " + espdu.getEntityLocationX() + " " + espdu.getEntityLocationY() + " " + espdu.getEntityLocationZ());
 
-                    // DIS conversions performed in eulersToMatrix()
+                    rotationMatrix.setIdentity();
+                    
                     orient = espdu.getEntityOrientation();
-                    eulersToMatrix(orient.getPhi(), // yaw (heading)
-                            orient.getTheta(),      // pitch
-                            orient.getPsi());       // roll
+
+                    eulersToMatrix(orient.getPhi(),
+                            orient.getTheta(),
+                            orient.getPsi());
 
                     rotationQuat.set(rotationMatrix);
 
-                    // Convert to DIS coordinates
+                    // Convert to normal coordinates
                     location = espdu.getEntityLocation();
+                    
                     translation = new Vector3d(location.getX(),
                             -location.getZ(),
                             location.getY());
 
                     linearVelocity = espdu.getEntityLinearVelocity();
+
                     translationDerivatives[0].set(linearVelocity.getX(),
                             -linearVelocity.getZ(),
                             linearVelocity.getY());
 
                     drp = espdu.getDeadReckoningParameters();
                     angularVelocity = drp.getEntityAngularVelocity();
-                    rotationDerivatives[0].set(angularVelocity.getX(), // yaw (heading)
-                            -angularVelocity.getZ(),                   // pitch
-                            angularVelocity.getY());                   // roll
+
+                    rotationDerivatives[0].set(angularVelocity.getX(),
+                            -angularVelocity.getZ(),
+                            angularVelocity.getY());
 
                     linearAcceleration = drp.getEntityLinearAcceleration();
+
                     translationDerivatives[1].set(linearAcceleration.getX(),
                             -linearAcceleration.getZ(),
                             linearAcceleration.getY());
@@ -341,26 +359,20 @@ public class DISProtocolHandler
                 dt = (currTime - node.lastTime) * 0.001f;
 //                dt = (currTime - node.lastTime) * 0.01f;
 
-                if (node.currEspdu != null) {
-                    espdu = node.currEspdu;
-                    linearVelocity = espdu.getEntityLinearVelocity();
-                    drp = espdu.getDeadReckoningParameters();
-                    linearAcceleration = drp.getEntityLinearAcceleration();
-                
-                    if (Math.abs(linearVelocity.getX()) <= DR_TOLERANCE
-                            && Math.abs(linearVelocity.getY()) <= DR_TOLERANCE
-                            && Math.abs(linearVelocity.getZ()) <= DR_TOLERANCE
-                            && Math.abs(linearAcceleration.getX()) <= DR_TOLERANCE
-                            && Math.abs(linearAcceleration.getY()) <= DR_TOLERANCE
-                            && Math.abs(linearAcceleration.getZ()) <= DR_TOLERANCE) {
-
-                        node.closeEnough = true;
-                    }
+
+                if (Math.abs(node.currEspdu.getEntityLinearVelocity().getX()) <= 0.0001 &&
+                        Math.abs(node.currEspdu.getEntityLinearVelocity().getY()) <= 0.0001 &&
+                        Math.abs(node.currEspdu.getEntityLinearVelocity().getZ()) <= 0.0001 &&
+                        Math.abs(node.currEspdu.getDeadReckoningParameters().getEntityLinearAcceleration().getX()) <= 0.0001 &&
+                        Math.abs(node.currEspdu.getDeadReckoningParameters().getEntityLinearAcceleration().getY()) <= 0.0001 &&
+                        Math.abs(node.currEspdu.getDeadReckoningParameters().getEntityLinearAcceleration().getZ()) <= 0.0001) {
+
+                    node.closeEnough = true;
                 }
 
                 int idx;
 
-                if (node.translationConverger != null && DEAD_RECKON_POSITION) {
+                if (DEAD_RECKON_POSITION) {
                     node.translationConverger.getValue(currTime, translationVec);
                     tempPositionArray[0] = (float) translationVec.x;
                     tempPositionArray[1] = (float) translationVec.y;
@@ -369,7 +381,7 @@ public class DISProtocolHandler
                     di.setValue(idx, tempPositionArray, 3);
                 }
 
-                if (node.rotationConverger != null && DEAD_RECKON_ROTATION) {
+                if (DEAD_RECKON_ROTATION) {
                     node.rotationConverger.getValue(currTime, rotationQuat);
                     rotationQuat.normalize();
 
@@ -418,7 +430,6 @@ public class DISProtocolHandler
         while (writer != null) {
             di = writer.node;
 
-            // TODO: decisions can be consolidated for now until DR errors are checked
             if (di.valuesToWrite()) {
                 writer.lastTime = currTime;
                 pdu = di.getState();
@@ -638,25 +649,20 @@ public class DISProtocolHandler
     // See ProtocolHandlerUtils
     
     /**
-     * Sets Euler angles (phi, theta, psi) into a rotation matrix. Converts to 
-     * DIS values for the orientation vector.
+     * Converts a set of Euler angles (phi, theta, psi) to a rotation matrix.
      *
-     * @param phi   (yaw | heading) in radians
-     * @param theta (pitch) in radians
-     * @param psi   (roll) in radians
+     * @param x phi
+     * @param y theta
+     * @param z psi
      */
-    private void eulersToMatrix(double phi, double theta, double psi) {
+    private void eulersToMatrix(double x, double y, double z) {
+        psiMat.setIdentity();
+        psiMat.rotY(-z);
 
-        phiMat.setIdentity();
-        phiMat.rotY(-phi);
+        thetaMat.rotZ(y);
 
-        thetaMat.setIdentity();
-        thetaMat.rotX(psi);
-        
-        psiMat.setIdentity();
-        psiMat.rotZ(theta);
+        phiMat.rotX(x);
 
-        rotationMatrix.setIdentity();
         rotationMatrix.mul(phiMat, thetaMat);
         rotationMatrix.mul(psiMat);
     }
diff --git a/src/java/org/web3d/vrml/renderer/common/input/dis/DISXMLProtocolHandler.java b/src/java/org/web3d/vrml/renderer/common/input/dis/DISXMLProtocolHandler.java
index 73b45a36cc0f43396fd301540153abfb3a28c2b5..15cc187260e429dfb959808357347539e1ef2c5f 100644
--- a/src/java/org/web3d/vrml/renderer/common/input/dis/DISXMLProtocolHandler.java
+++ b/src/java/org/web3d/vrml/renderer/common/input/dis/DISXMLProtocolHandler.java
@@ -43,6 +43,7 @@ import org.xj3d.core.eventmodel.NetworkProtocolHandler;
  * TODO: Consolidate DISProtocolHandler and this PH
  *
  * The handler for DISXML protocol network traffic.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.10 $
diff --git a/src/java/org/web3d/vrml/renderer/common/input/dis/OrderNVector3dConverger.java b/src/java/org/web3d/vrml/renderer/common/input/dis/OrderNVector3dConverger.java
index 4913e3d4154140e84422b4e173f04d4db4dd5cc9..164b3e1626c63c16783a6d198cdc5572108bebf8 100644
--- a/src/java/org/web3d/vrml/renderer/common/input/dis/OrderNVector3dConverger.java
+++ b/src/java/org/web3d/vrml/renderer/common/input/dis/OrderNVector3dConverger.java
@@ -176,7 +176,7 @@ public class OrderNVector3dConverger
     /**
      * Are the values still converging?
      *
-     * @return Are we still converging.
+     * @return Are we still convering.
      */
     public boolean isConverging()
     {
diff --git a/src/java/org/web3d/vrml/renderer/common/input/dis/ProtocolHandlerUtils.java b/src/java/org/web3d/vrml/renderer/common/input/dis/ProtocolHandlerUtils.java
index 2ac7e4594c42183cc0bd4100bea01f1dc7a27ce8..d224a69cac1197673914fb1dbca8598dc2c386c4 100644
--- a/src/java/org/web3d/vrml/renderer/common/input/dis/ProtocolHandlerUtils.java
+++ b/src/java/org/web3d/vrml/renderer/common/input/dis/ProtocolHandlerUtils.java
@@ -30,15 +30,15 @@ public class ProtocolHandlerUtils {
 
         dRPosition[0] = (float) (location.getX() +
                 dt * linearVelocity.getX() +
-                0.5 * dtSq * linearAcceleration.getX());
+                dtSq * linearAcceleration.getX());
 
         dRPosition[1] = (float) (-location.getZ() -
                 dt * linearVelocity.getZ() -
-                0.5 * dtSq * linearAcceleration.getZ());
+                dtSq * linearAcceleration.getZ());
 
         dRPosition[2] = (float) (location.getY() +
                 dt * linearVelocity.getY() +
-                0.5 * dtSq * linearAcceleration.getY());
+                dtSq * linearAcceleration.getY());
 //System.out.println("DRPOS:");
 //System.out.println("   Current Pos: " + espdu.getEntityLocationX() + " " + espdu.getEntityLocationY() + " " + espdu.getEntityLocationZ());
 //System.out.println("   Velocity: " + espdu.getEntityLinearVelocityX() + " " + espdu.getEntityLinearVelocityY() + " " + espdu.getEntityLinearVelocityZ());
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/AreaListener.java b/src/java/org/web3d/vrml/renderer/common/nodes/AreaListener.java
index ae0027ac5b513cc468cbec2d657aa46e27726d80..a2c844dd970f2f78bd0470624f8f30e31ba36662 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/AreaListener.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/AreaListener.java
@@ -23,6 +23,7 @@ package org.web3d.vrml.renderer.common.nodes;
 /**
  * A marker interface for a node that wants to know about the viewpoint entry or
  * exit from an area.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/BaseBindableNode.java b/src/java/org/web3d/vrml/renderer/common/nodes/BaseBindableNode.java
index 3ce92063f5cb9486fa3c2e990edd6af7b03492b0..629c3587f985953fb73809cc4a3007fb18702fb2 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/BaseBindableNode.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/BaseBindableNode.java
@@ -18,16 +18,19 @@ import java.util.List;
 
 // Local imports
 import org.web3d.vrml.nodes.*;
+
 import org.web3d.vrml.lang.InvalidFieldException;
 import org.web3d.vrml.lang.InvalidFieldValueException;
 import org.web3d.vrml.lang.TypeConstants;
 
 /**
  * An abstract implementation of any bindable node.
+ * <p>
  *
  * The implementation treats the time and bound states independently. It is
  * assumed that the browser environment displaying the world will take care
  * of the stack and bind time information setting.
+ * <p>
  *
  * @author Alan Hudson, Justin Couch
  * @version $Revision: 1.13 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/BaseComponentGeometryNode.java b/src/java/org/web3d/vrml/renderer/common/nodes/BaseComponentGeometryNode.java
index fef0d04d9922896243d025a1296c1e8abbcf6320..3b533cdd2dd18c4c820b14143df2f09c9181398d 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/BaseComponentGeometryNode.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/BaseComponentGeometryNode.java
@@ -26,6 +26,8 @@ import org.web3d.vrml.lang.InvalidFieldValueException;
 /**
  * An abstract implementation of any node that uses component nodes to provide
  * coordinate, normal and texture information.
+ * <p>
+ *
  *
  * @author Justin Couch
  * @version $Revision: 1.20 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/BaseDragSensorNode.java b/src/java/org/web3d/vrml/renderer/common/nodes/BaseDragSensorNode.java
index 179dd0e741265baa212d8bec829d232c3eb86313..ed1157da27663b847571525205dd62a2c3156b8a 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/BaseDragSensorNode.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/BaseDragSensorNode.java
@@ -25,6 +25,7 @@ import org.web3d.vrml.nodes.VRMLDragSensorNodeType;
 /**
  * An abstract representation of any form of sensor for
  * subclassing by specific implementations.
+ * <p>
  *
  * @author Justin Couch, Alan Hudson
  * @version $Revision: 1.11 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/BaseIndexedTriangleGeometryNode.java b/src/java/org/web3d/vrml/renderer/common/nodes/BaseIndexedTriangleGeometryNode.java
index f042921042b0cfe163343cb2739871417070ef5b..1628d63cd0fffa8b1d399d4a5347ed5c50396add 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/BaseIndexedTriangleGeometryNode.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/BaseIndexedTriangleGeometryNode.java
@@ -27,6 +27,7 @@ import org.web3d.vrml.lang.VRMLException;
 
 /**
  * An abstract implementation of the IndexedTriangle* nodes.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.11 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/BaseMetadataObjectNode.java b/src/java/org/web3d/vrml/renderer/common/nodes/BaseMetadataObjectNode.java
index 67644499d553afadb970f58683d42a749df52b4a..b7dc7899f3513da481c656ac5c99b7d13d7a987a 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/BaseMetadataObjectNode.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/BaseMetadataObjectNode.java
@@ -25,6 +25,8 @@ import org.web3d.vrml.lang.InvalidFieldValueException;
 /**
  * An abstract implementation of any node that uses component nodes to provide
  * coordinate, normal and texture information.
+ * <p>
+ *
  *
  * @author =Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/BasePointSetGeometryNode.java b/src/java/org/web3d/vrml/renderer/common/nodes/BasePointSetGeometryNode.java
index 60ed7d2a678158c833cc7560320a78c1b193000d..061aff7ef3195f5939b333919338c40a26712c68 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/BasePointSetGeometryNode.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/BasePointSetGeometryNode.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.lang.InvalidFieldValueException;
 
 /**
  * An abstract implementation of the PointSet nodes.
+ * <p>
  *
  * @author Russell Dodds
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/BaseSensorNode.java b/src/java/org/web3d/vrml/renderer/common/nodes/BaseSensorNode.java
index 2fdf10dde5a03802571fbaa215f515c26e2d57c4..c505369ace594af8517e6c48ecfa1357a513b078 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/BaseSensorNode.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/BaseSensorNode.java
@@ -25,6 +25,7 @@ import org.web3d.vrml.nodes.VRMLSensorNodeType;
 /**
  * An abstract representation of any form of sensor for
  * subclassing by specific implementations.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.8 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/BaseSequencerNode.java b/src/java/org/web3d/vrml/renderer/common/nodes/BaseSequencerNode.java
index c80e128c552b0d50f74ca6b5a8b1e8d56f115b99..1f9c641bd7c54954f1f5ef4d54974e7fd4eae349 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/BaseSequencerNode.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/BaseSequencerNode.java
@@ -27,10 +27,12 @@ import org.web3d.vrml.nodes.VRMLNodeType;
 /**
  * Abstract implementation of a sequencer so that specific instances can
  * derive from it.
+ * <p>
  *
  * Sequencer nodes are designed for discrete animation.
  * Sequencers are driven by an input and produce
  * corresponding impulse output functions.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.8 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/BaseTextureNode.java b/src/java/org/web3d/vrml/renderer/common/nodes/BaseTextureNode.java
index 97e8bad32ced4131bf098a7684212e909639679a..78420dc0a7b4ce76deb8bdcb377064557ae02224 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/BaseTextureNode.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/BaseTextureNode.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.nodes.*;
 
 /**
  * Base implementation of a texture object.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/BaseTriangleGeometryNode.java b/src/java/org/web3d/vrml/renderer/common/nodes/BaseTriangleGeometryNode.java
index d514911b28284adfc5d85df79946edc420815d33..383445fd69c47eb82debddca9a9a995b48ed9518 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/BaseTriangleGeometryNode.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/BaseTriangleGeometryNode.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.lang.InvalidFieldValueException;
 
 /**
  * An abstract implementation of the Triangle* nodes.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/GeometryHolder.java b/src/java/org/web3d/vrml/renderer/common/nodes/GeometryHolder.java
index 35d8a82c99548d8d3a5044b957dc258d8f9cefa7..50f2643c01bb8f48bcce32ec87aaae0cb7429805 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/GeometryHolder.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/GeometryHolder.java
@@ -1,243 +1,243 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.renderer.common.nodes;
-
-// Standard imports
-import java.text.NumberFormat;
-
-// Application specific imports
-// none
-
-/**
- * Data representation of geometry information that is created through the
- * various generator classes in this package.
- * <p>
- *
- * This class is similar to the j3d.org GeometryHolder class.  It includes
- * data like fogCoordinates and vertex attribs and the ability to store
- * multiple data sets.
-
- * This data representation is used to hold information needed to generate
- * geometry from one of the generator classes in this package. In general,
- * data does not get filled in for items that are not requested.
- * <p>
- *
- * The type of data to be produced can be changed with each call. While it is
- * possible to ask for both 2D and 3D texture coordinates, the code will only
- * generate 2D values if asked.
- *
- * @author Justin Couch, Alan Hudson
- * @version $Revision: 1.2 $
- */
-public class GeometryHolder {
-
-    /** Generate the geometry as individual unindexed triangles */
-    public static final int TRIANGLES = 1;
-
-    /** Generate the geometry as individual unindexed quads */
-    public static final int QUADS = 2;
-
-    /** Generate the geometry as a triangle strip array(s) */
-    public static final int TRIANGLE_STRIPS = 3;
-
-    /** Generate the geometry as a triangle fan array(s) */
-    public static final int TRIANGLE_FANS = 4;
-
-    /** Generate the geometry as indexed quads */
-    public static final int INDEXED_QUADS = 5;
-
-    /** Generate the geometry as an indexed triangle array */
-    public static final int INDEXED_TRIANGLES = 6;
-
-    /** Generate the geometry as an indexed triangle strip array */
-    public static final int INDEXED_TRIANGLE_STRIPS = 7;
-
-    /** Generate the geometry as an indexed triangle fan array */
-    public static final int INDEXED_TRIANGLE_FANS = 8;
-
-    /** Generate the geometry as a line array */
-    public static final int LINES = 9;
-
-    /** Generate the geometry as an line strip array */
-    public static final int LINE_STRIPS = 10;
-
-    /** Generate the geometry as an indexed line array */
-    public static final int INDEXED_LINES = 11;
-
-    /** Generate the geometry as an indexed line strip array */
-    public static final int INDEXED_LINE_STRIPS = 12;
-
-
-    /** Request for lighting normal data to be produced */
-    public static final int NORMAL_DATA = 0x02;
-
-    /** Request for 2D Texture coordinate data to be produced */
-    public static final int TEXTURE_2D_DATA = 0x04;
-
-    /** Request for 3D Texture coordinate data to be produced */
-    public static final int TEXTURE_3D_DATA = 0x08;
-
-    /** This is the type of geometry that you want to have made */
-    public int geometryType = 0;
-
-    /**
-     * A generator specific field that describes the type of output
-     * algorithm you would like to use for the geometry. May be ignored.
-     */
-    public int geometrySubType;
-
-    /**
-     * The attributes of the geometry you want created. This is an OR'd
-     * list of the above variables. It is not possible to generate anything
-     * without the raw geometry being computed.
-     */
-    public int geometryComponents;
-
-    /** The number of vertices stored in the coordinates array */
-    public int vertexCount;
-
-    /**
-     * Storage for coordinate information. These are stored in flat
-     * [x1, y1, z1, x2, y2, z2, ...] configuration
-     */
-    public float[] coordinates;
-
-    /**
-     * Storage for lighting normal information. This should be at least the
-     * length of the coordinates array. Data is stored in the same fashion.
-     * If normals are requested, the count is the same as vertexCount.
-     */
-    public float[] normals;
-
-    /** The number of items stored in the indexes array */
-    public int indexesCount;
-
-    /** Storage for coordinate index information if the shape type requires it. */
-    public int[] indexes;
-
-    /** The number of items stored in the strip counts */
-    public int numStrips;
-
-    /** Storage for strip counts if the shape type uses it */
-    public int[] stripCounts;
-
-    /**
-     * Texture coordinate information if requested. May be 2D or 3D depending
-     * on the requested type. If 2D the values are stored [s1, t1, s2, t2...]
-     * For 3D coordinates it is stores as [r1, s1, t1, r2, s2, t2,...]
-     */
-    public float[][] textureCoordinates;
-
-    /** The number of texture sets in the textureCoordinates field */
-    public int numTexSets;
-
-    /** The number of unique texture sets */
-    public int numUniqueTexSets;
-
-    /**
-     * Colour values if using per-vertex coloring. This array will be identical
-     * in length to the coordinate array and index values match etc.
-     */
-    public float[] colors;
-
-    /**
-     * Storage for normal index information if the shape type requires it. Not
-     * used by the geometry generation classes, but may be by 3rd party software.
-     */
-    public int[] normalIndexes;
-
-    /**
-     * Storage for texture coordinate index information if the shape type
-     * requires it. Not used by the geometry generation classes, but may be by
-     * 3rd party software.
-     */
-    public int[] texCoordIndexes;
-
-    /**
-     * Storage for color index information if the shape type requires it. Not
-     * used by the geometry generation classes, but may be by 3rd party software.
-     */
-    public int[] colorIndexes;
-
-    /**
-     * Convenience method to print out all the data associated with
-     * this geometry array. Prints one vertex per line. Ignores
-     * index information.
-     */
-    public void prettyPrint()
-    {
-        NumberFormat format = NumberFormat.getInstance();
-        format.setMaximumFractionDigits(3);
-        format.setMinimumFractionDigits(3);
-
-        boolean has_3d_texture =
-            (geometryComponents & GeometryHolder.TEXTURE_2D_DATA) == 0;
-
-        System.out.println();
-        for(int i = 0; i < vertexCount; i++)
-        {
-            System.out.print(i);
-            System.out.print(" v: ");
-            System.out.print(format.format(coordinates[i * 3]));
-            System.out.print(' ');
-            System.out.print(format.format(coordinates[i * 3 + 1]));
-            System.out.print(' ');
-            System.out.print(format.format(coordinates[i * 3 + 2]));
-
-            if(normals != null)
-            {
-                System.out.print(", n: ");
-                System.out.print(format.format(normals[i * 3]));
-                System.out.print(' ');
-                System.out.print(format.format(normals[i * 3 + 1]));
-                System.out.print(' ');
-                System.out.print(format.format(normals[i * 3 + 2]));
-            }
-
-            if(colors != null)
-            {
-                System.out.print(", c: ");
-                System.out.print(format.format(colors[i * 3]));
-                System.out.print(' ');
-                System.out.print(format.format(colors[i * 3 + 1]));
-                System.out.print(' ');
-                System.out.print(format.format(colors[i * 3 + 2]));
-            }
-
-            for(int j=0; j < numTexSets; j++) {
-                if(textureCoordinates[j] != null)
-                {
-                    if(has_3d_texture)
-                    {
-                        System.out.print(", t: ");
-                        System.out.print(format.format(textureCoordinates[j][i * 3]));
-                        System.out.print(' ');
-                        System.out.print(format.format(textureCoordinates[j][i * 3 + 1]));
-                        System.out.print(' ');
-                        System.out.print(format.format(textureCoordinates[j][i * 3 + 2]));
-                    }
-                    else
-                    {
-                        System.out.print(", t: ");
-                        System.out.print(format.format(textureCoordinates[j][i * 2]));
-                        System.out.print(' ');
-                        System.out.print(format.format(textureCoordinates[j][i * 2 + 1]));
-                    }
-
-                }
-            }
-
-            System.out.println();
-        }
-    }
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.renderer.common.nodes;
+
+// Standard imports
+import java.text.NumberFormat;
+
+// Application specific imports
+// none
+
+/**
+ * Data representation of geometry information that is created through the
+ * various generator classes in this package.
+ * <p>
+ *
+ * This class is similar to the j3d.org GeometryHolder class.  It includes
+ * data like fogCoordinates and vertex attribs and the ability to store
+ * multiple data sets.
+
+ * This data representation is used to hold information needed to generate
+ * geometry from one of the generator classes in this package. In general,
+ * data does not get filled in for items that are not requested.
+ * <p>
+ *
+ * The type of data to be produced can be changed with each call. While it is
+ * possible to ask for both 2D and 3D texture coordinates, the code will only
+ * generate 2D values if asked.
+ *
+ * @author Justin Couch, Alan Hudson
+ * @version $Revision: 1.2 $
+ */
+public class GeometryHolder {
+
+    /** Generate the geometry as individual unindexed triangles */
+    public static final int TRIANGLES = 1;
+
+    /** Generate the geometry as individual unindexed quads */
+    public static final int QUADS = 2;
+
+    /** Generate the geometry as a triangle strip array(s) */
+    public static final int TRIANGLE_STRIPS = 3;
+
+    /** Generate the geometry as a triangle fan array(s) */
+    public static final int TRIANGLE_FANS = 4;
+
+    /** Generate the geometry as indexed quads */
+    public static final int INDEXED_QUADS = 5;
+
+    /** Generate the geometry as an indexed triangle array */
+    public static final int INDEXED_TRIANGLES = 6;
+
+    /** Generate the geometry as an indexed triangle strip array */
+    public static final int INDEXED_TRIANGLE_STRIPS = 7;
+
+    /** Generate the geometry as an indexed triangle fan array */
+    public static final int INDEXED_TRIANGLE_FANS = 8;
+
+    /** Generate the geometry as a line array */
+    public static final int LINES = 9;
+
+    /** Generate the geometry as an line strip array */
+    public static final int LINE_STRIPS = 10;
+
+    /** Generate the geometry as an indexed line array */
+    public static final int INDEXED_LINES = 11;
+
+    /** Generate the geometry as an indexed line strip array */
+    public static final int INDEXED_LINE_STRIPS = 12;
+
+
+    /** Request for lighting normal data to be produced */
+    public static final int NORMAL_DATA = 0x02;
+
+    /** Request for 2D Texture coordinate data to be produced */
+    public static final int TEXTURE_2D_DATA = 0x04;
+
+    /** Request for 3D Texture coordinate data to be produced */
+    public static final int TEXTURE_3D_DATA = 0x08;
+
+    /** This is the type of geometry that you want to have made */
+    public int geometryType = 0;
+
+    /**
+     * A generator specific field that describes the type of output
+     * algorithm you would like to use for the geometry. May be ignored.
+     */
+    public int geometrySubType;
+
+    /**
+     * The attributes of the geometry you want created. This is an OR'd
+     * list of the above variables. It is not possible to generate anything
+     * without the raw geometry being computed.
+     */
+    public int geometryComponents;
+
+    /** The number of vertices stored in the coordinates array */
+    public int vertexCount;
+
+    /**
+     * Storage for coordinate information. These are stored in flat
+     * [x1, y1, z1, x2, y2, z2, ...] configuration
+     */
+    public float[] coordinates;
+
+    /**
+     * Storage for lighting normal information. This should be at least the
+     * length of the coordinates array. Data is stored in the same fashion.
+     * If normals are requested, the count is the same as vertexCount.
+     */
+    public float[] normals;
+
+    /** The number of items stored in the indexes array */
+    public int indexesCount;
+
+    /** Storage for coordinate index information if the shape type requires it. */
+    public int[] indexes;
+
+    /** The number of items stored in the strip counts */
+    public int numStrips;
+
+    /** Storage for strip counts if the shape type uses it */
+    public int[] stripCounts;
+
+    /**
+     * Texture coordinate information if requested. May be 2D or 3D depending
+     * on the requested type. If 2D the values are stored [s1, t1, s2, t2...]
+     * For 3D coordinates it is stores as [r1, s1, t1, r2, s2, t2,...]
+     */
+    public float[][] textureCoordinates;
+
+    /** The number of texture sets in the textureCoordinates field */
+    public int numTexSets;
+
+    /** The number of unique texture sets */
+    public int numUniqueTexSets;
+
+    /**
+     * Colour values if using per-vertex coloring. This array will be identical
+     * in length to the coordinate array and index values match etc.
+     */
+    public float[] colors;
+
+    /**
+     * Storage for normal index information if the shape type requires it. Not
+     * used by the geometry generation classes, but may be by 3rd party software.
+     */
+    public int[] normalIndexes;
+
+    /**
+     * Storage for texture coordinate index information if the shape type
+     * requires it. Not used by the geometry generation classes, but may be by
+     * 3rd party software.
+     */
+    public int[] texCoordIndexes;
+
+    /**
+     * Storage for color index information if the shape type requires it. Not
+     * used by the geometry generation classes, but may be by 3rd party software.
+     */
+    public int[] colorIndexes;
+
+    /**
+     * Convenience method to print out all the data associated with
+     * this geometry array. Prints one vertex per line. Ignores
+     * index information.
+     */
+    public void prettyPrint()
+    {
+        NumberFormat format = NumberFormat.getInstance();
+        format.setMaximumFractionDigits(3);
+        format.setMinimumFractionDigits(3);
+
+        boolean has_3d_texture =
+            (geometryComponents & GeometryHolder.TEXTURE_2D_DATA) == 0;
+
+        System.out.println();
+        for(int i = 0; i < vertexCount; i++)
+        {
+            System.out.print(i);
+            System.out.print(" v: ");
+            System.out.print(format.format(coordinates[i * 3]));
+            System.out.print(' ');
+            System.out.print(format.format(coordinates[i * 3 + 1]));
+            System.out.print(' ');
+            System.out.print(format.format(coordinates[i * 3 + 2]));
+
+            if(normals != null)
+            {
+                System.out.print(", n: ");
+                System.out.print(format.format(normals[i * 3]));
+                System.out.print(' ');
+                System.out.print(format.format(normals[i * 3 + 1]));
+                System.out.print(' ');
+                System.out.print(format.format(normals[i * 3 + 2]));
+            }
+
+            if(colors != null)
+            {
+                System.out.print(", c: ");
+                System.out.print(format.format(colors[i * 3]));
+                System.out.print(' ');
+                System.out.print(format.format(colors[i * 3 + 1]));
+                System.out.print(' ');
+                System.out.print(format.format(colors[i * 3 + 2]));
+            }
+
+            for(int j=0; j < numTexSets; j++) {
+                if(textureCoordinates[j] != null)
+                {
+                    if(has_3d_texture)
+                    {
+                        System.out.print(", t: ");
+                        System.out.print(format.format(textureCoordinates[j][i * 3]));
+                        System.out.print(' ');
+                        System.out.print(format.format(textureCoordinates[j][i * 3 + 1]));
+                        System.out.print(' ');
+                        System.out.print(format.format(textureCoordinates[j][i * 3 + 2]));
+                    }
+                    else
+                    {
+                        System.out.print(", t: ");
+                        System.out.print(format.format(textureCoordinates[j][i * 2]));
+                        System.out.print(' ');
+                        System.out.print(format.format(textureCoordinates[j][i * 2 + 1]));
+                    }
+
+                }
+            }
+
+            System.out.println();
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/VisibilityListener.java b/src/java/org/web3d/vrml/renderer/common/nodes/VisibilityListener.java
index 78c80a98e135e6ee55af616d7f88b1ed67e14b1b..6c3c029f4d901cc8bf3cc0c3634974902fc86f26 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/VisibilityListener.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/VisibilityListener.java
@@ -22,6 +22,7 @@ package org.web3d.vrml.renderer.common.nodes;
 
 /**
  * A marker interface for a node that wants to know whether its visible
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseCADAssembly.java b/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseCADAssembly.java
index 709b0a64b5a4ca6c9594d47caa694416551d206f..526a0d9ad44d600c2374e47ba4cf1379a340a684 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseCADAssembly.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseCADAssembly.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseGroupingNode;
 
 /**
  * Common base implementation of a CADAssembly node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseCADFace.java b/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseCADFace.java
index 8e5bfe4219f986f6f0b375fa1b42534d370376fa..4dcec228b9ab43e53c753113af450c1ff6566fa0 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseCADFace.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseCADFace.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.common.nodes.AbstractNode;
 
 /**
  * Common base implementation of a CADFace node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseCADLayer.java b/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseCADLayer.java
index 14345c4d0d0c24cb6ef1bf150d19cff099145955..65f7825af6c880fd52675ef2da8a4175d4577c77 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseCADLayer.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseCADLayer.java
@@ -26,6 +26,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseGroupingNode;
 
 /**
  * Common base implementation of a CADLayer node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.6 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseCADPart.java b/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseCADPart.java
index e2ca1d6a5656ee9a28df53ef5f67e749be7dfa20..6f11dfef56f2e04a221cf18a2f9cab6ff5008fb7 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseCADPart.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseCADPart.java
@@ -28,6 +28,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseGroupingNode;
 
 /**
  * Common base implementation of a CADPart node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseIndexedQuadSet.java b/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseIndexedQuadSet.java
index 1fd5fb1516da4daeef10ed924929fb77157fd537..8b18486d1a712bc8c42871ea74d3220c56343af2 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseIndexedQuadSet.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseIndexedQuadSet.java
@@ -24,7 +24,9 @@ import org.web3d.vrml.renderer.common.nodes.BaseComponentGeometryNode;
 
 /**
  * Common IndexedQuadSet handling.
- * 
+ * <p>
+ *
+ *
  * @author Vincent Marchetti
  * @version $Revision: 1.6 $
  * copied from the BaseQuadSet.java class by Alan Hudson
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseQuadSet.java b/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseQuadSet.java
index 7b3340322582b49dec4d797d221112b15b4afc4d..7a016f9fcaa8e3599aa75a892bce94eaa493d4d3 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseQuadSet.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/cadgeometry/BaseQuadSet.java
@@ -24,6 +24,8 @@ import org.web3d.vrml.renderer.common.nodes.BaseComponentGeometryNode;
 
 /**
  * Common QuadSet handling.
+ * <p>
+ *
  *
  * @author Alan Hudson
  * @version $Revision: 1.6 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseMetadataDouble.java b/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseMetadataDouble.java
index a6b5eb5d3c60a54a3f3721c32a6f3dbb7179acb5..a7250d158b4bf100c211d426b3717fc8401b1571 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseMetadataDouble.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseMetadataDouble.java
@@ -24,7 +24,8 @@ import org.web3d.vrml.renderer.common.nodes.BaseMetadataObjectNode;
 
 /**
  * A node that represents double metadata node.
- * 
+ * <p>
+ *
  * @author Justin Couch
  * @version $Revision: 1.7 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseMetadataFloat.java b/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseMetadataFloat.java
index 50de772b430e2263b233a8a85e1b734378010882..23364c2c17186d28b4da04b0da4feb699633bbc1 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseMetadataFloat.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseMetadataFloat.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseMetadataObjectNode;
 
 /**
  * A node that represents Float metadata node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.7 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseMetadataInteger.java b/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseMetadataInteger.java
index cb205f8f633dec829db17a34405752a069fd15fd..8830cdab73d2542db4d31336abcb8e7f3aa26b21 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseMetadataInteger.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseMetadataInteger.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseMetadataObjectNode;
 
 /**
  * A node that represents Integer metadata node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.8 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseMetadataSet.java b/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseMetadataSet.java
index 4e3551ed58b1472fd658ce4f27951b87841f48c3..2acf94d8c5296bc19aaf6c4d4ea12f68f7a63e1a 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseMetadataSet.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseMetadataSet.java
@@ -26,6 +26,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseMetadataObjectNode;
 
 /**
  * A node that represents a set of metadata nodes.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.8 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseMetadataString.java b/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseMetadataString.java
index fef709cfa55fe551cc38170050a6db20365f705c..72405aa5d906580e604091b6bf136e0ba9b5dd48 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseMetadataString.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseMetadataString.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseMetadataObjectNode;
 
 /**
  * A node that represents String metadata node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.6 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseWorldInfo.java b/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseWorldInfo.java
index 8f0e2d2e437a3faff462221caba1cb609de1521d..3d63779273a6d004d9ae87d36b7ff257762bb498 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseWorldInfo.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/core/BaseWorldInfo.java
@@ -26,6 +26,7 @@ import org.web3d.vrml.renderer.common.nodes.AbstractNode;
 
 /**
  * Common base implementation of a WorldInfo node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.14 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/enveffects/BaseBackground.java b/src/java/org/web3d/vrml/renderer/common/nodes/enveffects/BaseBackground.java
index e61b32ffac9a996c401ae53de7b7b780874a7872..03c6ab6e54febd1fbf90939660766c5c0b892149 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/enveffects/BaseBackground.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/enveffects/BaseBackground.java
@@ -30,6 +30,8 @@ import org.web3d.vrml.util.FieldValidator;
 
 /**
  * Common base implementation of a Background node.
+ * <p>
+ *
  * @author Justin Couch
  * @version $Revision: 1.22 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/enveffects/BaseFog.java b/src/java/org/web3d/vrml/renderer/common/nodes/enveffects/BaseFog.java
index baa1f2f23c89357a800f536dbf2733e613a5c06e..a9f93f0cd6a91f214eee9c42d16e99bbec0faa1a 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/enveffects/BaseFog.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/enveffects/BaseFog.java
@@ -28,6 +28,7 @@ import org.web3d.vrml.util.FieldValidator;
 
 /**
  * Common base implementation of a fog node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.14 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/environment/BaseProximitySensor.java b/src/java/org/web3d/vrml/renderer/common/nodes/environment/BaseProximitySensor.java
index c7b7eb7a86e56a295622b7a34821a9fa369d9c10..387243bc23293415a9bf7e674792cff2655823d2 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/environment/BaseProximitySensor.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/environment/BaseProximitySensor.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseSensorNode;
 
 /**
  * Common base implementation of a ProximitySensor node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.8 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/environment/BaseVisibilitySensor.java b/src/java/org/web3d/vrml/renderer/common/nodes/environment/BaseVisibilitySensor.java
index cddb030f939dad5d605a3ce575091573e568908f..a36d43aaea43c7027e49313a7ab6675333ff5bd0 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/environment/BaseVisibilitySensor.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/environment/BaseVisibilitySensor.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseSensorNode;
 
 /**
  * Base implementation of a VisibilitySensor node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.11 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseBooleanFilter.java b/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseBooleanFilter.java
index be27a78e7426461d5a8fa2ec3638350b22957e76..2a48bc77cc507eacbefbc3b9638b076d733b07dc 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseBooleanFilter.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseBooleanFilter.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.common.nodes.AbstractNode;
 
 /**
  * Common implementation of a BooleanFilter Node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.8 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseBooleanSequencer.java b/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseBooleanSequencer.java
index ddecb1149be7f2dac719429ee2c28bb1a12f5080..6211a8e8eb124d6cfd41cfce4ce1b764b6a56a1c 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseBooleanSequencer.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseBooleanSequencer.java
@@ -30,6 +30,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseSequencerNode;
 /**
  * Abstract implementation of a boolean sequencer so that specific
  * renderer instances can derive from it.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.12 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseBooleanToggle.java b/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseBooleanToggle.java
index 1a2c781bcff91fc407c5d3c280be9d3b5ea08b79..222b6ed02b822b2fbe5fa79f44734223bdc72783 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseBooleanToggle.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseBooleanToggle.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.common.nodes.AbstractNode;
 
 /**
  * Common implementation of a BooleanToggle Node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.7 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseBooleanTrigger.java b/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseBooleanTrigger.java
index 98480bb166117af2ff4e0c5af77e3271d27872a5..309bb458ebf1d08f38e8b7034e710b33b32d7ed3 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseBooleanTrigger.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseBooleanTrigger.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.common.nodes.AbstractNode;
 
 /**
  * Common implementation of a BooleanTrigger Node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.7 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseIntegerTrigger.java b/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseIntegerTrigger.java
index 62c42de7f5abb697f44fd21b53938b11407c0df0..5f617bb97ae2a68e0ced28474318a4b33271afb0 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseIntegerTrigger.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseIntegerTrigger.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.common.nodes.AbstractNode;
 
 /**
  * Common implementation of a IntegerTrigger Node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.7 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseTimeTrigger.java b/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseTimeTrigger.java
index d4bd8866abc17fc1bc756da18aa210efb8741a37..5a61710baa6d025e09116358075699e70b3a3bd8 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseTimeTrigger.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/eventutils/BaseTimeTrigger.java
@@ -29,6 +29,7 @@ import org.web3d.vrml.renderer.common.nodes.AbstractNode;
  * time information. As an efficiency measure, if the time sensor is disabled
  * it will remove itself as a listener to the global clock. When it becomes
  * re-enabled that listener will be added back again.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.7 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geom3d/BaseBox.java b/src/java/org/web3d/vrml/renderer/common/nodes/geom3d/BaseBox.java
index fc8830220ca55414dd48d39a0a4f005b72ff6a21..ac61c3fb624c466fbfb97ae9d82585c21e3fa6b2 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geom3d/BaseBox.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geom3d/BaseBox.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.common.nodes.AbstractNode;
 
 /**
  * Common base implementation of a Box node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.19 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geom3d/BaseCone.java b/src/java/org/web3d/vrml/renderer/common/nodes/geom3d/BaseCone.java
index 657b752f53f976356b2efa4566337674320ae18b..20f9083c2e5220a811fc6a446c495deb05cb35fd 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geom3d/BaseCone.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geom3d/BaseCone.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.common.nodes.AbstractNode;
 
 /**
  * Common base implementation of a Cone node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.16 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geom3d/BaseCylinder.java b/src/java/org/web3d/vrml/renderer/common/nodes/geom3d/BaseCylinder.java
index 7722a3636bfd4be094a837ccf0000b83e389209b..f383ad23bf42c96056652ec1c29676f84eec7b16 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geom3d/BaseCylinder.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geom3d/BaseCylinder.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.common.nodes.AbstractNode;
 
 /**
  * Common base implementation of a Cylinder.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.18 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geom3d/BaseExtrusion.java b/src/java/org/web3d/vrml/renderer/common/nodes/geom3d/BaseExtrusion.java
index 309bf7e4777fccb61310a800d38d1d209fd2c508..bb95ee8c6c4d4236186d2920d072873e778f8c1e 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geom3d/BaseExtrusion.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geom3d/BaseExtrusion.java
@@ -1,993 +1,993 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.renderer.common.nodes.geom3d;
-
-// External imports
-import java.util.HashMap;
-import java.util.Map;
-
-// Local imports
-import org.web3d.vrml.lang.*;
-import org.web3d.vrml.nodes.*;
-import org.web3d.vrml.renderer.common.nodes.AbstractNode;
-
-/**
- * Common base implementation of an Extrusion.
- * An Extrusion node specifies geometric shapes based on a
- * two-dimensional cross-section extruded along a three dimensional
- * spine in the local coordinate system.<p>
- * The cross-sections of an Extrusion can be scaled and rotated
- * at each spine point to produce a wide variety of shapes.  For
- * each spine point, the cross-section shape is scaled by the
- * vfScale parameter, translated by the spine parameter, and then
- * oriented using the orientation parameter.  Corresponding
- * vertices of the first and second cross-sections are then
- * connected, forming a quadrilateral polygon between each pair
- * of vertices.
- *
- * @author Andrzej Kapolka, additional commenting by Eric Fickenscher
- * @version $Revision: 1.19 $
- */
-public abstract class BaseExtrusion extends AbstractNode
-    implements VRMLGeometryNodeType {
-
-    /** Field Index for beginCap */
-    protected static final int FIELD_BEGIN_CAP = LAST_NODE_INDEX + 1;
-
-    /** Field Index for ccw */
-    protected static final int FIELD_CCW = LAST_NODE_INDEX + 2;
-
-    /** Field Index for convex */
-    protected static final int FIELD_CONVEX = LAST_NODE_INDEX + 3;
-
-    /** Field Index for creaseAngle */
-    protected static final int FIELD_CREASE_ANGLE = LAST_NODE_INDEX + 4;
-
-    /** Field Index for crossSection */
-    protected static final int FIELD_CROSS_SECTION = LAST_NODE_INDEX + 5;
-
-    /** Field Index for endCap */
-    protected static final int FIELD_END_CAP = LAST_NODE_INDEX + 6;
-
-    /** Field Index for orientation */
-    protected static final int FIELD_ORIENTATION = LAST_NODE_INDEX + 7;
-
-    /** Field Index for scale */
-    protected static final int FIELD_SCALE = LAST_NODE_INDEX + 8;
-
-    /** Field Index for solid */
-    protected static final int FIELD_SOLID = LAST_NODE_INDEX + 9;
-
-    /** Field Index for spine */
-    protected static final int FIELD_SPINE = LAST_NODE_INDEX + 10;
-
-    /** Field Index for set_crossSection */
-    protected static final int FIELD_SET_CROSS_SECTION = LAST_NODE_INDEX + 11;
-
-    /** Field Index for set_orientation */
-    protected static final int FIELD_SET_ORIENTATION = LAST_NODE_INDEX + 12;
-
-    /** Field Index for set_scale */
-    protected static final int FIELD_SET_SCALE = LAST_NODE_INDEX + 13;
-
-    /** Field Index for set_spine */
-    protected static final int FIELD_SET_SPINE = LAST_NODE_INDEX + 14;
-
-    /** The last index in this node */
-    protected static final int LAST_EXTRUSION_INDEX = FIELD_SET_SPINE;
-
-    /** Number of fields constant */
-    protected static final int NUM_FIELDS = LAST_EXTRUSION_INDEX + 1;
-
-    /** Array of VRMLFieldDeclarations */
-    private static VRMLFieldDeclaration[] fieldDecl;
-
-    /** Hashmap between a field name and its index */
-    private static final Map<String, Integer> fieldMap;
-
-    /** Listing of field indexes that have nodes */
-    private static int[] nodeFields;
-
-    // VRML Field declarations
-
-    /**
-     * This field specifies the vertex ordering -
-     * if TRUE, the right-hand rule is used, meaning
-     * the vertices are ordered in a counter-clockwise
-     * direction. <p> SFBool ccw
-     */
-    protected boolean vfCCW;
-
-    /**
-     * This field specifies if the cross-section is convex
-     * or concave.  If FALSE, the cross-section is concave;
-     * the browser will split the cross-section into
-     * smaller convex cross sections. <p>
-     * SFBool convex
-     */
-    protected boolean vfConvex;
-
-    /**
-     * creaseAngle specifies an angle threshold.  If two
-     * adjacent faces make an angle bigger than the
-     * creaseAngle, viewer will clearly see where the two
-     * faces meet - the edge linking the two faces is sharp.
-     * Otherwise the edge linking the two faces will be smooth.
-     * <p>SFFloat creaseAngle
-     */
-    protected float vfCreaseAngle;
-
-    /**
-     * This is an array of floats that represents
-     * the extrusion's 2D cross-section. The 2D cross-
-     * section is replicated once for each 'spine'
-     * point, and manipulated with the 'scale' and
-     * 'orientation' fields.
-     * <p> This float array represents a 2D cross-section
-     * in the y=0 plane.  Thus, every two float values
-     * constitute a point (index [0] is the "x" value of the
-     * first point, index [1] is the "z" value of the first
-     * point; index [2] is the "x" value of the second
-     * point, etc.).  When the final two values match the
-     * first two values, the 2D cross-section is closed
-     * (the first and last points are the same). If
-     * crossSection is not a closed curve, note that
-     * beginCaps or endCaps can still be generated by
-     * adding a final point to the crossSection that is
-     * equal to the initial point.  A simple case of a
-     * capped open surface is a shape analogous to a soda
-     * can sliced in half vertically.
-     *  <p>
-     * MFVec2f crossSection
-     */
-    protected float[] vfCrossSection;
-
-    /**
-     * This int keeps track of the number of valid items in
-     * vfCrossSection.  Since vfCrossSection represents a
-     * number of points in a 2D plane, there are two values
-     * needed to represent each point.  Thus, the number of
-     * points is always equal to half the length of
-     * vfCrossSection.
-     */
-    protected int numCrossSection;
-
-    /**
-     * This field specifies if the extruded shape is open
-     * or closed at one end.  If TRUE, the 'beginning'
-     * spine point will be closed.  If vfEndCap is also
-     * TRUE, then user will _not_ be able to see into the
-     * object. <p>
-     * SFBool beginCap
-     */
-    protected boolean vfBeginCap;
-
-    /**
-     * This field specifies if the extruded shape is open
-     * or closed at one end.  If TRUE, the final 'end
-     * spine point will be closed.  If vfBeginCap is also
-     * TRUE, then user will _not_ be able to see into the
-     * object. <p>
-     * SFBool endCap
-     */
-    protected boolean vfEndCap;
-
-    /**
-     * This field specifies cross-section rotation.
-     * The final orientation of each cross-section is computed
-     * by first orienting it relative to the spine segments
-     * on either side of the point at which the cross-
-     * section is placed (the "spine-aligned cross-section
-     * plane", or SCP) and then rotating it according to
-     * the appropriate orientation value. <p> Each orientation
-     * value is defined by four float values.  The first
-     * three floats specify an axis corresponding to a ray cast
-     * from the relative-to-the-SCP origin through an x-, y-,
-     * and z- point.  The fourth float specifies the amount
-     * (in radians) of rotation around this axis; 3.14
-     * corresponds to 180 degrees of rotation, .523
-     * corresponds to 60 degrees of rotation, etc. <p> As
-     * is the case with the 'scale' field, if the number
-     * of orientation values is greater than the number
-     * of spine points, the excess values are ignored.
-     * If there is only one orientation value, it is
-     * applied at all spine points.
-     * <p> MFRotation orientation
-     */
-    protected float[] vfOrientation;
-
-    /**
-     * This int keeps track of the number of valid items
-     * in vfOrientation.  Since orientation specifies
-     * a rotation around an axis, four float values are
-     * needed - the first three specify the axis of
-     * rotation via x-, y-, and z- values (ie: yaw,
-     * pitch, and roll), and the fourth float value
-     * specifies the amount (in radians) of rotation
-     * around this axis.  Thus, the the number of
-     * orientation points is always equal to one-
-     * fourth the length of vfOrientation.
-     */
-    protected int numOrientation;
-
-    /**
-     * This field specifies scaling of the cross-sections.
-     * Since the cross-section represents a 2-dimensional
-     * shape, two values are needed to scale a cross-section.
-     * Each cross-section is scaled about its relative origin
-     * by the appropriate scale parameter (the first value
-     * scales in X, second values scales in Z). <p>  As is
-     * the case with the 'orientation' field, if the number
-     * of scale values is greater than the number of spine
-     * points, the excess values are ignored.  If there is
-     * only one scale value, it is applied at all spine points.
-     * <p> MFVec2f scale
-     */
-    protected float[] vfScale;
-
-    /**
-     * This int keeps track of the number of valid items
-     * in vfScale.  Since vfScale specifies the scaling
-     * of a two-dimensional object, two float values are
-     * needed - the first specifies the amount of scaling
-     * in the x-direction and the second specifies the
-     * amount of scaling in the z-direction.  Thus, the
-     * number of scale points is always equal to one-half
-     * the length of vfScale.
-     */
-    protected int numScale;
-
-    /**
-     * This field specifies if the extruded shape is
-     * solid or not.  If TRUE, the object is treated
-     * as a solid, which means that the _inside_
-     * surfaces will not be rendered.  IE, if the ends
-     * are not capped and vfSolid is TRUE, user will
-     * only see the faces of the object that directly
-     * face the viewer.  If FALSE, the extruded shape
-     * is treated as hollow, and user will see all
-     * faces of the shape if the ends are not capped.
-     * <p>
-     * SFBool solid
-     */
-    protected boolean vfSolid;
-
-    /**
-     * This field represents the placement of the
-     * cross-sections in 3D space.  In other words, the
-     * spine defines the path that the cross-section will
-     * travel.  The corners of each cross-section are connected
-     * to matching corners of adjacent cross-sections, thus
-     * defining a volume.  <p> In a two-point spine, the
-     * cross-section is oriented so that the y-axis coincides
-     * with the direction defined by the two spine points.
-     * When using more spine points, this holds true for the
-     * first spine point, and second and subsequent spine points
-     * should orient the cross-section so that it is
-     * perpendicular to the tangent of the spine.
-     * <p> Every three values constitute a point
-     * (indices [0],[1], and [2] represent the first point,
-     * indices [3],[4], and [5] represent the second point, etc.).
-     * The simplest spine consists of only two points. <p>
-     * MFVec3f spine
-     */
-    protected float[] vfSpine;
-
-    /**
-     * This int keeps track of the number of valid items in
-     * vfSpine.  Since vfSpine represents a number of points
-     * in a 3D plane, there are three values needed to
-     * represent each point.  Thus, the number of spine
-     * points is always equal to one-third the length of
-     * vfSpine.
-     */
-    protected int numSpine;
-
-    // Static constructor
-    static {
-        nodeFields = new int[] { FIELD_METADATA };
-
-        fieldDecl = new VRMLFieldDeclaration[NUM_FIELDS];
-        fieldMap = new HashMap<>(NUM_FIELDS*3);
-
-        fieldDecl[FIELD_METADATA] =
-            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
-                                     "SFNode",
-                                     "metadata");
-        fieldDecl[FIELD_BEGIN_CAP] =
-            new VRMLFieldDeclaration(FieldConstants.FIELD,
-                                     "SFBool",
-                                     "beginCap");
-        fieldDecl[FIELD_CCW] =
-            new VRMLFieldDeclaration(FieldConstants.FIELD,
-                                     "SFBool",
-                                     "ccw");
-        fieldDecl[FIELD_CONVEX] =
-            new VRMLFieldDeclaration(FieldConstants.FIELD,
-                                     "SFBool",
-                                     "convex");
-        fieldDecl[FIELD_CREASE_ANGLE] =
-            new VRMLFieldDeclaration(FieldConstants.FIELD,
-                                     "SFFloat",
-                                     "creaseAngle");
-        fieldDecl[FIELD_CROSS_SECTION] =
-            new VRMLFieldDeclaration(FieldConstants.FIELD,
-                                     "MFVec2f",
-                                     "crossSection");
-        fieldDecl[FIELD_END_CAP] =
-            new VRMLFieldDeclaration(FieldConstants.FIELD,
-                                     "SFBool",
-                                     "endCap");
-        fieldDecl[FIELD_ORIENTATION] =
-            new VRMLFieldDeclaration(FieldConstants.FIELD,
-                                     "MFRotation",
-                                     "orientation");
-        fieldDecl[FIELD_SCALE] =
-            new VRMLFieldDeclaration(FieldConstants.FIELD,
-                                     "MFVec2f",
-                                     "scale");
-        fieldDecl[FIELD_SOLID] =
-            new VRMLFieldDeclaration(FieldConstants.FIELD,
-                                     "SFBool",
-                                     "solid");
-        fieldDecl[FIELD_SPINE] =
-            new VRMLFieldDeclaration(FieldConstants.FIELD,
-                                     "MFVec3f",
-                                     "spine");
-        fieldDecl[FIELD_SET_CROSS_SECTION] =
-            new VRMLFieldDeclaration(FieldConstants.EVENTIN,
-                                     "MFVec2f",
-                                     "set_crossSection");
-        fieldDecl[FIELD_SET_ORIENTATION] =
-            new VRMLFieldDeclaration(FieldConstants.EVENTIN,
-                                     "MFRotation",
-                                     "set_orientation");
-        fieldDecl[FIELD_SET_SCALE] =
-            new VRMLFieldDeclaration(FieldConstants.EVENTIN,
-                                     "MFVec2f",
-                                     "set_scale");
-        fieldDecl[FIELD_SET_SPINE] =
-            new VRMLFieldDeclaration(FieldConstants.EVENTIN,
-                                     "MFVec3f",
-                                     "set_spine");
-
-        Integer idx = FIELD_METADATA;
-        fieldMap.put("metadata", idx);
-        fieldMap.put("set_metadata", idx);
-        fieldMap.put("metadata_changed", idx);
-
-        fieldMap.put("beginCap", FIELD_BEGIN_CAP);
-        fieldMap.put("endCap", FIELD_END_CAP);
-        fieldMap.put("ccw", FIELD_CCW);
-        fieldMap.put("convex", FIELD_CONVEX);
-        fieldMap.put("creaseAngle", FIELD_CREASE_ANGLE);
-        fieldMap.put("solid", FIELD_SOLID);
-
-        fieldMap.put("scale", FIELD_SCALE);
-        fieldMap.put("set_scale", FIELD_SET_SCALE);
-
-        fieldMap.put("orientation", FIELD_ORIENTATION);
-        fieldMap.put("set_orientation", FIELD_SET_ORIENTATION);
-
-        fieldMap.put("crossSection", FIELD_CROSS_SECTION);
-        fieldMap.put("set_crossSection", FIELD_SET_CROSS_SECTION);
-
-        fieldMap.put("spine", FIELD_SPINE);
-        fieldMap.put("set_spine", FIELD_SET_SPINE);
-    }
-
-    /**
-     * Construct a default extrusion instance
-     */
-    protected BaseExtrusion() {
-        super("Extrusion");
-
-        hasChanged = new boolean[NUM_FIELDS];
-
-        vfBeginCap = true;
-        vfCCW = true;
-        vfConvex = true;
-        vfCreaseAngle = 0.9f;
-        vfCrossSection = new float[] { 1.0f, 1.0f, 1.0f, -1.0f, -1.0f,
-                                       -1.0f, -1.0f, 1.0f, 1.0f, 1.0f };
-        numCrossSection = vfCrossSection.length / 2;
-
-        vfEndCap = true;
-        vfOrientation = new float[] { 0.0f, 0.0f, 1.0f, 0.0f };
-        numOrientation = vfOrientation.length / 4;
-
-        vfScale = new float[] { 1.0f, 1.0f };
-        numScale = vfScale.length / 2;
-        vfSolid = true;
-        vfSpine = new float[] { 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f };
-        numSpine = vfSpine.length / 3;
-    }
-
-    /**
-     * Construct a new instance of this node based on the details from the
-     * given node. If the node is not a Box node, an exception will be
-     * thrown.
-     *
-     * @param node The node to copy
-     * @throws IllegalArgumentException The node is not a Group node
-     */
-    public BaseExtrusion(VRMLNodeType node) {
-        this(); // invoke default constructor
-
-        checkNodeType(node);
-
-        try {
-            int index = node.getFieldIndex("beginCap");
-            VRMLFieldData field = node.getFieldValue(index);
-            vfBeginCap = field.booleanValue;
-
-            index = node.getFieldIndex("ccw");
-            field = node.getFieldValue(index);
-            vfCCW = field.booleanValue;
-
-            index = node.getFieldIndex("convex");
-            field = node.getFieldValue(index);
-            vfConvex = field.booleanValue;
-
-            index = node.getFieldIndex("creaseAngle");
-            field = node.getFieldValue(index);
-            vfCreaseAngle = field.floatValue;
-
-            index = node.getFieldIndex("crossSection");
-            field = node.getFieldValue(index);
-
-            if(field.numElements != 0) {
-                vfCrossSection = new float[field.numElements * 2];
-                System.arraycopy(field.floatArrayValues,
-                                 0,
-                                 vfCrossSection,
-                                 0,
-                                 field.numElements * 2);
-
-                numCrossSection = field.numElements;
-            }
-
-            index = node.getFieldIndex("endCap");
-            field = node.getFieldValue(index);
-            vfEndCap = field.booleanValue;
-
-            index = node.getFieldIndex("orientation");
-            field = node.getFieldValue(index);
-
-            if(field.numElements != 0) {
-                vfOrientation = new float[field.numElements * 4];
-                System.arraycopy(field.floatArrayValues,
-                                 0,
-                                 vfOrientation,
-                                 0,
-                                 field.numElements * 4);
-
-                numOrientation = field.numElements;
-            }
-
-            index = node.getFieldIndex("scale");
-            field = node.getFieldValue(index);
-
-            if(field.numElements != 0) {
-                vfScale = new float[field.numElements * 2];
-                System.arraycopy(field.floatArrayValues,
-                                 0,
-                                 vfScale,
-                                 0,
-                                 field.numElements * 2);
-
-                numScale = field.numElements;
-            }
-
-            index = node.getFieldIndex("solid");
-            field = node.getFieldValue(index);
-            vfSolid = field.booleanValue;
-
-            index = node.getFieldIndex("spine");
-            field = node.getFieldValue(index);
-
-            if(field.numElements != 0) {
-                vfSpine = new float[field.numElements * 3];
-                System.arraycopy(field.floatArrayValues,
-                                 0,
-                                 vfSpine,
-                                 0,
-                                 field.numElements * 3);
-
-                numSpine = field.numElements;
-            }
-        } catch(VRMLException ve) {
-            throw new IllegalArgumentException(ve.getMessage());
-        }
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by VRMLGeometryNodeType
-    //----------------------------------------------------------
-
-    /**
-     * Specified whether this node has color information.  If so, then it
-     * will be used for diffuse terms instead of materials.
-     *
-     * @return true Use local color information for diffuse lighting.
-     */
-    @Override
-    public boolean hasLocalColors() {
-        return false;
-    }
-
-    /**
-     * Specified whether this node has alpha values in the local colour
-     * information. If so, then it will be used for to override the material's
-     * transparency value.
-     *
-     * @return true when the local color value has inbuilt alpha
-     */
-    @Override
-    public boolean hasLocalColorAlpha() {
-        return false;
-    }
-
-    /**
-     * Add a listener for local color changes.  Nulls and duplicates will be ignored.
-     *
-     * @param l The listener.
-     */
-    @Override
-    public void addLocalColorsListener(LocalColorsListener l) {
-    }
-
-    /**
-     * Remove a listener for local color changes.  Nulls will be ignored.
-     *
-     * @param l The listener.
-     */
-    @Override
-    public void removeLocalColorsListener(LocalColorsListener l) {
-    }
-
-    /**
-     * Add a listener for texture coordinate generation mode changes.
-     * Nulls and duplicates will be ignored.
-     *
-     * @param l The listener.
-     */
-    @Override
-    public void addTexCoordGenModeChanged(TexCoordGenModeListener l) {
-    }
-
-    /**
-     * Remove a listener for texture coordinate generation mode changes.
-     * Nulls will be ignored.
-     *
-     * @param l The listener.
-     */
-    @Override
-    public void removeTexCoordGenModeChanged(TexCoordGenModeListener l) {
-    }
-
-    /**
-     * Get the texture coordinate generation mode.  NULL is returned
-     * if the texture coordinates are not generated.
-     *
-     * @param setNum The set which this tex gen mode refers
-     * @return The mode or NULL
-     */
-    @Override
-    public String getTexCoordGenMode(int setNum) {
-        return null;
-    }
-
-    /**
-     * Set the number of textures that were found on the accompanying Appearance
-     * node. Used to set the number of texture coordinates that need to be
-     * passed in to the renderer when no explicit texture coordinates were
-     * given.
-     *
-     * @param count The number of texture coordinate sets to add
-     */
-    @Override
-    public void setTextureCount(int count) {
-    }
-
-    /**
-     * Get the number of texture coordinate sets contained by this node
-     *
-     * @return the number of texture coordinate sets
-     */
-    @Override
-    public int getNumSets() {
-        return 0;
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by VRMLGeometryNodeType
-    //----------------------------------------------------------
-
-    /**
-     * Get the value of the solid field.
-     *
-     * @return true This object is solid (ie single sided)
-     */
-    @Override
-    public boolean isSolid() {
-        return vfSolid;
-    }
-
-    /**
-     * Get the value of the CCW field. If the node does not have one, this will
-     * return true.
-     *
-     * @return true if the vertices are CCW ordered
-     */
-    @Override
-    public boolean isCCW() {
-        return true;
-    }
-
-    /**
-     * Specifies whether this node requires lighting.
-     *
-     * @return Should lighting be enabled
-     */
-    @Override
-    public boolean isLightingEnabled() {
-        return true;
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by VRMLNodeType
-    //----------------------------------------------------------
-
-    /**
-     * Get the index of the given field name. If the name does not exist for
-     * this node then return a value of -1.
-     *
-     * @param fieldName The name of the field we want the index from
-     * @return The index of the field name or -1
-     */
-    @Override
-    public int getFieldIndex(String fieldName) {
-        Integer index = fieldMap.get(fieldName);
-
-        return (index == null) ? -1 : index;
-    }
-
-    /**
-     * Get the list of indices that correspond to fields that contain nodes
-     * ie MFNode and SFNode). Used for blind scene graph traversal without
-     * needing to spend time querying for all fields etc. If a node does
-     * not have any fields that contain nodes, this shall return null. The
-     * field list covers all field types, regardless of whether they are
-     * readable or not at the VRML-level.
-     *
-     * @return The list of field indices that correspond to SF/MFnode fields
-     *    or null if none
-     */
-    @Override
-    public int[] getNodeFieldIndices() {
-        return nodeFields;
-    }
-
-    /**
-     * Get the declaration of the field at the given index. This allows for
-     * reverse lookup if needed. If the field does not exist, this will give
-     * a value of null.
-     *
-     * @param index The index of the field to get information
-     * @return A representation of this field's information
-     */
-    @Override
-    public VRMLFieldDeclaration getFieldDeclaration(int index) {
-        if(index < 0  || index > LAST_EXTRUSION_INDEX)
-            return null;
-
-        return fieldDecl[index];
-    }
-
-    /**
-     * Get the number of fields.
-     *
-     * @return The number of fields.
-     */
-    @Override
-    public int getNumFields() {
-        return fieldDecl.length;
-    }
-
-    /**
-     * Get the primary type of this node.  Replaces the instanceof mechanism
-     * for use in switch statements.
-     *
-     * @return The primary type
-     */
-    @Override
-    public int getPrimaryType() {
-        return TypeConstants.GeometryNodeType;
-    }
-
-    /**
-     * Get the value of a field. If the field is a primitive type, it will
-     * return a class representing the value. For arrays or nodes it will
-     * return the instance directly.
-     *
-     * @param index The index of the field to change.
-     * @return The class representing the field value
-     * @throws InvalidFieldException The field index is not known
-     */
-    @Override
-    public VRMLFieldData getFieldValue(int index)
-        throws InvalidFieldException {
-
-        VRMLFieldData fieldData = fieldLocalData.get();
-
-        fieldData.clear();
-
-        switch(index) {
-            case FIELD_BEGIN_CAP:
-                fieldData.booleanValue = vfBeginCap;
-                fieldData.dataType = VRMLFieldData.BOOLEAN_DATA;
-                break;
-
-            case FIELD_CCW:
-                fieldData.booleanValue = vfCCW;
-                fieldData.dataType = VRMLFieldData.BOOLEAN_DATA;
-                break;
-
-            case FIELD_CONVEX:
-                fieldData.booleanValue = vfConvex;
-                fieldData.dataType = VRMLFieldData.BOOLEAN_DATA;
-                break;
-
-            case FIELD_CREASE_ANGLE:
-                fieldData.floatValue = vfCreaseAngle;
-                fieldData.dataType = VRMLFieldData.FLOAT_DATA;
-                break;
-
-            case FIELD_CROSS_SECTION:
-                fieldData.floatArrayValues = vfCrossSection;
-                fieldData.numElements = numCrossSection;
-                fieldData.dataType = VRMLFieldData.FLOAT_ARRAY_DATA;
-                break;
-
-            case FIELD_END_CAP:
-                fieldData.booleanValue = vfEndCap;
-                fieldData.dataType = VRMLFieldData.BOOLEAN_DATA;
-                break;
-
-            case FIELD_ORIENTATION:
-                fieldData.floatArrayValues = vfOrientation;
-                fieldData.numElements = numOrientation;
-                fieldData.dataType = VRMLFieldData.FLOAT_ARRAY_DATA;
-                break;
-
-            case FIELD_SCALE:
-                fieldData.floatArrayValues = vfScale;
-                fieldData.numElements = numScale;
-                fieldData.dataType = VRMLFieldData.FLOAT_ARRAY_DATA;
-                break;
-
-            case FIELD_SOLID:
-                fieldData.booleanValue = vfSolid;
-                fieldData.dataType = VRMLFieldData.BOOLEAN_DATA;
-                break;
-
-            case FIELD_SPINE:
-                fieldData.floatArrayValues = vfSpine;
-                fieldData.numElements = numSpine;
-                fieldData.dataType = VRMLFieldData.FLOAT_ARRAY_DATA;
-                break;
-
-            default:
-                super.getFieldValue(index);
-        }
-
-        return fieldData;
-    }
-
-    /**
-     * Set the value of the field at the given index as an boolean. This would
-     * be used to set SFBool field types.
-     *
-     * @param index The index of destination field to set
-     * @param value The new value to use for the node
-     * @throws InvalidFieldException The field index is not known
-     * @throws InvalidFieldValueException The value provided is out of range
-     *    for the field type.
-     */
-    @Override
-    public void setValue(int index, boolean value)
-        throws InvalidFieldException, InvalidFieldValueException {
-
-
-        switch(index) {
-            case FIELD_BEGIN_CAP:
-                if(!inSetup)
-                    throwInitOnlyWriteException("beginCap");
-
-                vfBeginCap = value;
-                break;
-
-            case FIELD_CCW:
-                if(!inSetup)
-                    throwInitOnlyWriteException("ccw");
-
-                vfCCW = value;
-                break;
-
-            case FIELD_CONVEX:
-                if(!inSetup)
-                    throwInitOnlyWriteException("convex");
-
-                vfConvex = value;
-                break;
-
-            case FIELD_END_CAP:
-                if(!inSetup)
-                    throwInitOnlyWriteException("endCap");
-
-                vfEndCap = value;
-                break;
-
-            case FIELD_SOLID:
-                if(!inSetup)
-                    throwInitOnlyWriteException("solid");
-
-                vfSolid = value;
-                break;
-
-            default:
-                super.setValue(index, value);
-        }
-    }
-
-    /**
-     * Set the value of the field at the given index as a float. This would
-     * be used to set SFFloat field types.
-     *
-     * @param index The index of destination field to set
-     * @param value The new value to use for the node
-     * @throws InvalidFieldException The field index is not known
-     * @throws InvalidFieldValueException The value provided is out of range
-     *    for the field type.
-     */
-    @Override
-    public void setValue(int index, float value)
-        throws InvalidFieldException, InvalidFieldValueException {
-
-        switch(index)
-        {
-            case FIELD_CREASE_ANGLE:
-                if(!inSetup)
-                    throwInitOnlyWriteException("creaseAngle");
-
-                vfCreaseAngle = value;
-                break;
-
-            default:
-                super.setValue(index, value);
-        }
-    }
-
-    /**
-     * Set the value of the field at the given index as an array of floats.
-     * This would be used to set MFFloat, SFVec2f, SFVec3f and SFRotation
-     * field types.
-     *
-     * @param index The index of destination field to set
-     * @param value The new value to use for the node
-     * @param numValid The number of valid values to copy from the array
-     * @throws InvalidFieldException The field index is not known
-     * @throws InvalidFieldValueException The value provided is out of range
-     *    for the field type.
-     * @throws InvalidFieldAccessException The call is attempting to write to
-     *    a field that does not permit writing now
-     */
-    @Override
-    public void setValue(int index, float[] value, int numValid)
-        throws InvalidFieldException, InvalidFieldValueException,
-               InvalidFieldAccessException {
-
-        switch(index) {
-            case FIELD_CROSS_SECTION:
-                if(!inSetup)
-                    throwInitOnlyWriteException("crossSection");
-
-                vfCrossSection = value;
-                numCrossSection = numValid / 2;
-                break;
-
-            case FIELD_ORIENTATION:
-                if(!inSetup)
-                    throwInitOnlyWriteException("orientation");
-
-                vfOrientation = value;
-                numOrientation = numValid / 4;
-                break;
-
-            case FIELD_SCALE:
-                if(!inSetup)
-                    throwInitOnlyWriteException("scale");
-
-                vfScale = value;
-                numScale = numValid / 2;
-                break;
-
-            case FIELD_SPINE:
-                if(!inSetup)
-                    throwInitOnlyWriteException("spine");
-
-                vfSpine = value;
-                numSpine = numValid / 3;
-                break;
-
-            case FIELD_SET_CROSS_SECTION:
-                if(inSetup)
-                    throwInputOnlyWriteException("set_crossSection");
-
-                if(vfCrossSection.length < numValid)
-                    vfCrossSection = new float[numValid];
-
-                if(numValid != 0)
-                    System.arraycopy(value, 0, vfCrossSection, 0, numValid);
-
-                numCrossSection = numValid / 2;
-                break;
-
-            case FIELD_SET_ORIENTATION:
-                if(inSetup)
-                    throwInputOnlyWriteException("set_orientation");
-
-                if(vfOrientation.length < numValid)
-                    vfOrientation = new float[numValid];
-
-                if(numValid != 0)
-                    System.arraycopy(value, 0, vfOrientation, 0, numValid);
-
-                numOrientation = numValid / 4;
-                break;
-
-            case FIELD_SET_SCALE:
-                if(inSetup)
-                    throwInputOnlyWriteException("set_scale");
-
-                if(vfScale.length < numValid)
-                    vfScale = new float[numValid];
-
-                if(numValid != 0)
-                    System.arraycopy(value, 0, vfScale, 0, numValid);
-
-                numScale = numValid / 2;
-                break;
-
-            case FIELD_SET_SPINE:
-                if(inSetup)
-                    throwInputOnlyWriteException("set_spine");
-
-                if(vfSpine.length < numValid)
-                    vfSpine = new float[numValid];
-
-                if(numValid != 0)
-                    System.arraycopy(value, 0, vfSpine, 0, numValid);
-
-                numSpine = numValid / 3;
-                break;
-
-            default:
-                super.setValue(index, value, numValid);
-        }
-
-//        hasChanged[index] = true;
-//        fireFieldChanged(index);
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.renderer.common.nodes.geom3d;
+
+// External imports
+import java.util.HashMap;
+import java.util.Map;
+
+// Local imports
+import org.web3d.vrml.lang.*;
+import org.web3d.vrml.nodes.*;
+import org.web3d.vrml.renderer.common.nodes.AbstractNode;
+
+/**
+ * Common base implementation of an Extrusion.
+ * An Extrusion node specifies geometric shapes based on a
+ * two-dimensional cross-section extruded along a three dimensional
+ * spine in the local coordinate system.<p>
+ * The cross-sections of an Extrusion can be scaled and rotated
+ * at each spine point to produce a wide variety of shapes.  For
+ * each spine point, the cross-section shape is scaled by the
+ * vfScale parameter, translated by the spine parameter, and then
+ * oriented using the orientation parameter.  Corresponding
+ * vertices of the first and second cross-sections are then
+ * connected, forming a quadrilateral polygon between each pair
+ * of vertices.
+ *
+ * @author Andrzej Kapolka, additional commenting by Eric Fickenscher
+ * @version $Revision: 1.19 $
+ */
+public abstract class BaseExtrusion extends AbstractNode
+    implements VRMLGeometryNodeType {
+
+    /** Field Index for beginCap */
+    protected static final int FIELD_BEGIN_CAP = LAST_NODE_INDEX + 1;
+
+    /** Field Index for ccw */
+    protected static final int FIELD_CCW = LAST_NODE_INDEX + 2;
+
+    /** Field Index for convex */
+    protected static final int FIELD_CONVEX = LAST_NODE_INDEX + 3;
+
+    /** Field Index for creaseAngle */
+    protected static final int FIELD_CREASE_ANGLE = LAST_NODE_INDEX + 4;
+
+    /** Field Index for crossSection */
+    protected static final int FIELD_CROSS_SECTION = LAST_NODE_INDEX + 5;
+
+    /** Field Index for endCap */
+    protected static final int FIELD_END_CAP = LAST_NODE_INDEX + 6;
+
+    /** Field Index for orientation */
+    protected static final int FIELD_ORIENTATION = LAST_NODE_INDEX + 7;
+
+    /** Field Index for scale */
+    protected static final int FIELD_SCALE = LAST_NODE_INDEX + 8;
+
+    /** Field Index for solid */
+    protected static final int FIELD_SOLID = LAST_NODE_INDEX + 9;
+
+    /** Field Index for spine */
+    protected static final int FIELD_SPINE = LAST_NODE_INDEX + 10;
+
+    /** Field Index for set_crossSection */
+    protected static final int FIELD_SET_CROSS_SECTION = LAST_NODE_INDEX + 11;
+
+    /** Field Index for set_orientation */
+    protected static final int FIELD_SET_ORIENTATION = LAST_NODE_INDEX + 12;
+
+    /** Field Index for set_scale */
+    protected static final int FIELD_SET_SCALE = LAST_NODE_INDEX + 13;
+
+    /** Field Index for set_spine */
+    protected static final int FIELD_SET_SPINE = LAST_NODE_INDEX + 14;
+
+    /** The last index in this node */
+    protected static final int LAST_EXTRUSION_INDEX = FIELD_SET_SPINE;
+
+    /** Number of fields constant */
+    protected static final int NUM_FIELDS = LAST_EXTRUSION_INDEX + 1;
+
+    /** Array of VRMLFieldDeclarations */
+    private static VRMLFieldDeclaration[] fieldDecl;
+
+    /** Hashmap between a field name and its index */
+    private static final Map<String, Integer> fieldMap;
+
+    /** Listing of field indexes that have nodes */
+    private static int[] nodeFields;
+
+    // VRML Field declarations
+
+    /**
+     * This field specifies the vertex ordering -
+     * if TRUE, the right-hand rule is used, meaning
+     * the vertices are ordered in a counter-clockwise
+     * direction. <p> SFBool ccw
+     */
+    protected boolean vfCCW;
+
+    /**
+     * This field specifies if the cross-section is convex
+     * or concave.  If FALSE, the cross-section is concave;
+     * the browser will split the cross-section into
+     * smaller convex cross sections. <p>
+     * SFBool convex
+     */
+    protected boolean vfConvex;
+
+    /**
+     * creaseAngle specifies an angle threshold.  If two
+     * adjacent faces make an angle bigger than the
+     * creaseAngle, viewer will clearly see where the two
+     * faces meet - the edge linking the two faces is sharp.
+     * Otherwise the edge linking the two faces will be smooth.
+     * <p>SFFloat creaseAngle
+     */
+    protected float vfCreaseAngle;
+
+    /**
+     * This is an array of floats that represents
+     * the extrusion's 2D cross-section. The 2D cross-
+     * section is replicated once for each 'spine'
+     * point, and manipulated with the 'scale' and
+     * 'orientation' fields.
+     * <p> This float array represents a 2D cross-section
+     * in the y=0 plane.  Thus, every two float values
+     * constitute a point (index [0] is the "x" value of the
+     * first point, index [1] is the "z" value of the first
+     * point; index [2] is the "x" value of the second
+     * point, etc.).  When the final two values match the
+     * first two values, the 2D cross-section is closed
+     * (the first and last points are the same). If
+     * crossSection is not a closed curve, note that
+     * beginCaps or endCaps can still be generated by
+     * adding a final point to the crossSection that is
+     * equal to the initial point.  A simple case of a
+     * capped open surface is a shape analogous to a soda
+     * can sliced in half vertically.
+     *  <p>
+     * MFVec2f crossSection
+     */
+    protected float[] vfCrossSection;
+
+    /**
+     * This int keeps track of the number of valid items in
+     * vfCrossSection.  Since vfCrossSection represents a
+     * number of points in a 2D plane, there are two values
+     * needed to represent each point.  Thus, the number of
+     * points is always equal to half the length of
+     * vfCrossSection.
+     */
+    protected int numCrossSection;
+
+    /**
+     * This field specifies if the extruded shape is open
+     * or closed at one end.  If TRUE, the 'beginning'
+     * spine point will be closed.  If vfEndCap is also
+     * TRUE, then user will _not_ be able to see into the
+     * object. <p>
+     * SFBool beginCap
+     */
+    protected boolean vfBeginCap;
+
+    /**
+     * This field specifies if the extruded shape is open
+     * or closed at one end.  If TRUE, the final 'end
+     * spine point will be closed.  If vfBeginCap is also
+     * TRUE, then user will _not_ be able to see into the
+     * object. <p>
+     * SFBool endCap
+     */
+    protected boolean vfEndCap;
+
+    /**
+     * This field specifies cross-section rotation.
+     * The final orientation of each cross-section is computed
+     * by first orienting it relative to the spine segments
+     * on either side of the point at which the cross-
+     * section is placed (the "spine-aligned cross-section
+     * plane", or SCP) and then rotating it according to
+     * the appropriate orientation value. <p> Each orientation
+     * value is defined by four float values.  The first
+     * three floats specify an axis corresponding to a ray cast
+     * from the relative-to-the-SCP origin through an x-, y-,
+     * and z- point.  The fourth float specifies the amount
+     * (in radians) of rotation around this axis; 3.14
+     * corresponds to 180 degrees of rotation, .523
+     * corresponds to 60 degrees of rotation, etc. <p> As
+     * is the case with the 'scale' field, if the number
+     * of orientation values is greater than the number
+     * of spine points, the excess values are ignored.
+     * If there is only one orientation value, it is
+     * applied at all spine points.
+     * <p> MFRotation orientation
+     */
+    protected float[] vfOrientation;
+
+    /**
+     * This int keeps track of the number of valid items
+     * in vfOrientation.  Since orientation specifies
+     * a rotation around an axis, four float values are
+     * needed - the first three specify the axis of
+     * rotation via x-, y-, and z- values (ie: yaw,
+     * pitch, and roll), and the fourth float value
+     * specifies the amount (in radians) of rotation
+     * around this axis.  Thus, the the number of
+     * orientation points is always equal to one-
+     * fourth the length of vfOrientation.
+     */
+    protected int numOrientation;
+
+    /**
+     * This field specifies scaling of the cross-sections.
+     * Since the cross-section represents a 2-dimensional
+     * shape, two values are needed to scale a cross-section.
+     * Each cross-section is scaled about its relative origin
+     * by the appropriate scale parameter (the first value
+     * scales in X, second values scales in Z). <p>  As is
+     * the case with the 'orientation' field, if the number
+     * of scale values is greater than the number of spine
+     * points, the excess values are ignored.  If there is
+     * only one scale value, it is applied at all spine points.
+     * <p> MFVec2f scale
+     */
+    protected float[] vfScale;
+
+    /**
+     * This int keeps track of the number of valid items
+     * in vfScale.  Since vfScale specifies the scaling
+     * of a two-dimensional object, two float values are
+     * needed - the first specifies the amount of scaling
+     * in the x-direction and the second specifies the
+     * amount of scaling in the z-direction.  Thus, the
+     * number of scale points is always equal to one-half
+     * the length of vfScale.
+     */
+    protected int numScale;
+
+    /**
+     * This field specifies if the extruded shape is
+     * solid or not.  If TRUE, the object is treated
+     * as a solid, which means that the _inside_
+     * surfaces will not be rendered.  IE, if the ends
+     * are not capped and vfSolid is TRUE, user will
+     * only see the faces of the object that directly
+     * face the viewer.  If FALSE, the extruded shape
+     * is treated as hollow, and user will see all
+     * faces of the shape if the ends are not capped.
+     * <p>
+     * SFBool solid
+     */
+    protected boolean vfSolid;
+
+    /**
+     * This field represents the placement of the
+     * cross-sections in 3D space.  In other words, the
+     * spine defines the path that the cross-section will
+     * travel.  The corners of each cross-section are connected
+     * to matching corners of adjacent cross-sections, thus
+     * defining a volume.  <p> In a two-point spine, the
+     * cross-section is oriented so that the y-axis coincides
+     * with the direction defined by the two spine points.
+     * When using more spine points, this holds true for the
+     * first spine point, and second and subsequent spine points
+     * should orient the cross-section so that it is
+     * perpendicular to the tangent of the spine.
+     * <p> Every three values constitute a point
+     * (indices [0],[1], and [2] represent the first point,
+     * indices [3],[4], and [5] represent the second point, etc.).
+     * The simplest spine consists of only two points. <p>
+     * MFVec3f spine
+     */
+    protected float[] vfSpine;
+
+    /**
+     * This int keeps track of the number of valid items in
+     * vfSpine.  Since vfSpine represents a number of points
+     * in a 3D plane, there are three values needed to
+     * represent each point.  Thus, the number of spine
+     * points is always equal to one-third the length of
+     * vfSpine.
+     */
+    protected int numSpine;
+
+    // Static constructor
+    static {
+        nodeFields = new int[] { FIELD_METADATA };
+
+        fieldDecl = new VRMLFieldDeclaration[NUM_FIELDS];
+        fieldMap = new HashMap<>(NUM_FIELDS*3);
+
+        fieldDecl[FIELD_METADATA] =
+            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
+                                     "SFNode",
+                                     "metadata");
+        fieldDecl[FIELD_BEGIN_CAP] =
+            new VRMLFieldDeclaration(FieldConstants.FIELD,
+                                     "SFBool",
+                                     "beginCap");
+        fieldDecl[FIELD_CCW] =
+            new VRMLFieldDeclaration(FieldConstants.FIELD,
+                                     "SFBool",
+                                     "ccw");
+        fieldDecl[FIELD_CONVEX] =
+            new VRMLFieldDeclaration(FieldConstants.FIELD,
+                                     "SFBool",
+                                     "convex");
+        fieldDecl[FIELD_CREASE_ANGLE] =
+            new VRMLFieldDeclaration(FieldConstants.FIELD,
+                                     "SFFloat",
+                                     "creaseAngle");
+        fieldDecl[FIELD_CROSS_SECTION] =
+            new VRMLFieldDeclaration(FieldConstants.FIELD,
+                                     "MFVec2f",
+                                     "crossSection");
+        fieldDecl[FIELD_END_CAP] =
+            new VRMLFieldDeclaration(FieldConstants.FIELD,
+                                     "SFBool",
+                                     "endCap");
+        fieldDecl[FIELD_ORIENTATION] =
+            new VRMLFieldDeclaration(FieldConstants.FIELD,
+                                     "MFRotation",
+                                     "orientation");
+        fieldDecl[FIELD_SCALE] =
+            new VRMLFieldDeclaration(FieldConstants.FIELD,
+                                     "MFVec2f",
+                                     "scale");
+        fieldDecl[FIELD_SOLID] =
+            new VRMLFieldDeclaration(FieldConstants.FIELD,
+                                     "SFBool",
+                                     "solid");
+        fieldDecl[FIELD_SPINE] =
+            new VRMLFieldDeclaration(FieldConstants.FIELD,
+                                     "MFVec3f",
+                                     "spine");
+        fieldDecl[FIELD_SET_CROSS_SECTION] =
+            new VRMLFieldDeclaration(FieldConstants.EVENTIN,
+                                     "MFVec2f",
+                                     "set_crossSection");
+        fieldDecl[FIELD_SET_ORIENTATION] =
+            new VRMLFieldDeclaration(FieldConstants.EVENTIN,
+                                     "MFRotation",
+                                     "set_orientation");
+        fieldDecl[FIELD_SET_SCALE] =
+            new VRMLFieldDeclaration(FieldConstants.EVENTIN,
+                                     "MFVec2f",
+                                     "set_scale");
+        fieldDecl[FIELD_SET_SPINE] =
+            new VRMLFieldDeclaration(FieldConstants.EVENTIN,
+                                     "MFVec3f",
+                                     "set_spine");
+
+        Integer idx = FIELD_METADATA;
+        fieldMap.put("metadata", idx);
+        fieldMap.put("set_metadata", idx);
+        fieldMap.put("metadata_changed", idx);
+
+        fieldMap.put("beginCap", FIELD_BEGIN_CAP);
+        fieldMap.put("endCap", FIELD_END_CAP);
+        fieldMap.put("ccw", FIELD_CCW);
+        fieldMap.put("convex", FIELD_CONVEX);
+        fieldMap.put("creaseAngle", FIELD_CREASE_ANGLE);
+        fieldMap.put("solid", FIELD_SOLID);
+
+        fieldMap.put("scale", FIELD_SCALE);
+        fieldMap.put("set_scale", FIELD_SET_SCALE);
+
+        fieldMap.put("orientation", FIELD_ORIENTATION);
+        fieldMap.put("set_orientation", FIELD_SET_ORIENTATION);
+
+        fieldMap.put("crossSection", FIELD_CROSS_SECTION);
+        fieldMap.put("set_crossSection", FIELD_SET_CROSS_SECTION);
+
+        fieldMap.put("spine", FIELD_SPINE);
+        fieldMap.put("set_spine", FIELD_SET_SPINE);
+    }
+
+    /**
+     * Construct a default extrusion instance
+     */
+    protected BaseExtrusion() {
+        super("Extrusion");
+
+        hasChanged = new boolean[NUM_FIELDS];
+
+        vfBeginCap = true;
+        vfCCW = true;
+        vfConvex = true;
+        vfCreaseAngle = 0.9f;
+        vfCrossSection = new float[] { 1.0f, 1.0f, 1.0f, -1.0f, -1.0f,
+                                       -1.0f, -1.0f, 1.0f, 1.0f, 1.0f };
+        numCrossSection = vfCrossSection.length / 2;
+
+        vfEndCap = true;
+        vfOrientation = new float[] { 0.0f, 0.0f, 1.0f, 0.0f };
+        numOrientation = vfOrientation.length / 4;
+
+        vfScale = new float[] { 1.0f, 1.0f };
+        numScale = vfScale.length / 2;
+        vfSolid = true;
+        vfSpine = new float[] { 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f };
+        numSpine = vfSpine.length / 3;
+    }
+
+    /**
+     * Construct a new instance of this node based on the details from the
+     * given node. If the node is not a Box node, an exception will be
+     * thrown.
+     *
+     * @param node The node to copy
+     * @throws IllegalArgumentException The node is not a Group node
+     */
+    public BaseExtrusion(VRMLNodeType node) {
+        this(); // invoke default constructor
+
+        checkNodeType(node);
+
+        try {
+            int index = node.getFieldIndex("beginCap");
+            VRMLFieldData field = node.getFieldValue(index);
+            vfBeginCap = field.booleanValue;
+
+            index = node.getFieldIndex("ccw");
+            field = node.getFieldValue(index);
+            vfCCW = field.booleanValue;
+
+            index = node.getFieldIndex("convex");
+            field = node.getFieldValue(index);
+            vfConvex = field.booleanValue;
+
+            index = node.getFieldIndex("creaseAngle");
+            field = node.getFieldValue(index);
+            vfCreaseAngle = field.floatValue;
+
+            index = node.getFieldIndex("crossSection");
+            field = node.getFieldValue(index);
+
+            if(field.numElements != 0) {
+                vfCrossSection = new float[field.numElements * 2];
+                System.arraycopy(field.floatArrayValues,
+                                 0,
+                                 vfCrossSection,
+                                 0,
+                                 field.numElements * 2);
+
+                numCrossSection = field.numElements;
+            }
+
+            index = node.getFieldIndex("endCap");
+            field = node.getFieldValue(index);
+            vfEndCap = field.booleanValue;
+
+            index = node.getFieldIndex("orientation");
+            field = node.getFieldValue(index);
+
+            if(field.numElements != 0) {
+                vfOrientation = new float[field.numElements * 4];
+                System.arraycopy(field.floatArrayValues,
+                                 0,
+                                 vfOrientation,
+                                 0,
+                                 field.numElements * 4);
+
+                numOrientation = field.numElements;
+            }
+
+            index = node.getFieldIndex("scale");
+            field = node.getFieldValue(index);
+
+            if(field.numElements != 0) {
+                vfScale = new float[field.numElements * 2];
+                System.arraycopy(field.floatArrayValues,
+                                 0,
+                                 vfScale,
+                                 0,
+                                 field.numElements * 2);
+
+                numScale = field.numElements;
+            }
+
+            index = node.getFieldIndex("solid");
+            field = node.getFieldValue(index);
+            vfSolid = field.booleanValue;
+
+            index = node.getFieldIndex("spine");
+            field = node.getFieldValue(index);
+
+            if(field.numElements != 0) {
+                vfSpine = new float[field.numElements * 3];
+                System.arraycopy(field.floatArrayValues,
+                                 0,
+                                 vfSpine,
+                                 0,
+                                 field.numElements * 3);
+
+                numSpine = field.numElements;
+            }
+        } catch(VRMLException ve) {
+            throw new IllegalArgumentException(ve.getMessage());
+        }
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by VRMLGeometryNodeType
+    //----------------------------------------------------------
+
+    /**
+     * Specified whether this node has color information.  If so, then it
+     * will be used for diffuse terms instead of materials.
+     *
+     * @return true Use local color information for diffuse lighting.
+     */
+    @Override
+    public boolean hasLocalColors() {
+        return false;
+    }
+
+    /**
+     * Specified whether this node has alpha values in the local colour
+     * information. If so, then it will be used for to override the material's
+     * transparency value.
+     *
+     * @return true when the local color value has inbuilt alpha
+     */
+    @Override
+    public boolean hasLocalColorAlpha() {
+        return false;
+    }
+
+    /**
+     * Add a listener for local color changes.  Nulls and duplicates will be ignored.
+     *
+     * @param l The listener.
+     */
+    @Override
+    public void addLocalColorsListener(LocalColorsListener l) {
+    }
+
+    /**
+     * Remove a listener for local color changes.  Nulls will be ignored.
+     *
+     * @param l The listener.
+     */
+    @Override
+    public void removeLocalColorsListener(LocalColorsListener l) {
+    }
+
+    /**
+     * Add a listener for texture coordinate generation mode changes.
+     * Nulls and duplicates will be ignored.
+     *
+     * @param l The listener.
+     */
+    @Override
+    public void addTexCoordGenModeChanged(TexCoordGenModeListener l) {
+    }
+
+    /**
+     * Remove a listener for texture coordinate generation mode changes.
+     * Nulls will be ignored.
+     *
+     * @param l The listener.
+     */
+    @Override
+    public void removeTexCoordGenModeChanged(TexCoordGenModeListener l) {
+    }
+
+    /**
+     * Get the texture coordinate generation mode.  NULL is returned
+     * if the texture coordinates are not generated.
+     *
+     * @param setNum The set which this tex gen mode refers
+     * @return The mode or NULL
+     */
+    @Override
+    public String getTexCoordGenMode(int setNum) {
+        return null;
+    }
+
+    /**
+     * Set the number of textures that were found on the accompanying Appearance
+     * node. Used to set the number of texture coordinates that need to be
+     * passed in to the renderer when no explicit texture coordinates were
+     * given.
+     *
+     * @param count The number of texture coordinate sets to add
+     */
+    @Override
+    public void setTextureCount(int count) {
+    }
+
+    /**
+     * Get the number of texture coordinate sets contained by this node
+     *
+     * @return the number of texture coordinate sets
+     */
+    @Override
+    public int getNumSets() {
+        return 0;
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by VRMLGeometryNodeType
+    //----------------------------------------------------------
+
+    /**
+     * Get the value of the solid field.
+     *
+     * @return true This object is solid (ie single sided)
+     */
+    @Override
+    public boolean isSolid() {
+        return vfSolid;
+    }
+
+    /**
+     * Get the value of the CCW field. If the node does not have one, this will
+     * return true.
+     *
+     * @return true if the vertices are CCW ordered
+     */
+    @Override
+    public boolean isCCW() {
+        return true;
+    }
+
+    /**
+     * Specifies whether this node requires lighting.
+     *
+     * @return Should lighting be enabled
+     */
+    @Override
+    public boolean isLightingEnabled() {
+        return true;
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by VRMLNodeType
+    //----------------------------------------------------------
+
+    /**
+     * Get the index of the given field name. If the name does not exist for
+     * this node then return a value of -1.
+     *
+     * @param fieldName The name of the field we want the index from
+     * @return The index of the field name or -1
+     */
+    @Override
+    public int getFieldIndex(String fieldName) {
+        Integer index = fieldMap.get(fieldName);
+
+        return (index == null) ? -1 : index;
+    }
+
+    /**
+     * Get the list of indices that correspond to fields that contain nodes
+     * ie MFNode and SFNode). Used for blind scene graph traversal without
+     * needing to spend time querying for all fields etc. If a node does
+     * not have any fields that contain nodes, this shall return null. The
+     * field list covers all field types, regardless of whether they are
+     * readable or not at the VRML-level.
+     *
+     * @return The list of field indices that correspond to SF/MFnode fields
+     *    or null if none
+     */
+    @Override
+    public int[] getNodeFieldIndices() {
+        return nodeFields;
+    }
+
+    /**
+     * Get the declaration of the field at the given index. This allows for
+     * reverse lookup if needed. If the field does not exist, this will give
+     * a value of null.
+     *
+     * @param index The index of the field to get information
+     * @return A representation of this field's information
+     */
+    @Override
+    public VRMLFieldDeclaration getFieldDeclaration(int index) {
+        if(index < 0  || index > LAST_EXTRUSION_INDEX)
+            return null;
+
+        return fieldDecl[index];
+    }
+
+    /**
+     * Get the number of fields.
+     *
+     * @return The number of fields.
+     */
+    @Override
+    public int getNumFields() {
+        return fieldDecl.length;
+    }
+
+    /**
+     * Get the primary type of this node.  Replaces the instanceof mechanism
+     * for use in switch statements.
+     *
+     * @return The primary type
+     */
+    @Override
+    public int getPrimaryType() {
+        return TypeConstants.GeometryNodeType;
+    }
+
+    /**
+     * Get the value of a field. If the field is a primitive type, it will
+     * return a class representing the value. For arrays or nodes it will
+     * return the instance directly.
+     *
+     * @param index The index of the field to change.
+     * @return The class representing the field value
+     * @throws InvalidFieldException The field index is not known
+     */
+    @Override
+    public VRMLFieldData getFieldValue(int index)
+        throws InvalidFieldException {
+
+        VRMLFieldData fieldData = fieldLocalData.get();
+
+        fieldData.clear();
+
+        switch(index) {
+            case FIELD_BEGIN_CAP:
+                fieldData.booleanValue = vfBeginCap;
+                fieldData.dataType = VRMLFieldData.BOOLEAN_DATA;
+                break;
+
+            case FIELD_CCW:
+                fieldData.booleanValue = vfCCW;
+                fieldData.dataType = VRMLFieldData.BOOLEAN_DATA;
+                break;
+
+            case FIELD_CONVEX:
+                fieldData.booleanValue = vfConvex;
+                fieldData.dataType = VRMLFieldData.BOOLEAN_DATA;
+                break;
+
+            case FIELD_CREASE_ANGLE:
+                fieldData.floatValue = vfCreaseAngle;
+                fieldData.dataType = VRMLFieldData.FLOAT_DATA;
+                break;
+
+            case FIELD_CROSS_SECTION:
+                fieldData.floatArrayValues = vfCrossSection;
+                fieldData.numElements = numCrossSection;
+                fieldData.dataType = VRMLFieldData.FLOAT_ARRAY_DATA;
+                break;
+
+            case FIELD_END_CAP:
+                fieldData.booleanValue = vfEndCap;
+                fieldData.dataType = VRMLFieldData.BOOLEAN_DATA;
+                break;
+
+            case FIELD_ORIENTATION:
+                fieldData.floatArrayValues = vfOrientation;
+                fieldData.numElements = numOrientation;
+                fieldData.dataType = VRMLFieldData.FLOAT_ARRAY_DATA;
+                break;
+
+            case FIELD_SCALE:
+                fieldData.floatArrayValues = vfScale;
+                fieldData.numElements = numScale;
+                fieldData.dataType = VRMLFieldData.FLOAT_ARRAY_DATA;
+                break;
+
+            case FIELD_SOLID:
+                fieldData.booleanValue = vfSolid;
+                fieldData.dataType = VRMLFieldData.BOOLEAN_DATA;
+                break;
+
+            case FIELD_SPINE:
+                fieldData.floatArrayValues = vfSpine;
+                fieldData.numElements = numSpine;
+                fieldData.dataType = VRMLFieldData.FLOAT_ARRAY_DATA;
+                break;
+
+            default:
+                super.getFieldValue(index);
+        }
+
+        return fieldData;
+    }
+
+    /**
+     * Set the value of the field at the given index as an boolean. This would
+     * be used to set SFBool field types.
+     *
+     * @param index The index of destination field to set
+     * @param value The new value to use for the node
+     * @throws InvalidFieldException The field index is not known
+     * @throws InvalidFieldValueException The value provided is out of range
+     *    for the field type.
+     */
+    @Override
+    public void setValue(int index, boolean value)
+        throws InvalidFieldException, InvalidFieldValueException {
+
+
+        switch(index) {
+            case FIELD_BEGIN_CAP:
+                if(!inSetup)
+                    throwInitOnlyWriteException("beginCap");
+
+                vfBeginCap = value;
+                break;
+
+            case FIELD_CCW:
+                if(!inSetup)
+                    throwInitOnlyWriteException("ccw");
+
+                vfCCW = value;
+                break;
+
+            case FIELD_CONVEX:
+                if(!inSetup)
+                    throwInitOnlyWriteException("convex");
+
+                vfConvex = value;
+                break;
+
+            case FIELD_END_CAP:
+                if(!inSetup)
+                    throwInitOnlyWriteException("endCap");
+
+                vfEndCap = value;
+                break;
+
+            case FIELD_SOLID:
+                if(!inSetup)
+                    throwInitOnlyWriteException("solid");
+
+                vfSolid = value;
+                break;
+
+            default:
+                super.setValue(index, value);
+        }
+    }
+
+    /**
+     * Set the value of the field at the given index as a float. This would
+     * be used to set SFFloat field types.
+     *
+     * @param index The index of destination field to set
+     * @param value The new value to use for the node
+     * @throws InvalidFieldException The field index is not known
+     * @throws InvalidFieldValueException The value provided is out of range
+     *    for the field type.
+     */
+    @Override
+    public void setValue(int index, float value)
+        throws InvalidFieldException, InvalidFieldValueException {
+
+        switch(index)
+        {
+            case FIELD_CREASE_ANGLE:
+                if(!inSetup)
+                    throwInitOnlyWriteException("creaseAngle");
+
+                vfCreaseAngle = value;
+                break;
+
+            default:
+                super.setValue(index, value);
+        }
+    }
+
+    /**
+     * Set the value of the field at the given index as an array of floats.
+     * This would be used to set MFFloat, SFVec2f, SFVec3f and SFRotation
+     * field types.
+     *
+     * @param index The index of destination field to set
+     * @param value The new value to use for the node
+     * @param numValid The number of valid values to copy from the array
+     * @throws InvalidFieldException The field index is not known
+     * @throws InvalidFieldValueException The value provided is out of range
+     *    for the field type.
+     * @throws InvalidFieldAccessException The call is attempting to write to
+     *    a field that does not permit writing now
+     */
+    @Override
+    public void setValue(int index, float[] value, int numValid)
+        throws InvalidFieldException, InvalidFieldValueException,
+               InvalidFieldAccessException {
+
+        switch(index) {
+            case FIELD_CROSS_SECTION:
+                if(!inSetup)
+                    throwInitOnlyWriteException("crossSection");
+
+                vfCrossSection = value;
+                numCrossSection = numValid / 2;
+                break;
+
+            case FIELD_ORIENTATION:
+                if(!inSetup)
+                    throwInitOnlyWriteException("orientation");
+
+                vfOrientation = value;
+                numOrientation = numValid / 4;
+                break;
+
+            case FIELD_SCALE:
+                if(!inSetup)
+                    throwInitOnlyWriteException("scale");
+
+                vfScale = value;
+                numScale = numValid / 2;
+                break;
+
+            case FIELD_SPINE:
+                if(!inSetup)
+                    throwInitOnlyWriteException("spine");
+
+                vfSpine = value;
+                numSpine = numValid / 3;
+                break;
+
+            case FIELD_SET_CROSS_SECTION:
+                if(inSetup)
+                    throwInputOnlyWriteException("set_crossSection");
+
+                if(vfCrossSection.length < numValid)
+                    vfCrossSection = new float[numValid];
+
+                if(numValid != 0)
+                    System.arraycopy(value, 0, vfCrossSection, 0, numValid);
+
+                numCrossSection = numValid / 2;
+                break;
+
+            case FIELD_SET_ORIENTATION:
+                if(inSetup)
+                    throwInputOnlyWriteException("set_orientation");
+
+                if(vfOrientation.length < numValid)
+                    vfOrientation = new float[numValid];
+
+                if(numValid != 0)
+                    System.arraycopy(value, 0, vfOrientation, 0, numValid);
+
+                numOrientation = numValid / 4;
+                break;
+
+            case FIELD_SET_SCALE:
+                if(inSetup)
+                    throwInputOnlyWriteException("set_scale");
+
+                if(vfScale.length < numValid)
+                    vfScale = new float[numValid];
+
+                if(numValid != 0)
+                    System.arraycopy(value, 0, vfScale, 0, numValid);
+
+                numScale = numValid / 2;
+                break;
+
+            case FIELD_SET_SPINE:
+                if(inSetup)
+                    throwInputOnlyWriteException("set_spine");
+
+                if(vfSpine.length < numValid)
+                    vfSpine = new float[numValid];
+
+                if(numValid != 0)
+                    System.arraycopy(value, 0, vfSpine, 0, numValid);
+
+                numSpine = numValid / 3;
+                break;
+
+            default:
+                super.setValue(index, value, numValid);
+        }
+
+//        hasChanged[index] = true;
+//        fireFieldChanged(index);
+    }
+}
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geom3d/BaseIndexedFaceSet.java b/src/java/org/web3d/vrml/renderer/common/nodes/geom3d/BaseIndexedFaceSet.java
index 4ae5225d4ab904973ca9e1780249d53dc2db4c85..dfeff6d5f5c9c89df8d10a042c213cfe5ed1e041 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geom3d/BaseIndexedFaceSet.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geom3d/BaseIndexedFaceSet.java
@@ -26,7 +26,9 @@ import org.web3d.vrml.renderer.common.nodes.BaseIndexedGeometryNode;
 
 /**
  * An abstract implementation of an IndexedFaceSet
- * 
+ * <p>
+ *
+ *
  * @author Justin Couch
  * @version $Revision: 1.28 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoECParameters.java b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoECParameters.java
index 9a6fe8d9a5119fac28f3ed0c51b34ffc02eca4af..d89a4612a54796ee3120703ddc9987ab2ae64003 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoECParameters.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoECParameters.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.lang.*;
 
 /**
  * Common implementation of an GeoECParameters node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLCCParameters.java b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLCCParameters.java
index c4f6440370ccae3ac4365a397c6bd22f19449051..9328ccd9635012495da73373a790d32b4ddafe63 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLCCParameters.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLCCParameters.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.lang.*;
 
 /**
  * Common implementation of an GeoLCCParameters node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLCE3DParameters.java b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLCE3DParameters.java
index 37cb8428c6063394bba130588de6ae1adba66128..156665f1f1276050c2b16b02886054d70f47ee6f 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLCE3DParameters.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLCE3DParameters.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.lang.*;
 
 /**
  * Common implementation of an GeoLCE3DParameters node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLSR3DParameters.java b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLSR3DParameters.java
index dee6970176e9190cd5a246299ec117d2258dd7aa..d42d262a9c16c27ee710d1b37a862dbd9b725aef 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLSR3DParameters.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLSR3DParameters.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.lang.*;
 
 /**
  * Common implementation of an GeoLSR3DParameters node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLTSEParameters.java b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLTSEParameters.java
index ab71d720a8aa2044d92efc7c478c3e641f0e4ded..556e034c2138017213efe95869d2db00af67d6ab 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLTSEParameters.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLTSEParameters.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.lang.*;
 
 /**
  * Common implementation of an GeoLTSEParameters node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLocalTangentParameters.java b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLocalTangentParameters.java
index dfbd22bcc7e80b9573272bf627d8264bfe1cb09b..27056028af5d94b88cca187b4d16f36b2bfdec97 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLocalTangentParameters.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLocalTangentParameters.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.lang.*;
 
 /**
  * Common implementation of an GeoLocalTangentParameters node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLocation.java b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLocation.java
index 3548c2a5c31b592cf6a04c2faefff1d5a2f03dbb..64d68bc0819c37d8086274fafb9fe3aaf95f3c3a 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLocation.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoLocation.java
@@ -35,6 +35,7 @@ import org.xj3d.impl.core.eventmodel.OriginManagerFactory;
 
 /**
  * Common implementation of a GeoLocation node functionality.
+ * <p>
  *
  * @author Alan Hudson, Justin Couch
  * @version $Revision: 1.17 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoMParameters.java b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoMParameters.java
index a1f826031bd4bd669259656fee542b49f20add13..6f0eb4371cd8aa20492f687c04f9ddff594db508 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoMParameters.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoMParameters.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.lang.*;
 
 /**
  * Common implementation of an GeoMParameters node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoMetadata.java b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoMetadata.java
index 7a6203c9d2003a14d0437d3aa69f189b0ea69bba..e8ae23ebea55539e2396dd4d9daa0c3dbd8a3eb3 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoMetadata.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoMetadata.java
@@ -27,6 +27,7 @@ import org.web3d.vrml.renderer.common.nodes.AbstractNode;
 
 /**
  * Common implementation of an GeoMetadata node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoObliqueMercatorParameters.java b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoObliqueMercatorParameters.java
index e0bad2a9ec916288397a7154ddd28aacc2a43356..05cf3e1eba483c9480e7f6dad1f0ed6d6565c9dc 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoObliqueMercatorParameters.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoObliqueMercatorParameters.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.lang.*;
 
 /**
  * Common implementation of an GeoObliqueMercatorParameters node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoPSParameters.java b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoPSParameters.java
index 381657e14797d4a71653e53734555b559924a9b0..f4942061ecd5ff94ecaccd1347aedf2671e6014c 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoPSParameters.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoPSParameters.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.lang.*;
 
 /**
  * Common implementation of an GeoPSParameters node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoReferenceSurfaceInfo.java b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoReferenceSurfaceInfo.java
index 4f386bf1124c04cebcc56701cde81baa47df05f7..f792e218a48e34478d6f7637de87eb773cd2057c 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoReferenceSurfaceInfo.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoReferenceSurfaceInfo.java
@@ -26,6 +26,7 @@ import org.web3d.vrml.renderer.common.nodes.AbstractNode;
 
 /**
  * Common implementation of an GeoSRFParametersInfo node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoSRFInstance.java b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoSRFInstance.java
index d29dbf2d195e4ff43c42493ac996d240e0d13231..9655180977ea42d2a4febfd9fce4542454f52bb5 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoSRFInstance.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoSRFInstance.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.lang.*;
 
 /**
  * Common implementation of an GeoSRFInstance node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoSRFParametersInfo.java b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoSRFParametersInfo.java
index 16d5afb87cbda37ad3f9831214f52bc9a6e224dd..a5697123c29a20c5465474f4938a6ca9b16291b1 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoSRFParametersInfo.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoSRFParametersInfo.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.lang.*;
 
 /**
  * Common implementation of an GeoSRFParametersInfo node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoSRFParametersInfoNode.java b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoSRFParametersInfoNode.java
index 201fbb0caf944046b485dc82d27aadbb67d0c250..373547dbb61fae48f55f4a356b9444b45b0a4501 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoSRFParametersInfoNode.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoSRFParametersInfoNode.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.common.nodes.AbstractNode;
 
 /**
  * Common base implementation of the abstract node type X3DSRFParametersInfoNode node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoSRFSet.java b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoSRFSet.java
index 576598820b8dc6b96b7cb914ef36ec9a61afe2d0..28ba352676b1bccc2e0d76756b945e34d27d43e0 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoSRFSet.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoSRFSet.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.lang.*;
 
 /**
  * Common implementation of an GeoSRFSet node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoSRFTemplate.java b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoSRFTemplate.java
index 2dfb2f61f4631d9b2ce772e59c03a860ca5e365f..074de0c4d97c653a62a459bf6ea99532ea5cc81c 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoSRFTemplate.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoSRFTemplate.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.lang.*;
 
 /**
  * Common implementation of an GeoSRFTParametersInfo node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoTMParameters.java b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoTMParameters.java
index 65c0bc80ee0e0052e3264c9d7fb91d7cf5095f4f..cfbc50d7ffda87e6d35cb6ac5f51dc42bbafa8eb 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoTMParameters.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoTMParameters.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.lang.*;
 
 /**
  * Common implementation of an GeoTMParameters node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoTouchSensor.java b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoTouchSensor.java
index eed0d57112df24da7e12152b974b0a54120df82a..6a0cad1bfa6b7028acca3d718e66f6fd50c15630 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoTouchSensor.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/BaseGeoTouchSensor.java
@@ -36,6 +36,7 @@ import org.xj3d.impl.core.eventmodel.OriginManagerFactory;
 
 /**
  * Common base implementation of a GeoTouchSensor node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.13 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/ElevationGridGenerator.java b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/ElevationGridGenerator.java
index aa72f77baae77eb1e3f359f6a7fee6188992b917..5455a64597e612ca831672dd93c168cd1beae2e3 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/ElevationGridGenerator.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/ElevationGridGenerator.java
@@ -1,1741 +1,1741 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001-2004
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.renderer.common.nodes.geospatial;
-
-// External imports
-import org.j3d.geom.GeometryData;
-import org.j3d.geom.InvalidArraySizeException;
-import org.j3d.geom.UnsupportedTypeException;
-
-import org.opengis.referencing.operation.MathTransform;
-import org.opengis.referencing.operation.TransformException;
-
-// Local imports
-// None
-
-/**
- * A generator that takes a set of height values as a grid and turns it into
- * geometry suitable for local graphics projections.
- * <p>
- *
- * Points are defined in the height arrays in width first order. Normals, are
- * always smooth blended.
- * <p>
- *
- * Alan: There are some cases where texture generation is not complete.
- * Especially in regards to 3D textures.
- * <p>
- *
- * This class originally came from the j3d.org ElevationGridGenerator, but has
- * been mostly gutted and special cased for the needs of this system.
- *
- * @author Justin Couch
- * @version $Revision: 1.7 $
- */
-public class ElevationGridGenerator {
-
-    /** The default size of the terrain */
-    private static final float DEFAULT_SIZE = 100;
-
-    /** The default number of points in each direction */
-    private static final int DEFAULT_POINT_COUNT = 2;
-
-    /** The default base height of the terrain */
-    private static final float DEFAULT_HEIGHT = 2;
-
-    /** Current width of the terrain */
-    private double terrainWidth;
-
-    /** Depth of the terrain to generate */
-    private double terrainDepth;
-
-    /** Number of points in the width direction */
-    private int widthPoints;
-
-    /** Number of points in the depth direction */
-    private int depthPoints;
-
-    /** The yScale applied after coordinate conversion */
-    private float yScale;
-
-    /** The points to use as a 1D array. */
-    private double[] flatHeights;
-
-    /** The number of terrain coordinates in use */
-    private int numTerrainValues;
-
-    /** The number of texture coordinates in use */
-    private int numTexcoordValues;
-
-    /** The array holding all of the vertices during construction */
-    private float[] terrainCoordinates;
-
-    /** The array holding all of the normals during construction */
-    private float[] terrainNormals;
-
-    /** The array holding all of the texture coordinates during construction */
-    private float[] terrainTexcoords;
-
-    /** The number of quads in the terrain */
-    private int facetCount;
-
-    /** Utility class to supply the source coordinates for transformation */
-    private GeoPosition inPosition;
-
-    /** Utility class to fetch the output coordinates from transformation */
-    private GeoPosition outPosition;
-
-    /** work array to output normal generation into */
-    private float[] normal;
-
-    /** Are we calculating per vertex normals, hardcode for now */
-    private boolean perVertexNormals = true;
-
-    /**
-     * Construct a customized terrain according to the full set of configurable
-     * data.
-     *
-     * @param w The width of the terrain
-     * @param d The depth of the terrain
-     * @param wPnts The number of heights in the width
-     * @param dPnts The number of heights in the depth
-     * @param yScale y axix scalar
-     * @param heights The array of height values to use
-     * @throws IllegalArgumentException One of the points were &lt;= 1 or the
-     *   dimensions are non-positive
-     */
-    public ElevationGridGenerator(double w,
-                                  double d,
-                                  int wPnts,
-                                  int dPnts,
-                                  float yScale,
-                                  double[] heights)
-    {
-        if((wPnts < 2) || (dPnts < 2))
-            throw new IllegalArgumentException("Point count <= 1");
-
-        if((w <= 0) || (d <= 0))
-            throw new IllegalArgumentException("Dimension <= 0");
-
-        terrainWidth = w;
-        terrainDepth = d;
-        widthPoints = wPnts;
-        depthPoints = dPnts;
-        this.yScale = yScale;
-
-        facetCount = (depthPoints - 1) * (widthPoints - 1);
-
-        flatHeights = heights;
-
-        inPosition = new GeoPosition();
-        outPosition = new GeoPosition();
-        normal = new float[3];
-    }
-
-    /**
-     * Change the dimensions of the cone to be generated. Calling this will
-     * make the points be re-calculated next time you ask for geometry or
-     * normals.
-     *
-     * @param w The width of the terrain
-     * @param d The depth of the terrain
-     * @param wPnts The number of heights in the width
-     * @param dPnts The number of heights in the depth
-     * @throws IllegalArgumentException One of the points were &lt;= 1 or the
-     *   dimensions are non-positive
-     */
-    public void setDimensions(double w, double d, int wPnts, int dPnts)
-    {
-        if((terrainWidth != w) || (terrainDepth != d))
-        {
-            terrainDepth = d;
-            terrainWidth = w;
-        }
-
-        if((wPnts != widthPoints) || (dPnts != depthPoints))
-        {
-            widthPoints = wPnts;
-            depthPoints = dPnts;
-
-            facetCount = (depthPoints - 1) * (widthPoints - 1);
-        }
-    }
-
-    /**
-     * Set the details of the terrain height to use a flat array of values.
-     *
-     * @param heights The array of height values to use
-     */
-    public void setTerrainDetail(double[] heights)
-    {
-        flatHeights = heights;
-    }
-
-    /**
-     * Get the number of vertices that this generator will create for the
-     * shape given in the definition based on the current width and height
-     * information.
-     *
-     * @param indexed True if this is to be indexed triangle strips, false
-     *    otherwise
-     * @return The vertex count for the object
-     * @throws UnsupportedTypeException The generator cannot handle the type
-     *   of geometry you have requested.
-     */
-    public int getVertexCount(boolean indexed)
-    {
-        int ret_val;
-
-        if(indexed)
-            ret_val = facetCount * 2;
-        else
-            ret_val = widthPoints * 2 * (depthPoints - 1);
-
-        return ret_val;
-    }
-
-
-    /**
-     * Generate a new set of geometry items based on the passed data. If the
-     * data does not contain the right minimum array lengths an exception will
-     * be generated. If the array reference is null, this will create arrays
-     * of the correct length and assign them to the return value.
-     *
-     * @param data The data to base the calculations on
-     * @param transform The geodetic transformation needed
-     * @param gridOrigin The location of the SW corner of the grid
-     * @param localOrigin an origin offset if needed. Null if not
-     * @param indexed True if this is to be indexed triangle strips, false
-     *    otherwise
-     * @param creaseAngle angle over which we want to create separate normals
-     *   rather than smoothed normals
-     * @throws InvalidArraySizeException The array is not big enough to contain
-     *   the requested geometry
-     * @throws org.opengis.referencing.operation.TransformException
-     */
-    public void generate(GeometryData data,
-                         MathTransform transform,
-                         double[] gridOrigin,
-                         double[] localOrigin,
-                         boolean indexed,
-                         double creaseAngle)
-        throws InvalidArraySizeException, TransformException
-    {
-        if(indexed)
-            indexedTriangleStrips(data,
-                                  transform,
-                                  gridOrigin,
-                                  localOrigin,
-                                  creaseAngle);
-        else
-            triangleStrips(data,
-                           transform,
-                           gridOrigin,
-                           localOrigin,
-                           creaseAngle);
-
-    }
-
-    /**
-     * Generate indexed quads.
-     *
-     * @param data The data to base the calculations on
-     * @param transform The geodetic transformation needed
-     * @param gridOrigin The location of the SW corner of the grid
-     * @param localOrigin an origin offset if needed. Null if not
-     * @param indexed True if this is to be indexed triangle strips, false
-     *    otherwise
-     * @param creaseAngle angle over which we want to create separate normals
-     *   rather than smoothed normals
-     * @param vertex
-     * @throws InvalidArraySizeException The array is not big enough to contain
-     *   the requested geometry
-     * @throws org.opengis.referencing.operation.TransformException
-     */
-    public void generateIndexedQuads(GeometryData data,
-                         MathTransform transform,
-                         double[] gridOrigin,
-                         double[] localOrigin,
-                         boolean indexed,
-                         double creaseAngle, double[] vertex)
-        throws InvalidArraySizeException, TransformException {
-
-
-        int vtx_cnt = widthPoints * depthPoints;
-
-        if(data.coordinates == null)
-            data.coordinates = new float[vtx_cnt * 3];
-        else if(data.coordinates.length < vtx_cnt * 3)
-            throw new InvalidArraySizeException("Coordinates",
-                                                data.coordinates.length,
-                                                vtx_cnt * 3);
-
-        if(data.normals == null)
-            data.normals = new float[vtx_cnt * 3];
-        else if(data.normals.length < vtx_cnt * 3)
-            throw new InvalidArraySizeException("Normals",
-                                                data.normals.length,
-                                                vtx_cnt * 3);
-
-        if(data.textureCoordinates == null)
-            data.textureCoordinates = new float[vtx_cnt * 2];
-        else if(data.textureCoordinates.length < vtx_cnt * 2)
-            throw new InvalidArraySizeException("TextureCoordinates",
-                                                data.textureCoordinates.length,
-                                                vtx_cnt * 2);
-
-        int index_size = (widthPoints - 1) * ( depthPoints - 1 ) * 4;
-
-        if(data.indexes == null)
-            data.indexes = new int[index_size];
-        else if(data.indexes.length < index_size)
-            throw new InvalidArraySizeException("Indexes",
-                                                data.indexes.length,
-                                                index_size);
-
-        float[] coords = data.coordinates;
-        float[] texCoords = data.textureCoordinates;
-        float[] normals = data.normals;
-        data.vertexCount = vtx_cnt;
-
-        double w = gridOrigin[1];
-        double d = gridOrigin[0];
-        double width_inc = terrainWidth / (widthPoints - 1);
-        double depth_inc = terrainDepth / (depthPoints - 1);
-        float widthDiv = 1.0f/(  widthPoints - 1.0f );
-        float depthDiv = 1.0f/( depthPoints - 1.0f );
-
-        int count = 0;
-        int num = widthPoints * depthPoints;
-        int texIndex = 0;
-        double height;
-
-        if(localOrigin != null) {
-            int i = 0;
-            for(int z = 0; z < depthPoints; z++) {
-                for(int x = 0; x <widthPoints; x++) {
-                    i++;
-
-                    // Proposed behavior for missing values, issue warning?
-                    if (i > flatHeights.length)
-                        height = 0;
-                    else
-                        height = flatHeights[i - 1];
-
-                    inPosition.setPosition(d, w, height * yScale);
-
-                    transform.transform(inPosition, outPosition);
-
-                    double[] out = outPosition.getCoordinates();
-
-					vertex[count] = out[0];
-					vertex[count + 1] = out[1];
-					vertex[count + 2] = out[2];
-
-                    coords[count] = (float)(out[0] - localOrigin[0]);
-                    coords[count + 1] = (float)(out[1] - localOrigin[1]);
-                    coords[count + 2] = (float)(out[2] - localOrigin[2]);
-                    texCoords[texIndex++] = x * widthDiv;
-                    texCoords[texIndex++] = z * depthDiv;
-
-                    count += 3;
-                    w += width_inc;
-
-                    if(((i % (widthPoints)) == 0)) {
-                        d += depth_inc;
-                        w = gridOrigin[1];
-                    }
-                }
-            }
-        } else {
-            int i = 0;
-
-            for(int z = 0; z < depthPoints; z++) {
-                for(int x = 0; x <widthPoints; x++) {
-                    i++;
-                    // Proposed behavior for missing values, issue warning?
-                    if (i > flatHeights.length)
-                        height = 0;
-                    else
-                        height = flatHeights[i - 1];
-
-                    inPosition.setPosition(d, w, height * yScale);
-
-                    transform.transform(inPosition, outPosition);
-
-                    double[] out = outPosition.getCoordinates();
-
-					vertex[count] = out[0];
-					vertex[count + 1] = out[1];
-					vertex[count + 2] = out[2];
-
-                    coords[count] = (float)out[0];
-                    coords[count + 1] = (float)out[1];
-                    coords[count + 2] = (float)out[2];
-
-                    texCoords[texIndex++] =  (x * widthDiv);
-                    texCoords[texIndex++] =  (z * depthDiv);
-                    count += 3;
-
-                    w += width_inc;
-
-                    if(((i % (widthPoints)) == 0)) {
-                        d += depth_inc;
-                        w = gridOrigin[1];
-                    }
-
-                }
-            }
-        }
-
-
-        int index = 0;
-        int[] values = data.indexes;
-        data.indexesCount = data.indexes.length;
-
-//System.out.println("depth: " + depthPoints + " widthPoints: " + widthPoints);
-        for ( int z = 0; z < depthPoints - 1; z++ ) {
-            for ( int x = 0; x < widthPoints - 1; x++ ) {
-                values[index]   = x + z * widthPoints;
-                values[index+1] = values[index] + 1;
-                values[index+2] = values[index+1] + widthPoints;
-                values[index+3] = values[index+2] - 1;
-/*
-      System.out.println( "Poly: " + values[index] + " " +values[index+1] +
-                  " " + values[index+2] + " " + values[index+3] +
-                  "  (" + x + "," + z + ": " + index + ")" );
-*/
-
-                index += 4;
-            }
-        }
-
-        regenerateNormals(data.coordinates, data.normals);
-    }
-
-    /**
-     * Generate a new set of points for a triangle strip array. There is one
-     * strip for the side and one strip each for the ends.
-     *
-     * @param data The data to base the calculations on
-     * @param transform The geodetic transformation needed
-     * @param gridOrigin The location of the SW corner of the grid
-     * @param localOrigin an origin offset if needed. Null if not
-     * @param creaseAngle angle over which we want to create separate normals
-     *   rather than smoothed normals
-     * @throws InvalidArraySizeException The array is not big enough to contain
-     *   the requested geometry
-     */
-    private void triangleStrips(GeometryData data,
-                                MathTransform transform,
-                                double[] gridOrigin,
-                                double[] localOrigin,
-                                double creaseAngle)
-        throws InvalidArraySizeException, TransformException
-    {
-        generateUnindexedTriStripCoordinates(data,
-                                             transform,
-                                             gridOrigin,
-                                             localOrigin);
-
-        if((data.geometryComponents & GeometryData.NORMAL_DATA) != 0)
-            generateUnindexedTriStripNormals(data);
-
-        if((data.geometryComponents & GeometryData.TEXTURE_2D_DATA) != 0)
-            generateUnindexedTriStripTexture2D(data);
-        else if((data.geometryComponents & GeometryData.TEXTURE_3D_DATA) != 0)
-            generateTriTexture3D(data);
-
-        int num_strips = depthPoints - 1;
-        data.numStrips = num_strips;
-
-        if(data.stripCounts == null)
-            data.stripCounts = new int[num_strips];
-        else if(data.stripCounts.length < num_strips)
-            throw new InvalidArraySizeException("Strip counts",
-                                                data.stripCounts.length,
-                                                num_strips);
-
-        for(int i = num_strips; --i >= 0; )
-            data.stripCounts[i] = widthPoints * 2;
-    }
-
-    /**
-     * Generates new set of unindexed points for triangles strips. The array
-     * consists of one strip per width row.
-     *
-     * @param data The data to base the calculations on
-     * @param transform The geodetic transformation needed
-     * @param gridOrigin The location of the SW corner of the grid
-     * @param localOrigin an origin offset if needed. Null if not
-     * @throws InvalidArraySizeException The array is not big enough to contain
-     *   the requested geometry
-     */
-    private void generateUnindexedTriStripCoordinates(GeometryData data,
-                                                      MathTransform transform,
-                                                      double[] gridOrigin,
-                                                      double[] localOrigin)
-        throws InvalidArraySizeException, TransformException
-    {
-        int vtx_cnt = widthPoints * (depthPoints - 1) * 2;
-        if(data.coordinates == null)
-            data.coordinates = new float[vtx_cnt * 3];
-        else if(data.coordinates.length < vtx_cnt * 3)
-            throw new InvalidArraySizeException("Coordinates",
-                                                data.coordinates.length,
-                                                vtx_cnt * 3);
-
-        float[] coords = data.coordinates;
-        data.vertexCount = vtx_cnt;
-
-        numTerrainValues = widthPoints * depthPoints * 3;
-        terrainCoordinates = new float[numTerrainValues];
-
-        double d = gridOrigin[0];
-        double w = gridOrigin[1];
-        double width_inc = terrainWidth / (widthPoints - 1);
-        double depth_inc = terrainDepth / (depthPoints - 1);
-
-        if (perVertexNormals) {
-            terrainNormals = new float[coords.length];
-        }
-
-        int count = 0;
-        int tc_count = 0;
-        int num = widthPoints * (depthPoints - 1);
-
-        // TODO: All of the coordinates are -x,-z to align with GeoLocation and GeoCoordinate
-        // note sure why this is needed.
-
-        if(localOrigin != null) {
-            for(int i = 1; i <= num; i++) {
-                inPosition.setPosition(d + depth_inc,
-                                       w,
-                                       flatHeights[i + widthPoints - 1] * yScale);
-
-                transform.transform(inPosition, outPosition);
-
-                double[] out = outPosition.getCoordinates();
-                coords[count] = -(float)(out[0] - localOrigin[0]);
-                coords[count + 1] = (float)(out[1] - localOrigin[1]);
-                coords[count + 2] = -(float)(out[2] - localOrigin[2]);
-
-                if (perVertexNormals) {
-                    double x = out[0];
-                    double y = out[1];
-                    double z = out[2];
-
-                    double mag = x * x + y * y + z * z;
-
-                    if(mag != 0.0)
-                    {
-                        mag = 1.0 / Math.sqrt(mag);
-                        terrainNormals[count] = (float) (x * mag);
-                        terrainNormals[count + 1] = (float) (y * mag);
-                        terrainNormals[count + 2] = (float) (z * mag);
-                    }
-                    else
-                    {
-                        terrainNormals[count] = 0;
-                        terrainNormals[count + 1] = 1;
-                        terrainNormals[count + 2] = 0;
-                    }
-                }
-
-                // update the first row from data calculated. Otherwise, always
-                // take the next row's worth of data.
-                if(d == 0) {
-                    terrainCoordinates[tc_count] = coords[count];
-                    terrainCoordinates[tc_count + 1] = coords[count + 1];
-                    terrainCoordinates[tc_count + 2] = coords[count + 2];
-                    tc_count += 3;
-                }
-
-                inPosition.setPosition(d, w, flatHeights[i - 1] * yScale);
-
-                transform.transform(inPosition, outPosition);
-
-                out = outPosition.getCoordinates();
-
-                if (perVertexNormals) {
-                    double x = out[0];
-                    double y = out[1];
-                    double z = out[2];
-
-                    double mag = x * x + y * y + z * z;
-
-                    if(mag != 0.0)
-                    {
-                        mag = 1.0 / Math.sqrt(mag);
-                        terrainNormals[count + 3] = (float) (x * mag);
-                        terrainNormals[count + 4] = (float) (y * mag);
-                        terrainNormals[count + 5] = (float) (z * mag);
-                    }
-                    else
-                    {
-                        terrainNormals[count + 3] = 0;
-                        terrainNormals[count + 4] = 1;
-                        terrainNormals[count + 5] = 0;
-                    }
-                }
-
-                coords[count + 3] = -(float)(out[0] - localOrigin[0]);
-                coords[count + 4] = (float)(out[1] - localOrigin[1]);
-                coords[count + 5] = -(float)(out[2] - localOrigin[2]);
-
-                terrainCoordinates[tc_count] = coords[count + 3];
-                terrainCoordinates[tc_count + 1] = coords[count + 4];
-                terrainCoordinates[tc_count + 2] = coords[count + 5];
-
-                count += 6;
-                tc_count += 3;
-
-                w += width_inc;
-
-                if(((i % (widthPoints)) == 0))
-                {
-                    d += depth_inc;
-                    w = 0;
-                }
-            }
-        } else {
-System.out.println("*** EG no origin: " + num);
-            for(int i = 1; i <= num; i++) {
-                inPosition.setPosition(d + depth_inc,
-                                       w,
-                                       flatHeights[i + widthPoints - 1] * yScale);
-
-                transform.transform(inPosition, outPosition);
-
-                double[] out = outPosition.getCoordinates();
-
-
-                coords[count] = -(float)out[0];
-                coords[count + 1] = (float)out[1];
-                coords[count + 2] = -(float)out[2];
-
-System.out.println("out1: " + out[0] + " " + out[1] + " " + out[2]);
-/*
-                coords[count] = -(float)out[0];
-                coords[count + 1] = (float)out[1];
-                coords[count + 2] = -(float)out[2];
-*/
-                if (perVertexNormals) {
-                    double x = out[0];
-                    double y = out[1];
-                    double z = out[2];
-
-                    double mag = x * x + y * y + z * z;
-
-                    if(mag != 0.0)
-                    {
-                        mag = 1.0 / Math.sqrt(mag);
-                        terrainNormals[count] = (float) (x * mag);
-                        terrainNormals[count + 1] = (float) (y * mag);
-                        terrainNormals[count + 2] = (float) (z * mag);
-                    }
-                    else
-                    {
-                        terrainNormals[count] = 0;
-                        terrainNormals[count + 1] = 1;
-                        terrainNormals[count + 2] = 0;
-                    }
-                }
-
-                // update the first row from data calculated. Otherwise, always
-                // take the next row's worth of data.
-                if(d == 0) {
-                    terrainCoordinates[tc_count] = coords[count];
-                    terrainCoordinates[tc_count + 1] = coords[count + 1];
-                    terrainCoordinates[tc_count + 2] = coords[count + 2];
-                    tc_count += 3;
-                }
-
-                inPosition.setPosition(d, w, flatHeights[i - 1] * yScale);
-
-                transform.transform(inPosition, outPosition);
-
-                out = outPosition.getCoordinates();
-System.out.println("out2: " + out[0] + " " + out[1] + " " + out[2]);
-
-
-                coords[count + 3] = -(float)out[0];
-                coords[count + 4] = (float)out[1];
-                coords[count + 5] = -(float)out[2];
-/*
-                coords[count + 3] = -(float)out[0];
-                coords[count + 4] = (float)out[1];
-                coords[count + 5] = -(float)out[2];
-*/
-                if (perVertexNormals) {
-                    double x = out[0];
-                    double y = out[1];
-                    double z = out[2];
-
-                    double mag = x * x + y * y + z * z;
-
-                    if(mag != 0.0)
-                    {
-                        mag = 1.0 / Math.sqrt(mag);
-                        terrainNormals[count + 3] = (float) (x * mag);
-                        terrainNormals[count + 4] = (float) (y * mag);
-                        terrainNormals[count + 5] = (float) (z * mag);
-                    }
-                    else
-                    {
-                        terrainNormals[count + 3] = 0;
-                        terrainNormals[count + 4] = 1;
-                        terrainNormals[count + 5] = 0;
-                    }
-                }
-
-                terrainCoordinates[tc_count] = coords[count + 3];
-                terrainCoordinates[tc_count + 1] = coords[count + 4];
-                terrainCoordinates[tc_count + 2] = coords[count + 5];
-
-                count += 6;
-                tc_count += 3;
-
-                w += width_inc;
-
-                if(((i % (widthPoints)) == 0))
-                {
-                    d += depth_inc;
-                    w = 0;
-                }
-            }
-        }
-
-
-    }
-
-    /**
-     * Generate a new set of normals for a normal set of unindexed points.
-     * Smooth normals are used for the sides at the average between the faces.
-     * Bottom normals always point down.
-     * <p>
-     * This must always be called after the coordinate generation.
-     *
-     * @param data The data to base the calculations on
-     * @throws InvalidArraySizeException The array is not big enough to contain
-     *   the requested geometry
-     */
-    private void generateUnindexedTriStripNormals(GeometryData data)
-        throws InvalidArraySizeException
-    {
-        int vtx_cnt = data.vertexCount * 3;
-
-        if(data.normals == null)
-            data.normals = new float[vtx_cnt];
-        else if(data.normals.length < vtx_cnt)
-            throw new InvalidArraySizeException("Normals",
-                                                data.normals.length,
-                                                vtx_cnt);
-
-        regenerateNormals();
-
-        int i;
-        float[] normals = data.normals;
-        int count = 0;
-        int base_count = 0;
-        int width_inc = widthPoints * 3;
-        int total_points = widthPoints * (depthPoints - 1);
-
-        if (!perVertexNormals) {
-            // Start of with one less row (width) here because we don't have two
-            // sets of coordinates for those.
-            for(i = total_points; --i >= 0; )
-            {
-                normals[count++] = terrainNormals[base_count];
-                normals[count++] = terrainNormals[base_count + 1];
-                normals[count++] = terrainNormals[base_count + 2];
-
-                normals[count++] = terrainNormals[base_count + width_inc];
-                normals[count++] = terrainNormals[base_count + width_inc + 1];
-                normals[count++] = terrainNormals[base_count + width_inc + 2];
-
-                base_count += 3;
-            }
-        } else {
-            // Straight copy of generated normals
-            int len2 = terrainNormals.length;
-
-            for(i=0; i < len2; i++) {
-                normals[i] = terrainNormals[i];
-            }
-        }
-    }
-
-    /**
-     * Generates new set of unindexed texture coordinates for triangles strips.
-     * The array consists of one strip per width row.
-     *
-     * @param data The data to base the calculations on
-     * @throws InvalidArraySizeException The array is not big enough to contain
-     *   the requested geometry
-     */
-    private void generateUnindexedTriStripTexture2D(GeometryData data)
-        throws InvalidArraySizeException
-    {
-        int vtx_cnt = widthPoints * (depthPoints - 1) * 2;
-
-        if(data.textureCoordinates == null)
-            data.textureCoordinates = new float[vtx_cnt * 2];
-        else if(data.textureCoordinates.length < vtx_cnt * 2)
-            throw new InvalidArraySizeException("Coordinates",
-                                                data.textureCoordinates.length,
-                                                vtx_cnt * 2);
-
-        float[] coords = data.textureCoordinates;
-
-        regenerateTexcoords();
-
-        int i;
-        int count = 0;
-        int base_count = 0;
-        int width_inc = widthPoints * 2;
-        int total_points = widthPoints * (depthPoints - 1);
-
-        // Start of with one less row (width) here because we don't have two
-        // sets of coordinates for those.
-        for(i = total_points; --i >= 0; )
-        {
-            coords[count++] = terrainTexcoords[base_count + width_inc];
-            coords[count++] = terrainTexcoords[base_count + width_inc + 1];
-            coords[count++] = terrainTexcoords[base_count];
-            coords[count++] = terrainTexcoords[base_count + 1];
-
-            base_count += 2;
-        }
-    }
-
-    // Indexed generation routines
-
-    /**
-     * Generate a new set of points for an indexed triangle strip array. We
-     * build the strip from the existing points starting by working around the
-     * side and then doing the top and bottom. To create the ends we start at
-     * on radius point and then always refer to the center for each second
-     * item. This wastes every second triangle as a degenerate triangle, but
-     * the gain is less strips needing to be transmitted - ie less memory
-     * usage.
-     *
-     * @param data The data to base the calculations on
-     * @param transform The geodetic transformation needed
-     * @param gridOrigin The location of the SW corner of the grid
-     * @param localOrigin an origin offset if needed. Null if not
-     * @param creaseAngle angle over which we want to create separate normals
-     *   rather than smoothed normals
-     * @throws InvalidArraySizeException The array is not big enough to contain
-     *   the requested geometry
-     */
-    private void indexedTriangleStrips(GeometryData data,
-                                       MathTransform transform,
-                                       double[] gridOrigin,
-                                       double[] localOrigin,
-                                       double creaseAngle)
-        throws InvalidArraySizeException, TransformException {
-
-        generateIndexedCoordinates(data, transform, gridOrigin, localOrigin);
-
-        if((data.geometryComponents & GeometryData.NORMAL_DATA) != 0)
-            generateIndexedNormals(data);
-
-        if((data.geometryComponents & GeometryData.TEXTURE_2D_DATA) != 0)
-            generateTriTexture2D(data);
-        else if((data.geometryComponents & GeometryData.TEXTURE_3D_DATA) != 0)
-            generateTriTexture3D(data);
-
-        // now let's do the index list
-        int index_size = widthPoints * (depthPoints - 1) * 2;
-        int num_strips = depthPoints - 1;
-
-        if(data.indexes == null)
-            data.indexes = new int[index_size];
-        else if(data.indexes.length < index_size)
-            throw new InvalidArraySizeException("Indexes",
-                                                data.indexes.length,
-                                                index_size);
-
-        if(data.stripCounts == null)
-            data.stripCounts = new int[num_strips];
-        else if(data.stripCounts.length < num_strips)
-            throw new InvalidArraySizeException("Strip counts",
-                                                data.stripCounts.length,
-                                                num_strips);
-
-        int[] indexes = data.indexes;
-        int[] stripCounts = data.stripCounts;
-        data.indexesCount = index_size;
-        data.numStrips = num_strips;
-        int idx = 0;
-        int vtx = 0;
-        int total_points = widthPoints * (depthPoints - 1);
-
-        // The side is one big strip
-        for(int i = total_points; --i >= 0; ) {
-            indexes[idx++] = vtx;
-            indexes[idx++] = vtx + widthPoints;
-
-            vtx++;
-        }
-
-        for(int i = num_strips; --i >= 0; )
-            stripCounts[i] = widthPoints * 2;
-    }
-
-    /**
-     * Generates new set of indexed points for triangles or quads. The array
-     * consists of the side coordinates, followed by the center for top, then
-     * its points then the bottom center and its points. We do this as they
-     * use a completely different set of normals. The side
-     * coordinates are interleaved as top and then bottom values.
-     *
-     * @param data The data to base the calculations on
-     * @param transform The geodetic transformation needed
-     * @param gridOrigin The location of the SW corner of the grid
-     * @param localOrigin an origin offset if needed. Null if not
-     * @throws InvalidArraySizeException The array is not big enough to contain
-     *   the requested geometry
-     */
-    private void generateIndexedCoordinates(GeometryData data,
-                                            MathTransform transform,
-                                            double[] gridOrigin,
-                                            double[] localOrigin)
-        throws InvalidArraySizeException, TransformException {
-
-        int vtx_cnt = widthPoints * depthPoints;
-
-        if(data.coordinates == null)
-            data.coordinates = new float[vtx_cnt * 3];
-        else if(data.coordinates.length < vtx_cnt * 3)
-            throw new InvalidArraySizeException("Coordinates",
-                                                data.coordinates.length,
-                                                vtx_cnt * 3);
-
-        float[] coords = data.coordinates;
-        data.vertexCount = vtx_cnt;
-
-        double d = gridOrigin[0];
-        double w = gridOrigin[1];
-        double width_inc = terrainWidth / (widthPoints - 1);
-        double depth_inc = terrainDepth / (depthPoints - 1);
-
-        int count = 0;
-        int num = widthPoints * depthPoints;
-
-        if(localOrigin != null) {
-            for(int i = 1; i <= num; i++) {
-                inPosition.setPosition(w, flatHeights[i - 1], d);
-
-                transform.transform(inPosition, outPosition);
-
-                double[] out = outPosition.getCoordinates();
-
-                coords[count] = (float)(out[0] - localOrigin[0]);
-                coords[count + 1] = (float)(out[1] - localOrigin[1]);
-                coords[count + 2] = (float)(out[2] - localOrigin[2]);
-
-                count += 3;
-
-                w += width_inc;
-
-                if(((i % (widthPoints)) == 0)) {
-                    d += depth_inc;
-                    w = 0;
-                }
-            }
-        } else {
-            for(int i = 1; i <= num; i++) {
-                inPosition.setPosition(w, flatHeights[i - 1], d);
-
-                transform.transform(inPosition, outPosition);
-
-                double[] out = outPosition.getCoordinates();
-
-                coords[count] = (float)out[0];
-                coords[count + 1] = (float)out[1];
-                coords[count + 2] = (float)out[2];
-
-                count += 3;
-
-                w += width_inc;
-
-                if(((i % (widthPoints)) == 0)) {
-                    d += depth_inc;
-                    w = 0;
-                }
-            }
-        }
-    }
-
-    /**
-     * Generate a new set of normals for a normal set of indexed points.
-     * Smooth normals are used for the sides at the average between the faces.
-     * Bottom normals always point down.
-     * <p>
-     * This must always be called after the coordinate generation.
-     *
-     * @param data The data to base the calculations on
-     * @throws InvalidArraySizeException The array is not big enough to contain
-     *   the requested geometry
-     */
-    private void generateIndexedNormals(GeometryData data)
-        throws InvalidArraySizeException
-    {
-        int vtx_cnt = data.vertexCount * 3;
-
-        if(data.normals == null)
-            data.normals = new float[vtx_cnt];
-        else if(data.normals.length < vtx_cnt)
-            throw new InvalidArraySizeException("Normals",
-                                                data.normals.length,
-                                                vtx_cnt);
-
-        regenerateNormals();
-
-        System.arraycopy(terrainNormals, 0, data.normals, 0, numTerrainValues);
-    }
-
-    /**
-     * Generate a new set of texCoords for a set of unindexed points.
-     * <p>
-     * This must always be called after the coordinate generation.
-     *
-     * @param data The data to base the calculations on
-     * @throws InvalidArraySizeException The array is not big enough to contain
-     *   the requested geometry
-     */
-    private void generateTriTexture2D(GeometryData data)
-        throws InvalidArraySizeException
-    {
-        int vtx_cnt = data.vertexCount * 2;
-
-        if(data.textureCoordinates == null)
-            data.textureCoordinates = new float[vtx_cnt];
-        else if(data.textureCoordinates.length < vtx_cnt)
-            throw new InvalidArraySizeException("2D Texture coordinates",
-                                                data.textureCoordinates.length,
-                                                vtx_cnt);
-
-        regenerateTexcoords();
-
-        System.out.println("Unhandled textured generation case in " +
-            "ElevationGridGenerator");
-    }
-
-
-    /**
-     * Generate a new set of texCoords for a set of unindexed points.
-     * <p>
-     * This must always be called after the coordinate generation.
-     *
-     * @param data The data to base the calculations on
-     * @throws InvalidArraySizeException The array is not big enough to contain
-     *   the requested geometry
-     */
-    private void generateTriTexture3D(GeometryData data)
-        throws InvalidArraySizeException
-    {
-        int vtx_cnt = data.vertexCount * 2;
-
-        if(data.textureCoordinates == null)
-            data.textureCoordinates = new float[vtx_cnt];
-        else if(data.textureCoordinates.length < vtx_cnt)
-            throw new InvalidArraySizeException("3D Texture coordinates",
-                                                data.textureCoordinates.length,
-                                                vtx_cnt);
-
-        float[] texCoords = data.textureCoordinates;
-
-        System.out.println("Unhandled textured generation case in " +
-            "ElevationGridGenerator");
-    }
-
-    /**
-     * Regenerate the base normals points. These are the flat circle that
-     * makes up the base of the code. The normals are generated based the
-     * smoothing of normal averages for interior points. Around the edges,
-     * we use the average of the edge value polygons.
-     */
-    private void regenerateNormals()
-    {
-        // Already calculated?
-        if (perVertexNormals)
-            return;
-
-        // This code has been changed around to go from left to right instead
-        // of bottom to top, but it hasn't been tested.
-        terrainNormals = new float[numTerrainValues];
-
-        int count = 0;
-        int base_count;
-        int i, j;
-        int depth_inc = depthPoints * 3;
-
-        // The first edge
-        // corner point - normal based on only that face
-
-        createFaceNormal(terrainCoordinates, depth_inc, 0, 3);
-
-        terrainNormals[count] = normal[0];
-        terrainNormals[count + 1] = normal[1];
-        terrainNormals[count + 2] = normal[2];
-
-        count = 3;
-        base_count = 3;
-
-        for(i = 1; i < (depthPoints - 1); i++)
-        {
-            calcSideAverageNormal(terrainCoordinates,
-                                  base_count,
-                                  base_count + 3,
-                                  base_count + depth_inc,
-                                  base_count - 3);
-
-            terrainNormals[count] = normal[0];
-            terrainNormals[count + 1] = normal[1];
-            terrainNormals[count + 2] = normal[2];
-
-            count += 3;
-            base_count += 3;
-        }
-
-        // Last corner point of the first row
-        createFaceNormal(terrainCoordinates,
-                         base_count,
-                         base_count + depth_inc,
-                         base_count - 3);
-
-        terrainNormals[count] = normal[0];
-        terrainNormals[count + 1] = normal[1];
-        terrainNormals[count + 2] = normal[2];
-
-        count += 3;
-        base_count += 3;
-
-        // Now, process all of the internal points
-        for(i = 1; i < (widthPoints - 1); i++)
-        {
-
-            calcSideAverageNormal(terrainCoordinates,
-                                  base_count,
-                                  base_count - depth_inc,
-                                  base_count + 3,
-                                  base_count + depth_inc);
-
-            terrainNormals[count] = normal[0];
-            terrainNormals[count + 1] = normal[1];
-            terrainNormals[count + 2] = normal[2];
-
-            base_count += 3;
-            count += 3;
-
-            for(j = 1; j < (depthPoints - 1); j++)
-            {
-
-                calcQuadAverageNormal(terrainCoordinates,
-                                      base_count,
-                                      base_count + 3,
-                                      base_count + depth_inc,
-                                      base_count - 3,
-                                      base_count - depth_inc);
-
-                terrainNormals[count] = normal[0];
-                terrainNormals[count + 1] = normal[1];
-                terrainNormals[count + 2] = normal[2];
-
-                base_count += 3;
-                count += 3;
-            }
-
-            // Last point of the row
-            calcSideAverageNormal(terrainCoordinates,
-                                  base_count,
-                                  base_count + depth_inc,
-                                  base_count - 3,
-                                  base_count - depth_inc);
-
-            terrainNormals[count] = normal[0];
-            terrainNormals[count + 1] = normal[1];
-            terrainNormals[count + 2] = normal[2];
-
-            base_count += 3;
-            count += 3;
-        }
-
-        // The last edge
-        // corner point - normal based on only that face
-        createFaceNormal(terrainCoordinates,
-                         base_count,
-                         base_count - depth_inc,
-                         base_count + 3);
-
-        terrainNormals[count] = normal[0];
-        terrainNormals[count + 1] = normal[1];
-        terrainNormals[count + 2] = normal[2];
-
-        base_count += 3;
-        count += 3;
-
-        for(i = 1; i < (depthPoints - 1); i++)
-        {
-            calcSideAverageNormal(terrainCoordinates,
-                                  base_count,
-                                  base_count - 3,
-                                  base_count - depth_inc,
-                                  base_count + 3);
-
-            terrainNormals[count] = normal[0];
-            terrainNormals[count + 1] = normal[1];
-            terrainNormals[count + 2] = normal[2];
-
-            base_count += 3;
-            count += 3;
-        }
-
-        // Last corner point of the first row
-        createFaceNormal(terrainCoordinates,
-                         base_count,
-                         base_count - 3,
-                         base_count - depth_inc);
-
-        terrainNormals[count] = normal[0];
-        terrainNormals[count + 1] = normal[1];
-        terrainNormals[count + 2] = normal[2];
-    }
-
-    // This is the original bottom to top code
-/*
-    private final void regenerateNormals()
-    {
-        terrainNormals = new float[numTerrainValues];
-
-        int count = 0;
-        int base_count = 0;
-        int i, j;
-        int width_inc = widthPoints * 3;
-
-        // The first edge
-        // corner point - normal based on only that face
-
-        createFaceNormal(terrainCoordinates, width_inc, 0, 3);
-
-        terrainNormals[count] = normal[0];
-        terrainNormals[count + 1] = normal[1];
-        terrainNormals[count + 2] = normal[2];
-
-        count = 3;
-        base_count = 3;
-
-        for(i = 1; i < (widthPoints - 1); i++)
-        {
-            calcSideAverageNormal(terrainCoordinates,
-                                  base_count,
-                                  base_count + 3,
-                                  base_count + width_inc,
-                                  base_count - 3);
-
-            terrainNormals[count] = normal[0];
-            terrainNormals[count + 1] = normal[1];
-            terrainNormals[count + 2] = normal[2];
-
-            count += 3;
-            base_count += 3;
-        }
-
-        // Last corner point of the first row
-        createFaceNormal(terrainCoordinates,
-                         base_count,
-                         base_count + width_inc,
-                         base_count - 3);
-
-        terrainNormals[count] = normal[0];
-        terrainNormals[count + 1] = normal[1];
-        terrainNormals[count + 2] = normal[2];
-
-        count += 3;
-        base_count += 3;
-
-        // Now, process all of the internal points
-        for(i = 1; i < (depthPoints - 1); i++)
-        {
-
-            calcSideAverageNormal(terrainCoordinates,
-                                  base_count,
-                                  base_count - width_inc,
-                                  base_count + 3,
-                                  base_count + width_inc);
-
-            terrainNormals[count] = normal[0];
-            terrainNormals[count + 1] = normal[1];
-            terrainNormals[count + 2] = normal[2];
-
-            base_count += 3;
-            count += 3;
-
-            for(j = 1; j < (widthPoints - 1); j++)
-            {
-
-                calcQuadAverageNormal(terrainCoordinates,
-                                      base_count,
-                                      base_count + 3,
-                                      base_count + width_inc,
-                                      base_count - 3,
-                                      base_count - width_inc);
-
-                terrainNormals[count] = normal[0];
-                terrainNormals[count + 1] = normal[1];
-                terrainNormals[count + 2] = normal[2];
-
-                base_count += 3;
-                count += 3;
-            }
-
-            // Last point of the row
-            calcSideAverageNormal(terrainCoordinates,
-                                  base_count,
-                                  base_count + width_inc,
-                                  base_count - 3,
-                                  base_count - width_inc);
-
-            terrainNormals[count] = normal[0];
-            terrainNormals[count + 1] = normal[1];
-            terrainNormals[count + 2] = normal[2];
-
-            base_count += 3;
-            count += 3;
-        }
-
-        // The last edge
-        // corner point - normal based on only that face
-        createFaceNormal(terrainCoordinates,
-                         base_count,
-                         base_count - width_inc,
-                         base_count + 3);
-
-        terrainNormals[count] = normal[0];
-        terrainNormals[count + 1] = normal[1];
-        terrainNormals[count + 2] = normal[2];
-
-        base_count += 3;
-        count += 3;
-
-        for(i = 1; i < (widthPoints - 1); i++)
-        {
-            calcSideAverageNormal(terrainCoordinates,
-                                  base_count,
-                                  base_count - 3,
-                                  base_count - width_inc,
-                                  base_count + 3);
-
-            terrainNormals[count] = normal[0];
-            terrainNormals[count + 1] = normal[1];
-            terrainNormals[count + 2] = normal[2];
-
-            base_count += 3;
-            count += 3;
-        }
-
-        // Last corner point of the first row
-        createFaceNormal(terrainCoordinates,
-                         base_count,
-                         base_count - 3,
-                         base_count - width_inc);
-
-        terrainNormals[count] = normal[0];
-        terrainNormals[count + 1] = normal[1];
-        terrainNormals[count + 2] = normal[2];
-    }
-*/
-    /**
-     * Convenience method to calculate the average normal value between
-     * two quads - ie along the side of an object
-     *
-     * @param coords The coordinates to generate from
-     * @param p The centre point
-     * @param p1 The first point of the first side
-     * @param p2 The middle, shared side point
-     * @param p3 The last point of the second side
-     * @return The averaged vector
-     */
-    private void calcSideAverageNormal(float[] coords,
-                                       int p,
-                                       int p1,
-                                       int p2,
-                                       int p3)
-    {
-        float x, y, z;
-
-        // Normal first for the previous quad
-        createFaceNormal(coords, p, p1, p2);
-        x = normal[0];
-        y = normal[1];
-        z = normal[2];
-
-        // Normal for the next quad
-        createFaceNormal(coords, p, p2, p3);
-
-        // create the average of each compoenent for the final normal
-        normal[0] = (normal[0] + x) * 0.5f;
-        normal[1] = (normal[1] + y) * 0.5f;
-        normal[2] = (normal[2] + z) * 0.5f;
-
-        float mag = normal[0] * normal[0] +
-                    normal[1] * normal[1] +
-                    normal[2] * normal[2];
-
-        if(mag != 0.0f)
-        {
-            mag = 1.0f / ((float) Math.sqrt(mag));
-            normal[0] = normal[0] * mag;
-            normal[1] = normal[1] * mag;
-            normal[2] = normal[2] * mag;
-        }
-        else
-        {
-            normal[0] = 0;
-            normal[1] = 0;
-            normal[2] = 0;
-        }
-    }
-
-    /**
-     * Convenience method to create quad average normal amongst four
-     * quads based around a common centre point (the one having the normal
-     * calculated).
-     *
-     * @param coords The coordinates to generate from
-     * @param p The centre point
-     * @param p1 shared point between first and last quad
-     * @param p2 shared point between first and second quad
-     * @param p3 shared point between second and third quad
-     * @param p4 shared point between third and fourth quad
-     * @return The averaged vector
-     */
-    private void calcQuadAverageNormal(float[] coords,
-                                       int p,
-                                       int p1,
-                                       int p2,
-                                       int p3,
-                                       int p4)
-    {
-        float x, y, z;
-
-        // Normal first for quads 1 & 2
-        createFaceNormal(coords, p, p2, p1);
-        x = normal[0];
-        y = normal[1];
-        z = normal[2];
-
-        // Normal for the quads 2 & 3
-        createFaceNormal(coords, p, p2, p3);
-        x += normal[0];
-        y += normal[1];
-        z += normal[2];
-
-        // Normal for quads 3 & 4
-        createFaceNormal(coords, p, p3, p4);
-        x += normal[0];
-        y += normal[1];
-        z += normal[2];
-
-        // Normal for quads 1 & 4
-        createFaceNormal(coords, p, p4, p1);
-
-        // create the average of each compoenent for the final normal
-        normal[0] = (normal[0] + x) * 0.25f;
-        normal[1] = (normal[1] + y) * 0.25f;
-        normal[2] = (normal[2] + z) * 0.25f;
-
-        float mag = normal[0] * normal[0] +
-                    normal[1] * normal[1] +
-                    normal[2] * normal[2];
-
-        if(mag != 0.0f)
-        {
-            mag = 1.0f / ((float) Math.sqrt(mag));
-            normal[0] = normal[0] * mag;
-            normal[1] = normal[1] * mag;
-            normal[2] = normal[2] * mag;
-        }
-        else
-        {
-            normal[0] = 0;
-            normal[1] = 0;
-            normal[2] = 0;
-        }
-    }
-
-    /**
-     * Regenerate the texture coordinate points.
-     * Assumes regenerateBase has been called before this
-     */
-    private void regenerateTexcoords()
-    {
-        numTexcoordValues = widthPoints * depthPoints * 2;
-        terrainTexcoords = new float[numTexcoordValues];
-
-        float d = 0;
-        float w = 0;
-        float width_inc = 1.0f / (widthPoints - 1);
-        float depth_inc = 1.0f / (depthPoints - 1);
-
-        int count = 0;
-
-        if(flatHeights != null)
-        {
-            int num = numTerrainValues / 3;
-            for(int i = 1; i <= num; i++)
-            {
-
-                terrainTexcoords[count++] = w;
-                terrainTexcoords[count++] = d;
-                w += width_inc;
-
-                if(((i % (widthPoints)) == 0))
-                {
-                    d += depth_inc;
-                    w = 0;
-                }
-            }
-        }
-        else
-        {
-            for(int i = 0; i < depthPoints; i++)
-            {
-                for(int j = 0;  j < widthPoints; j++)
-                {
-
-                    terrainTexcoords[count++] = w;
-                    terrainTexcoords[count++] = d;
-
-
-                    w += width_inc;
-                }
-
-                d += depth_inc;
-                w = 0;
-            }
-        }
-    }
-
-    /**
-     * Convenience method to create a normal for the given vertex coordinates
-     * and normal array. This performs a cross product of the two vectors
-     * described by the middle and two end points.
-     *
-     * @param coords The coordinate array to read values from
-     * @param p The index of the middle point
-     * @param p1 The index of the first point
-     * @param p2 The index of the second point
-     * @return A temporary value containing the normal value
-     */
-    private void createFaceNormal(float[] coords, int p, int p1, int p2)
-    {
-        float x1 = coords[p1]     - coords[p];
-        float y1 = coords[p1 + 1] - coords[p + 1];
-        float z1 = coords[p1 + 2] - coords[p + 2];
-
-        float x2 = coords[p]     - coords[p2];
-        float y2 = coords[p + 1] - coords[p2 + 1];
-        float z2 = coords[p + 2] - coords[p2 + 2];
-
-        float x = y1 * z2 - z1 * y2;
-        float y = z1 * x2 - x1 * z2;
-        float z = x1 * y2 - y1 * x2;
-
-        float mag = x * x + y * y + z * z;
-
-// TODO: Flipping normals, not sure why this is needed
-        if(mag != 0.0f)
-        {
-            mag = 1.0f / ((float) Math.sqrt(mag));
-            normal[0] = -x * mag;
-            normal[1] = -y * mag;
-            normal[2] = -z * mag;
-        }
-        else
-        {
-            normal[0] = 0;
-            normal[1] = 0;
-            normal[2] = 0;
-        }
-    }
-
-    /**
-     * Regenerate the base normals points. These are the flat circle that
-     * makes up the base of the code. The normals are generated based the
-     * smoothing of normal averages for interior points. Around the edges,
-     * we use the average of the edge value polygons.
-     */
-    private void regenerateNormals(float[] coords, float[] normals)
-    {
-        int count = 0;
-        int base_count;
-        int i, j;
-        int width_inc = widthPoints * 3;
-
-        // The first edge
-        // corner point - normal based on only that face
-        createFaceNormal(coords, width_inc, 0, 3);
-
-        normals[count++] = normal[0];
-        normals[count++] = normal[1];
-        normals[count++] = normal[2];
-
-        base_count = 3;
-
-        for(i = 1; i < (widthPoints - 1); i++)
-        {
-            calcSideAverageNormal(coords,
-                                         base_count,
-                                         base_count + 3,
-                                         base_count + width_inc,
-                                         base_count - 3);
-
-            normals[count++] = normal[0];
-            normals[count++] = normal[1];
-            normals[count++] = normal[2];
-
-            base_count += 3;
-        }
-
-        // Last corner point of the first row
-        createFaceNormal(coords,
-                                base_count,
-                                base_count + width_inc,
-                                base_count - 3);
-
-        normals[count++] = normal[0];
-        normals[count++] = normal[1];
-        normals[count++] = normal[2];
-
-        base_count += 3;
-
-        // Now, process all of the internal points
-        for(i = 1; i < (depthPoints - 1); i++)
-        {
-
-            calcSideAverageNormal(coords,
-                                         base_count,
-                                         base_count - width_inc,
-                                         base_count + 3,
-                                         base_count + width_inc);
-
-            normals[count++] = normal[0];
-            normals[count++] = normal[1];
-            normals[count++] = normal[2];
-
-            base_count += 3;
-
-            for(j = 1; j < (widthPoints - 1); j++)
-            {
-
-                calcQuadAverageNormal(coords,
-                                             base_count,
-                                             base_count + 3,
-                                             base_count + width_inc,
-                                             base_count - 3,
-                                             base_count - width_inc);
-
-                normals[count++] = normal[0];
-                normals[count++] = normal[1];
-                normals[count++] = normal[2];
-
-                base_count += 3;
-            }
-
-            // Last point of the row
-            calcSideAverageNormal(coords,
-                                         base_count,
-                                         base_count + width_inc,
-                                         base_count - 3,
-                                         base_count - width_inc);
-
-            normals[count++] = normal[0];
-            normals[count++] = normal[1];
-            normals[count++] = normal[2];
-
-            base_count += 3;
-        }
-
-        // The last edge
-        // corner point - normal based on only that face
-        createFaceNormal(coords,
-                                base_count,
-                                base_count - width_inc,
-                                base_count + 3);
-
-        normals[count++] = normal[0];
-        normals[count++] = normal[1];
-        normals[count++] = normal[2];
-
-        base_count += 3;
-
-        for(i = 1; i < (widthPoints - 1); i++)
-        {
-            calcSideAverageNormal(coords,
-                                         base_count,
-                                         base_count - 3,
-                                         base_count - width_inc,
-                                         base_count + 3);
-
-            normals[count++] = normal[0];
-            normals[count++] = normal[1];
-            normals[count++] = normal[2];
-
-            base_count += 3;
-        }
-
-        // Last corner point of the first row
-        createFaceNormal(coords,
-                                base_count,
-                                base_count - 3,
-                                base_count - width_inc);
-
-        normals[count++] = normal[0];
-        normals[count++] = normal[1];
-        normals[count++] = normal[2];
-    }
-
-    // Float pretty printer
-
-    private String pp(float[] num, int places) {
-        StringBuilder buff = new StringBuilder();
-
-        for (int j=0; j < num.length; j++) {
-            String sfloat = Float.toString(num[j]);
-
-            int needs = places - sfloat.length();
-
-            if (needs == 0) {
-                buff.append(sfloat);
-                buff.append(" ");
-            } else if (needs < 0) {
-                buff.append(sfloat.substring(0,places));
-                buff.append(" ");
-            } else {
-                for(int i=0; i < needs; i++) {
-                    sfloat += " ";
-                }
-
-                buff.append(sfloat);
-                buff.append(" ");
-            }
-        }
-
-        return buff.toString();
-    }
-
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001-2004
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.renderer.common.nodes.geospatial;
+
+// External imports
+import org.j3d.geom.GeometryData;
+import org.j3d.geom.InvalidArraySizeException;
+import org.j3d.geom.UnsupportedTypeException;
+
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.TransformException;
+
+// Local imports
+// None
+
+/**
+ * A generator that takes a set of height values as a grid and turns it into
+ * geometry suitable for local graphics projections.
+ * <p>
+ *
+ * Points are defined in the height arrays in width first order. Normals, are
+ * always smooth blended.
+ * <p>
+ *
+ * Alan: There are some cases where texture generation is not complete.
+ * Especially in regards to 3D textures.
+ * <p>
+ *
+ * This class originally came from the j3d.org ElevationGridGenerator, but has
+ * been mostly gutted and special cased for the needs of this system.
+ *
+ * @author Justin Couch
+ * @version $Revision: 1.7 $
+ */
+public class ElevationGridGenerator {
+
+    /** The default size of the terrain */
+    private static final float DEFAULT_SIZE = 100;
+
+    /** The default number of points in each direction */
+    private static final int DEFAULT_POINT_COUNT = 2;
+
+    /** The default base height of the terrain */
+    private static final float DEFAULT_HEIGHT = 2;
+
+    /** Current width of the terrain */
+    private double terrainWidth;
+
+    /** Depth of the terrain to generate */
+    private double terrainDepth;
+
+    /** Number of points in the width direction */
+    private int widthPoints;
+
+    /** Number of points in the depth direction */
+    private int depthPoints;
+
+    /** The yScale applied after coordinate conversion */
+    private float yScale;
+
+    /** The points to use as a 1D array. */
+    private double[] flatHeights;
+
+    /** The number of terrain coordinates in use */
+    private int numTerrainValues;
+
+    /** The number of texture coordinates in use */
+    private int numTexcoordValues;
+
+    /** The array holding all of the vertices during construction */
+    private float[] terrainCoordinates;
+
+    /** The array holding all of the normals during construction */
+    private float[] terrainNormals;
+
+    /** The array holding all of the texture coordinates during construction */
+    private float[] terrainTexcoords;
+
+    /** The number of quads in the terrain */
+    private int facetCount;
+
+    /** Utility class to supply the source coordinates for transformation */
+    private GeoPosition inPosition;
+
+    /** Utility class to fetch the output coordinates from transformation */
+    private GeoPosition outPosition;
+
+    /** work array to output normal generation into */
+    private float[] normal;
+
+    /** Are we calculating per vertex normals, hardcode for now */
+    private boolean perVertexNormals = true;
+
+    /**
+     * Construct a customized terrain according to the full set of configurable
+     * data.
+     *
+     * @param w The width of the terrain
+     * @param d The depth of the terrain
+     * @param wPnts The number of heights in the width
+     * @param dPnts The number of heights in the depth
+     * @param yScale y axix scalar
+     * @param heights The array of height values to use
+     * @throws IllegalArgumentException One of the points were &lt;= 1 or the
+     *   dimensions are non-positive
+     */
+    public ElevationGridGenerator(double w,
+                                  double d,
+                                  int wPnts,
+                                  int dPnts,
+                                  float yScale,
+                                  double[] heights)
+    {
+        if((wPnts < 2) || (dPnts < 2))
+            throw new IllegalArgumentException("Point count <= 1");
+
+        if((w <= 0) || (d <= 0))
+            throw new IllegalArgumentException("Dimension <= 0");
+
+        terrainWidth = w;
+        terrainDepth = d;
+        widthPoints = wPnts;
+        depthPoints = dPnts;
+        this.yScale = yScale;
+
+        facetCount = (depthPoints - 1) * (widthPoints - 1);
+
+        flatHeights = heights;
+
+        inPosition = new GeoPosition();
+        outPosition = new GeoPosition();
+        normal = new float[3];
+    }
+
+    /**
+     * Change the dimensions of the cone to be generated. Calling this will
+     * make the points be re-calculated next time you ask for geometry or
+     * normals.
+     *
+     * @param w The width of the terrain
+     * @param d The depth of the terrain
+     * @param wPnts The number of heights in the width
+     * @param dPnts The number of heights in the depth
+     * @throws IllegalArgumentException One of the points were &lt;= 1 or the
+     *   dimensions are non-positive
+     */
+    public void setDimensions(double w, double d, int wPnts, int dPnts)
+    {
+        if((terrainWidth != w) || (terrainDepth != d))
+        {
+            terrainDepth = d;
+            terrainWidth = w;
+        }
+
+        if((wPnts != widthPoints) || (dPnts != depthPoints))
+        {
+            widthPoints = wPnts;
+            depthPoints = dPnts;
+
+            facetCount = (depthPoints - 1) * (widthPoints - 1);
+        }
+    }
+
+    /**
+     * Set the details of the terrain height to use a flat array of values.
+     *
+     * @param heights The array of height values to use
+     */
+    public void setTerrainDetail(double[] heights)
+    {
+        flatHeights = heights;
+    }
+
+    /**
+     * Get the number of vertices that this generator will create for the
+     * shape given in the definition based on the current width and height
+     * information.
+     *
+     * @param indexed True if this is to be indexed triangle strips, false
+     *    otherwise
+     * @return The vertex count for the object
+     * @throws UnsupportedTypeException The generator cannot handle the type
+     *   of geometry you have requested.
+     */
+    public int getVertexCount(boolean indexed)
+    {
+        int ret_val;
+
+        if(indexed)
+            ret_val = facetCount * 2;
+        else
+            ret_val = widthPoints * 2 * (depthPoints - 1);
+
+        return ret_val;
+    }
+
+
+    /**
+     * Generate a new set of geometry items based on the passed data. If the
+     * data does not contain the right minimum array lengths an exception will
+     * be generated. If the array reference is null, this will create arrays
+     * of the correct length and assign them to the return value.
+     *
+     * @param data The data to base the calculations on
+     * @param transform The geodetic transformation needed
+     * @param gridOrigin The location of the SW corner of the grid
+     * @param localOrigin an origin offset if needed. Null if not
+     * @param indexed True if this is to be indexed triangle strips, false
+     *    otherwise
+     * @param creaseAngle angle over which we want to create separate normals
+     *   rather than smoothed normals
+     * @throws InvalidArraySizeException The array is not big enough to contain
+     *   the requested geometry
+     * @throws org.opengis.referencing.operation.TransformException
+     */
+    public void generate(GeometryData data,
+                         MathTransform transform,
+                         double[] gridOrigin,
+                         double[] localOrigin,
+                         boolean indexed,
+                         double creaseAngle)
+        throws InvalidArraySizeException, TransformException
+    {
+        if(indexed)
+            indexedTriangleStrips(data,
+                                  transform,
+                                  gridOrigin,
+                                  localOrigin,
+                                  creaseAngle);
+        else
+            triangleStrips(data,
+                           transform,
+                           gridOrigin,
+                           localOrigin,
+                           creaseAngle);
+
+    }
+
+    /**
+     * Generate indexed quads.
+     *
+     * @param data The data to base the calculations on
+     * @param transform The geodetic transformation needed
+     * @param gridOrigin The location of the SW corner of the grid
+     * @param localOrigin an origin offset if needed. Null if not
+     * @param indexed True if this is to be indexed triangle strips, false
+     *    otherwise
+     * @param creaseAngle angle over which we want to create separate normals
+     *   rather than smoothed normals
+     * @param vertex
+     * @throws InvalidArraySizeException The array is not big enough to contain
+     *   the requested geometry
+     * @throws org.opengis.referencing.operation.TransformException
+     */
+    public void generateIndexedQuads(GeometryData data,
+                         MathTransform transform,
+                         double[] gridOrigin,
+                         double[] localOrigin,
+                         boolean indexed,
+                         double creaseAngle, double[] vertex)
+        throws InvalidArraySizeException, TransformException {
+
+
+        int vtx_cnt = widthPoints * depthPoints;
+
+        if(data.coordinates == null)
+            data.coordinates = new float[vtx_cnt * 3];
+        else if(data.coordinates.length < vtx_cnt * 3)
+            throw new InvalidArraySizeException("Coordinates",
+                                                data.coordinates.length,
+                                                vtx_cnt * 3);
+
+        if(data.normals == null)
+            data.normals = new float[vtx_cnt * 3];
+        else if(data.normals.length < vtx_cnt * 3)
+            throw new InvalidArraySizeException("Normals",
+                                                data.normals.length,
+                                                vtx_cnt * 3);
+
+        if(data.textureCoordinates == null)
+            data.textureCoordinates = new float[vtx_cnt * 2];
+        else if(data.textureCoordinates.length < vtx_cnt * 2)
+            throw new InvalidArraySizeException("TextureCoordinates",
+                                                data.textureCoordinates.length,
+                                                vtx_cnt * 2);
+
+        int index_size = (widthPoints - 1) * ( depthPoints - 1 ) * 4;
+
+        if(data.indexes == null)
+            data.indexes = new int[index_size];
+        else if(data.indexes.length < index_size)
+            throw new InvalidArraySizeException("Indexes",
+                                                data.indexes.length,
+                                                index_size);
+
+        float[] coords = data.coordinates;
+        float[] texCoords = data.textureCoordinates;
+        float[] normals = data.normals;
+        data.vertexCount = vtx_cnt;
+
+        double w = gridOrigin[1];
+        double d = gridOrigin[0];
+        double width_inc = terrainWidth / (widthPoints - 1);
+        double depth_inc = terrainDepth / (depthPoints - 1);
+        float widthDiv = 1.0f/(  widthPoints - 1.0f );
+        float depthDiv = 1.0f/( depthPoints - 1.0f );
+
+        int count = 0;
+        int num = widthPoints * depthPoints;
+        int texIndex = 0;
+        double height;
+
+        if(localOrigin != null) {
+            int i = 0;
+            for(int z = 0; z < depthPoints; z++) {
+                for(int x = 0; x <widthPoints; x++) {
+                    i++;
+
+                    // Proposed behavior for missing values, issue warning?
+                    if (i > flatHeights.length)
+                        height = 0;
+                    else
+                        height = flatHeights[i - 1];
+
+                    inPosition.setPosition(d, w, height * yScale);
+
+                    transform.transform(inPosition, outPosition);
+
+                    double[] out = outPosition.getCoordinates();
+
+					vertex[count] = out[0];
+					vertex[count + 1] = out[1];
+					vertex[count + 2] = out[2];
+
+                    coords[count] = (float)(out[0] - localOrigin[0]);
+                    coords[count + 1] = (float)(out[1] - localOrigin[1]);
+                    coords[count + 2] = (float)(out[2] - localOrigin[2]);
+                    texCoords[texIndex++] = x * widthDiv;
+                    texCoords[texIndex++] = z * depthDiv;
+
+                    count += 3;
+                    w += width_inc;
+
+                    if(((i % (widthPoints)) == 0)) {
+                        d += depth_inc;
+                        w = gridOrigin[1];
+                    }
+                }
+            }
+        } else {
+            int i = 0;
+
+            for(int z = 0; z < depthPoints; z++) {
+                for(int x = 0; x <widthPoints; x++) {
+                    i++;
+                    // Proposed behavior for missing values, issue warning?
+                    if (i > flatHeights.length)
+                        height = 0;
+                    else
+                        height = flatHeights[i - 1];
+
+                    inPosition.setPosition(d, w, height * yScale);
+
+                    transform.transform(inPosition, outPosition);
+
+                    double[] out = outPosition.getCoordinates();
+
+					vertex[count] = out[0];
+					vertex[count + 1] = out[1];
+					vertex[count + 2] = out[2];
+
+                    coords[count] = (float)out[0];
+                    coords[count + 1] = (float)out[1];
+                    coords[count + 2] = (float)out[2];
+
+                    texCoords[texIndex++] =  (x * widthDiv);
+                    texCoords[texIndex++] =  (z * depthDiv);
+                    count += 3;
+
+                    w += width_inc;
+
+                    if(((i % (widthPoints)) == 0)) {
+                        d += depth_inc;
+                        w = gridOrigin[1];
+                    }
+
+                }
+            }
+        }
+
+
+        int index = 0;
+        int[] values = data.indexes;
+        data.indexesCount = data.indexes.length;
+
+//System.out.println("depth: " + depthPoints + " widthPoints: " + widthPoints);
+        for ( int z = 0; z < depthPoints - 1; z++ ) {
+            for ( int x = 0; x < widthPoints - 1; x++ ) {
+                values[index]   = x + z * widthPoints;
+                values[index+1] = values[index] + 1;
+                values[index+2] = values[index+1] + widthPoints;
+                values[index+3] = values[index+2] - 1;
+/*
+      System.out.println( "Poly: " + values[index] + " " +values[index+1] +
+                  " " + values[index+2] + " " + values[index+3] +
+                  "  (" + x + "," + z + ": " + index + ")" );
+*/
+
+                index += 4;
+            }
+        }
+
+        regenerateNormals(data.coordinates, data.normals);
+    }
+
+    /**
+     * Generate a new set of points for a triangle strip array. There is one
+     * strip for the side and one strip each for the ends.
+     *
+     * @param data The data to base the calculations on
+     * @param transform The geodetic transformation needed
+     * @param gridOrigin The location of the SW corner of the grid
+     * @param localOrigin an origin offset if needed. Null if not
+     * @param creaseAngle angle over which we want to create separate normals
+     *   rather than smoothed normals
+     * @throws InvalidArraySizeException The array is not big enough to contain
+     *   the requested geometry
+     */
+    private void triangleStrips(GeometryData data,
+                                MathTransform transform,
+                                double[] gridOrigin,
+                                double[] localOrigin,
+                                double creaseAngle)
+        throws InvalidArraySizeException, TransformException
+    {
+        generateUnindexedTriStripCoordinates(data,
+                                             transform,
+                                             gridOrigin,
+                                             localOrigin);
+
+        if((data.geometryComponents & GeometryData.NORMAL_DATA) != 0)
+            generateUnindexedTriStripNormals(data);
+
+        if((data.geometryComponents & GeometryData.TEXTURE_2D_DATA) != 0)
+            generateUnindexedTriStripTexture2D(data);
+        else if((data.geometryComponents & GeometryData.TEXTURE_3D_DATA) != 0)
+            generateTriTexture3D(data);
+
+        int num_strips = depthPoints - 1;
+        data.numStrips = num_strips;
+
+        if(data.stripCounts == null)
+            data.stripCounts = new int[num_strips];
+        else if(data.stripCounts.length < num_strips)
+            throw new InvalidArraySizeException("Strip counts",
+                                                data.stripCounts.length,
+                                                num_strips);
+
+        for(int i = num_strips; --i >= 0; )
+            data.stripCounts[i] = widthPoints * 2;
+    }
+
+    /**
+     * Generates new set of unindexed points for triangles strips. The array
+     * consists of one strip per width row.
+     *
+     * @param data The data to base the calculations on
+     * @param transform The geodetic transformation needed
+     * @param gridOrigin The location of the SW corner of the grid
+     * @param localOrigin an origin offset if needed. Null if not
+     * @throws InvalidArraySizeException The array is not big enough to contain
+     *   the requested geometry
+     */
+    private void generateUnindexedTriStripCoordinates(GeometryData data,
+                                                      MathTransform transform,
+                                                      double[] gridOrigin,
+                                                      double[] localOrigin)
+        throws InvalidArraySizeException, TransformException
+    {
+        int vtx_cnt = widthPoints * (depthPoints - 1) * 2;
+        if(data.coordinates == null)
+            data.coordinates = new float[vtx_cnt * 3];
+        else if(data.coordinates.length < vtx_cnt * 3)
+            throw new InvalidArraySizeException("Coordinates",
+                                                data.coordinates.length,
+                                                vtx_cnt * 3);
+
+        float[] coords = data.coordinates;
+        data.vertexCount = vtx_cnt;
+
+        numTerrainValues = widthPoints * depthPoints * 3;
+        terrainCoordinates = new float[numTerrainValues];
+
+        double d = gridOrigin[0];
+        double w = gridOrigin[1];
+        double width_inc = terrainWidth / (widthPoints - 1);
+        double depth_inc = terrainDepth / (depthPoints - 1);
+
+        if (perVertexNormals) {
+            terrainNormals = new float[coords.length];
+        }
+
+        int count = 0;
+        int tc_count = 0;
+        int num = widthPoints * (depthPoints - 1);
+
+        // TODO: All of the coordinates are -x,-z to align with GeoLocation and GeoCoordinate
+        // note sure why this is needed.
+
+        if(localOrigin != null) {
+            for(int i = 1; i <= num; i++) {
+                inPosition.setPosition(d + depth_inc,
+                                       w,
+                                       flatHeights[i + widthPoints - 1] * yScale);
+
+                transform.transform(inPosition, outPosition);
+
+                double[] out = outPosition.getCoordinates();
+                coords[count] = -(float)(out[0] - localOrigin[0]);
+                coords[count + 1] = (float)(out[1] - localOrigin[1]);
+                coords[count + 2] = -(float)(out[2] - localOrigin[2]);
+
+                if (perVertexNormals) {
+                    double x = out[0];
+                    double y = out[1];
+                    double z = out[2];
+
+                    double mag = x * x + y * y + z * z;
+
+                    if(mag != 0.0)
+                    {
+                        mag = 1.0 / Math.sqrt(mag);
+                        terrainNormals[count] = (float) (x * mag);
+                        terrainNormals[count + 1] = (float) (y * mag);
+                        terrainNormals[count + 2] = (float) (z * mag);
+                    }
+                    else
+                    {
+                        terrainNormals[count] = 0;
+                        terrainNormals[count + 1] = 1;
+                        terrainNormals[count + 2] = 0;
+                    }
+                }
+
+                // update the first row from data calculated. Otherwise, always
+                // take the next row's worth of data.
+                if(d == 0) {
+                    terrainCoordinates[tc_count] = coords[count];
+                    terrainCoordinates[tc_count + 1] = coords[count + 1];
+                    terrainCoordinates[tc_count + 2] = coords[count + 2];
+                    tc_count += 3;
+                }
+
+                inPosition.setPosition(d, w, flatHeights[i - 1] * yScale);
+
+                transform.transform(inPosition, outPosition);
+
+                out = outPosition.getCoordinates();
+
+                if (perVertexNormals) {
+                    double x = out[0];
+                    double y = out[1];
+                    double z = out[2];
+
+                    double mag = x * x + y * y + z * z;
+
+                    if(mag != 0.0)
+                    {
+                        mag = 1.0 / Math.sqrt(mag);
+                        terrainNormals[count + 3] = (float) (x * mag);
+                        terrainNormals[count + 4] = (float) (y * mag);
+                        terrainNormals[count + 5] = (float) (z * mag);
+                    }
+                    else
+                    {
+                        terrainNormals[count + 3] = 0;
+                        terrainNormals[count + 4] = 1;
+                        terrainNormals[count + 5] = 0;
+                    }
+                }
+
+                coords[count + 3] = -(float)(out[0] - localOrigin[0]);
+                coords[count + 4] = (float)(out[1] - localOrigin[1]);
+                coords[count + 5] = -(float)(out[2] - localOrigin[2]);
+
+                terrainCoordinates[tc_count] = coords[count + 3];
+                terrainCoordinates[tc_count + 1] = coords[count + 4];
+                terrainCoordinates[tc_count + 2] = coords[count + 5];
+
+                count += 6;
+                tc_count += 3;
+
+                w += width_inc;
+
+                if(((i % (widthPoints)) == 0))
+                {
+                    d += depth_inc;
+                    w = 0;
+                }
+            }
+        } else {
+System.out.println("*** EG no origin: " + num);
+            for(int i = 1; i <= num; i++) {
+                inPosition.setPosition(d + depth_inc,
+                                       w,
+                                       flatHeights[i + widthPoints - 1] * yScale);
+
+                transform.transform(inPosition, outPosition);
+
+                double[] out = outPosition.getCoordinates();
+
+
+                coords[count] = -(float)out[0];
+                coords[count + 1] = (float)out[1];
+                coords[count + 2] = -(float)out[2];
+
+System.out.println("out1: " + out[0] + " " + out[1] + " " + out[2]);
+/*
+                coords[count] = -(float)out[0];
+                coords[count + 1] = (float)out[1];
+                coords[count + 2] = -(float)out[2];
+*/
+                if (perVertexNormals) {
+                    double x = out[0];
+                    double y = out[1];
+                    double z = out[2];
+
+                    double mag = x * x + y * y + z * z;
+
+                    if(mag != 0.0)
+                    {
+                        mag = 1.0 / Math.sqrt(mag);
+                        terrainNormals[count] = (float) (x * mag);
+                        terrainNormals[count + 1] = (float) (y * mag);
+                        terrainNormals[count + 2] = (float) (z * mag);
+                    }
+                    else
+                    {
+                        terrainNormals[count] = 0;
+                        terrainNormals[count + 1] = 1;
+                        terrainNormals[count + 2] = 0;
+                    }
+                }
+
+                // update the first row from data calculated. Otherwise, always
+                // take the next row's worth of data.
+                if(d == 0) {
+                    terrainCoordinates[tc_count] = coords[count];
+                    terrainCoordinates[tc_count + 1] = coords[count + 1];
+                    terrainCoordinates[tc_count + 2] = coords[count + 2];
+                    tc_count += 3;
+                }
+
+                inPosition.setPosition(d, w, flatHeights[i - 1] * yScale);
+
+                transform.transform(inPosition, outPosition);
+
+                out = outPosition.getCoordinates();
+System.out.println("out2: " + out[0] + " " + out[1] + " " + out[2]);
+
+
+                coords[count + 3] = -(float)out[0];
+                coords[count + 4] = (float)out[1];
+                coords[count + 5] = -(float)out[2];
+/*
+                coords[count + 3] = -(float)out[0];
+                coords[count + 4] = (float)out[1];
+                coords[count + 5] = -(float)out[2];
+*/
+                if (perVertexNormals) {
+                    double x = out[0];
+                    double y = out[1];
+                    double z = out[2];
+
+                    double mag = x * x + y * y + z * z;
+
+                    if(mag != 0.0)
+                    {
+                        mag = 1.0 / Math.sqrt(mag);
+                        terrainNormals[count + 3] = (float) (x * mag);
+                        terrainNormals[count + 4] = (float) (y * mag);
+                        terrainNormals[count + 5] = (float) (z * mag);
+                    }
+                    else
+                    {
+                        terrainNormals[count + 3] = 0;
+                        terrainNormals[count + 4] = 1;
+                        terrainNormals[count + 5] = 0;
+                    }
+                }
+
+                terrainCoordinates[tc_count] = coords[count + 3];
+                terrainCoordinates[tc_count + 1] = coords[count + 4];
+                terrainCoordinates[tc_count + 2] = coords[count + 5];
+
+                count += 6;
+                tc_count += 3;
+
+                w += width_inc;
+
+                if(((i % (widthPoints)) == 0))
+                {
+                    d += depth_inc;
+                    w = 0;
+                }
+            }
+        }
+
+
+    }
+
+    /**
+     * Generate a new set of normals for a normal set of unindexed points.
+     * Smooth normals are used for the sides at the average between the faces.
+     * Bottom normals always point down.
+     * <p>
+     * This must always be called after the coordinate generation.
+     *
+     * @param data The data to base the calculations on
+     * @throws InvalidArraySizeException The array is not big enough to contain
+     *   the requested geometry
+     */
+    private void generateUnindexedTriStripNormals(GeometryData data)
+        throws InvalidArraySizeException
+    {
+        int vtx_cnt = data.vertexCount * 3;
+
+        if(data.normals == null)
+            data.normals = new float[vtx_cnt];
+        else if(data.normals.length < vtx_cnt)
+            throw new InvalidArraySizeException("Normals",
+                                                data.normals.length,
+                                                vtx_cnt);
+
+        regenerateNormals();
+
+        int i;
+        float[] normals = data.normals;
+        int count = 0;
+        int base_count = 0;
+        int width_inc = widthPoints * 3;
+        int total_points = widthPoints * (depthPoints - 1);
+
+        if (!perVertexNormals) {
+            // Start of with one less row (width) here because we don't have two
+            // sets of coordinates for those.
+            for(i = total_points; --i >= 0; )
+            {
+                normals[count++] = terrainNormals[base_count];
+                normals[count++] = terrainNormals[base_count + 1];
+                normals[count++] = terrainNormals[base_count + 2];
+
+                normals[count++] = terrainNormals[base_count + width_inc];
+                normals[count++] = terrainNormals[base_count + width_inc + 1];
+                normals[count++] = terrainNormals[base_count + width_inc + 2];
+
+                base_count += 3;
+            }
+        } else {
+            // Straight copy of generated normals
+            int len2 = terrainNormals.length;
+
+            for(i=0; i < len2; i++) {
+                normals[i] = terrainNormals[i];
+            }
+        }
+    }
+
+    /**
+     * Generates new set of unindexed texture coordinates for triangles strips.
+     * The array consists of one strip per width row.
+     *
+     * @param data The data to base the calculations on
+     * @throws InvalidArraySizeException The array is not big enough to contain
+     *   the requested geometry
+     */
+    private void generateUnindexedTriStripTexture2D(GeometryData data)
+        throws InvalidArraySizeException
+    {
+        int vtx_cnt = widthPoints * (depthPoints - 1) * 2;
+
+        if(data.textureCoordinates == null)
+            data.textureCoordinates = new float[vtx_cnt * 2];
+        else if(data.textureCoordinates.length < vtx_cnt * 2)
+            throw new InvalidArraySizeException("Coordinates",
+                                                data.textureCoordinates.length,
+                                                vtx_cnt * 2);
+
+        float[] coords = data.textureCoordinates;
+
+        regenerateTexcoords();
+
+        int i;
+        int count = 0;
+        int base_count = 0;
+        int width_inc = widthPoints * 2;
+        int total_points = widthPoints * (depthPoints - 1);
+
+        // Start of with one less row (width) here because we don't have two
+        // sets of coordinates for those.
+        for(i = total_points; --i >= 0; )
+        {
+            coords[count++] = terrainTexcoords[base_count + width_inc];
+            coords[count++] = terrainTexcoords[base_count + width_inc + 1];
+            coords[count++] = terrainTexcoords[base_count];
+            coords[count++] = terrainTexcoords[base_count + 1];
+
+            base_count += 2;
+        }
+    }
+
+    // Indexed generation routines
+
+    /**
+     * Generate a new set of points for an indexed triangle strip array. We
+     * build the strip from the existing points starting by working around the
+     * side and then doing the top and bottom. To create the ends we start at
+     * on radius point and then always refer to the center for each second
+     * item. This wastes every second triangle as a degenerate triangle, but
+     * the gain is less strips needing to be transmitted - ie less memory
+     * usage.
+     *
+     * @param data The data to base the calculations on
+     * @param transform The geodetic transformation needed
+     * @param gridOrigin The location of the SW corner of the grid
+     * @param localOrigin an origin offset if needed. Null if not
+     * @param creaseAngle angle over which we want to create separate normals
+     *   rather than smoothed normals
+     * @throws InvalidArraySizeException The array is not big enough to contain
+     *   the requested geometry
+     */
+    private void indexedTriangleStrips(GeometryData data,
+                                       MathTransform transform,
+                                       double[] gridOrigin,
+                                       double[] localOrigin,
+                                       double creaseAngle)
+        throws InvalidArraySizeException, TransformException {
+
+        generateIndexedCoordinates(data, transform, gridOrigin, localOrigin);
+
+        if((data.geometryComponents & GeometryData.NORMAL_DATA) != 0)
+            generateIndexedNormals(data);
+
+        if((data.geometryComponents & GeometryData.TEXTURE_2D_DATA) != 0)
+            generateTriTexture2D(data);
+        else if((data.geometryComponents & GeometryData.TEXTURE_3D_DATA) != 0)
+            generateTriTexture3D(data);
+
+        // now let's do the index list
+        int index_size = widthPoints * (depthPoints - 1) * 2;
+        int num_strips = depthPoints - 1;
+
+        if(data.indexes == null)
+            data.indexes = new int[index_size];
+        else if(data.indexes.length < index_size)
+            throw new InvalidArraySizeException("Indexes",
+                                                data.indexes.length,
+                                                index_size);
+
+        if(data.stripCounts == null)
+            data.stripCounts = new int[num_strips];
+        else if(data.stripCounts.length < num_strips)
+            throw new InvalidArraySizeException("Strip counts",
+                                                data.stripCounts.length,
+                                                num_strips);
+
+        int[] indexes = data.indexes;
+        int[] stripCounts = data.stripCounts;
+        data.indexesCount = index_size;
+        data.numStrips = num_strips;
+        int idx = 0;
+        int vtx = 0;
+        int total_points = widthPoints * (depthPoints - 1);
+
+        // The side is one big strip
+        for(int i = total_points; --i >= 0; ) {
+            indexes[idx++] = vtx;
+            indexes[idx++] = vtx + widthPoints;
+
+            vtx++;
+        }
+
+        for(int i = num_strips; --i >= 0; )
+            stripCounts[i] = widthPoints * 2;
+    }
+
+    /**
+     * Generates new set of indexed points for triangles or quads. The array
+     * consists of the side coordinates, followed by the center for top, then
+     * its points then the bottom center and its points. We do this as they
+     * use a completely different set of normals. The side
+     * coordinates are interleaved as top and then bottom values.
+     *
+     * @param data The data to base the calculations on
+     * @param transform The geodetic transformation needed
+     * @param gridOrigin The location of the SW corner of the grid
+     * @param localOrigin an origin offset if needed. Null if not
+     * @throws InvalidArraySizeException The array is not big enough to contain
+     *   the requested geometry
+     */
+    private void generateIndexedCoordinates(GeometryData data,
+                                            MathTransform transform,
+                                            double[] gridOrigin,
+                                            double[] localOrigin)
+        throws InvalidArraySizeException, TransformException {
+
+        int vtx_cnt = widthPoints * depthPoints;
+
+        if(data.coordinates == null)
+            data.coordinates = new float[vtx_cnt * 3];
+        else if(data.coordinates.length < vtx_cnt * 3)
+            throw new InvalidArraySizeException("Coordinates",
+                                                data.coordinates.length,
+                                                vtx_cnt * 3);
+
+        float[] coords = data.coordinates;
+        data.vertexCount = vtx_cnt;
+
+        double d = gridOrigin[0];
+        double w = gridOrigin[1];
+        double width_inc = terrainWidth / (widthPoints - 1);
+        double depth_inc = terrainDepth / (depthPoints - 1);
+
+        int count = 0;
+        int num = widthPoints * depthPoints;
+
+        if(localOrigin != null) {
+            for(int i = 1; i <= num; i++) {
+                inPosition.setPosition(w, flatHeights[i - 1], d);
+
+                transform.transform(inPosition, outPosition);
+
+                double[] out = outPosition.getCoordinates();
+
+                coords[count] = (float)(out[0] - localOrigin[0]);
+                coords[count + 1] = (float)(out[1] - localOrigin[1]);
+                coords[count + 2] = (float)(out[2] - localOrigin[2]);
+
+                count += 3;
+
+                w += width_inc;
+
+                if(((i % (widthPoints)) == 0)) {
+                    d += depth_inc;
+                    w = 0;
+                }
+            }
+        } else {
+            for(int i = 1; i <= num; i++) {
+                inPosition.setPosition(w, flatHeights[i - 1], d);
+
+                transform.transform(inPosition, outPosition);
+
+                double[] out = outPosition.getCoordinates();
+
+                coords[count] = (float)out[0];
+                coords[count + 1] = (float)out[1];
+                coords[count + 2] = (float)out[2];
+
+                count += 3;
+
+                w += width_inc;
+
+                if(((i % (widthPoints)) == 0)) {
+                    d += depth_inc;
+                    w = 0;
+                }
+            }
+        }
+    }
+
+    /**
+     * Generate a new set of normals for a normal set of indexed points.
+     * Smooth normals are used for the sides at the average between the faces.
+     * Bottom normals always point down.
+     * <p>
+     * This must always be called after the coordinate generation.
+     *
+     * @param data The data to base the calculations on
+     * @throws InvalidArraySizeException The array is not big enough to contain
+     *   the requested geometry
+     */
+    private void generateIndexedNormals(GeometryData data)
+        throws InvalidArraySizeException
+    {
+        int vtx_cnt = data.vertexCount * 3;
+
+        if(data.normals == null)
+            data.normals = new float[vtx_cnt];
+        else if(data.normals.length < vtx_cnt)
+            throw new InvalidArraySizeException("Normals",
+                                                data.normals.length,
+                                                vtx_cnt);
+
+        regenerateNormals();
+
+        System.arraycopy(terrainNormals, 0, data.normals, 0, numTerrainValues);
+    }
+
+    /**
+     * Generate a new set of texCoords for a set of unindexed points.
+     * <p>
+     * This must always be called after the coordinate generation.
+     *
+     * @param data The data to base the calculations on
+     * @throws InvalidArraySizeException The array is not big enough to contain
+     *   the requested geometry
+     */
+    private void generateTriTexture2D(GeometryData data)
+        throws InvalidArraySizeException
+    {
+        int vtx_cnt = data.vertexCount * 2;
+
+        if(data.textureCoordinates == null)
+            data.textureCoordinates = new float[vtx_cnt];
+        else if(data.textureCoordinates.length < vtx_cnt)
+            throw new InvalidArraySizeException("2D Texture coordinates",
+                                                data.textureCoordinates.length,
+                                                vtx_cnt);
+
+        regenerateTexcoords();
+
+        System.out.println("Unhandled textured generation case in " +
+            "ElevationGridGenerator");
+    }
+
+
+    /**
+     * Generate a new set of texCoords for a set of unindexed points.
+     * <p>
+     * This must always be called after the coordinate generation.
+     *
+     * @param data The data to base the calculations on
+     * @throws InvalidArraySizeException The array is not big enough to contain
+     *   the requested geometry
+     */
+    private void generateTriTexture3D(GeometryData data)
+        throws InvalidArraySizeException
+    {
+        int vtx_cnt = data.vertexCount * 2;
+
+        if(data.textureCoordinates == null)
+            data.textureCoordinates = new float[vtx_cnt];
+        else if(data.textureCoordinates.length < vtx_cnt)
+            throw new InvalidArraySizeException("3D Texture coordinates",
+                                                data.textureCoordinates.length,
+                                                vtx_cnt);
+
+        float[] texCoords = data.textureCoordinates;
+
+        System.out.println("Unhandled textured generation case in " +
+            "ElevationGridGenerator");
+    }
+
+    /**
+     * Regenerate the base normals points. These are the flat circle that
+     * makes up the base of the code. The normals are generated based the
+     * smoothing of normal averages for interior points. Around the edges,
+     * we use the average of the edge value polygons.
+     */
+    private void regenerateNormals()
+    {
+        // Already calculated?
+        if (perVertexNormals)
+            return;
+
+        // This code has been changed around to go from left to right instead
+        // of bottom to top, but it hasn't been tested.
+        terrainNormals = new float[numTerrainValues];
+
+        int count = 0;
+        int base_count;
+        int i, j;
+        int depth_inc = depthPoints * 3;
+
+        // The first edge
+        // corner point - normal based on only that face
+
+        createFaceNormal(terrainCoordinates, depth_inc, 0, 3);
+
+        terrainNormals[count] = normal[0];
+        terrainNormals[count + 1] = normal[1];
+        terrainNormals[count + 2] = normal[2];
+
+        count = 3;
+        base_count = 3;
+
+        for(i = 1; i < (depthPoints - 1); i++)
+        {
+            calcSideAverageNormal(terrainCoordinates,
+                                  base_count,
+                                  base_count + 3,
+                                  base_count + depth_inc,
+                                  base_count - 3);
+
+            terrainNormals[count] = normal[0];
+            terrainNormals[count + 1] = normal[1];
+            terrainNormals[count + 2] = normal[2];
+
+            count += 3;
+            base_count += 3;
+        }
+
+        // Last corner point of the first row
+        createFaceNormal(terrainCoordinates,
+                         base_count,
+                         base_count + depth_inc,
+                         base_count - 3);
+
+        terrainNormals[count] = normal[0];
+        terrainNormals[count + 1] = normal[1];
+        terrainNormals[count + 2] = normal[2];
+
+        count += 3;
+        base_count += 3;
+
+        // Now, process all of the internal points
+        for(i = 1; i < (widthPoints - 1); i++)
+        {
+
+            calcSideAverageNormal(terrainCoordinates,
+                                  base_count,
+                                  base_count - depth_inc,
+                                  base_count + 3,
+                                  base_count + depth_inc);
+
+            terrainNormals[count] = normal[0];
+            terrainNormals[count + 1] = normal[1];
+            terrainNormals[count + 2] = normal[2];
+
+            base_count += 3;
+            count += 3;
+
+            for(j = 1; j < (depthPoints - 1); j++)
+            {
+
+                calcQuadAverageNormal(terrainCoordinates,
+                                      base_count,
+                                      base_count + 3,
+                                      base_count + depth_inc,
+                                      base_count - 3,
+                                      base_count - depth_inc);
+
+                terrainNormals[count] = normal[0];
+                terrainNormals[count + 1] = normal[1];
+                terrainNormals[count + 2] = normal[2];
+
+                base_count += 3;
+                count += 3;
+            }
+
+            // Last point of the row
+            calcSideAverageNormal(terrainCoordinates,
+                                  base_count,
+                                  base_count + depth_inc,
+                                  base_count - 3,
+                                  base_count - depth_inc);
+
+            terrainNormals[count] = normal[0];
+            terrainNormals[count + 1] = normal[1];
+            terrainNormals[count + 2] = normal[2];
+
+            base_count += 3;
+            count += 3;
+        }
+
+        // The last edge
+        // corner point - normal based on only that face
+        createFaceNormal(terrainCoordinates,
+                         base_count,
+                         base_count - depth_inc,
+                         base_count + 3);
+
+        terrainNormals[count] = normal[0];
+        terrainNormals[count + 1] = normal[1];
+        terrainNormals[count + 2] = normal[2];
+
+        base_count += 3;
+        count += 3;
+
+        for(i = 1; i < (depthPoints - 1); i++)
+        {
+            calcSideAverageNormal(terrainCoordinates,
+                                  base_count,
+                                  base_count - 3,
+                                  base_count - depth_inc,
+                                  base_count + 3);
+
+            terrainNormals[count] = normal[0];
+            terrainNormals[count + 1] = normal[1];
+            terrainNormals[count + 2] = normal[2];
+
+            base_count += 3;
+            count += 3;
+        }
+
+        // Last corner point of the first row
+        createFaceNormal(terrainCoordinates,
+                         base_count,
+                         base_count - 3,
+                         base_count - depth_inc);
+
+        terrainNormals[count] = normal[0];
+        terrainNormals[count + 1] = normal[1];
+        terrainNormals[count + 2] = normal[2];
+    }
+
+    // This is the original bottom to top code
+/*
+    private final void regenerateNormals()
+    {
+        terrainNormals = new float[numTerrainValues];
+
+        int count = 0;
+        int base_count = 0;
+        int i, j;
+        int width_inc = widthPoints * 3;
+
+        // The first edge
+        // corner point - normal based on only that face
+
+        createFaceNormal(terrainCoordinates, width_inc, 0, 3);
+
+        terrainNormals[count] = normal[0];
+        terrainNormals[count + 1] = normal[1];
+        terrainNormals[count + 2] = normal[2];
+
+        count = 3;
+        base_count = 3;
+
+        for(i = 1; i < (widthPoints - 1); i++)
+        {
+            calcSideAverageNormal(terrainCoordinates,
+                                  base_count,
+                                  base_count + 3,
+                                  base_count + width_inc,
+                                  base_count - 3);
+
+            terrainNormals[count] = normal[0];
+            terrainNormals[count + 1] = normal[1];
+            terrainNormals[count + 2] = normal[2];
+
+            count += 3;
+            base_count += 3;
+        }
+
+        // Last corner point of the first row
+        createFaceNormal(terrainCoordinates,
+                         base_count,
+                         base_count + width_inc,
+                         base_count - 3);
+
+        terrainNormals[count] = normal[0];
+        terrainNormals[count + 1] = normal[1];
+        terrainNormals[count + 2] = normal[2];
+
+        count += 3;
+        base_count += 3;
+
+        // Now, process all of the internal points
+        for(i = 1; i < (depthPoints - 1); i++)
+        {
+
+            calcSideAverageNormal(terrainCoordinates,
+                                  base_count,
+                                  base_count - width_inc,
+                                  base_count + 3,
+                                  base_count + width_inc);
+
+            terrainNormals[count] = normal[0];
+            terrainNormals[count + 1] = normal[1];
+            terrainNormals[count + 2] = normal[2];
+
+            base_count += 3;
+            count += 3;
+
+            for(j = 1; j < (widthPoints - 1); j++)
+            {
+
+                calcQuadAverageNormal(terrainCoordinates,
+                                      base_count,
+                                      base_count + 3,
+                                      base_count + width_inc,
+                                      base_count - 3,
+                                      base_count - width_inc);
+
+                terrainNormals[count] = normal[0];
+                terrainNormals[count + 1] = normal[1];
+                terrainNormals[count + 2] = normal[2];
+
+                base_count += 3;
+                count += 3;
+            }
+
+            // Last point of the row
+            calcSideAverageNormal(terrainCoordinates,
+                                  base_count,
+                                  base_count + width_inc,
+                                  base_count - 3,
+                                  base_count - width_inc);
+
+            terrainNormals[count] = normal[0];
+            terrainNormals[count + 1] = normal[1];
+            terrainNormals[count + 2] = normal[2];
+
+            base_count += 3;
+            count += 3;
+        }
+
+        // The last edge
+        // corner point - normal based on only that face
+        createFaceNormal(terrainCoordinates,
+                         base_count,
+                         base_count - width_inc,
+                         base_count + 3);
+
+        terrainNormals[count] = normal[0];
+        terrainNormals[count + 1] = normal[1];
+        terrainNormals[count + 2] = normal[2];
+
+        base_count += 3;
+        count += 3;
+
+        for(i = 1; i < (widthPoints - 1); i++)
+        {
+            calcSideAverageNormal(terrainCoordinates,
+                                  base_count,
+                                  base_count - 3,
+                                  base_count - width_inc,
+                                  base_count + 3);
+
+            terrainNormals[count] = normal[0];
+            terrainNormals[count + 1] = normal[1];
+            terrainNormals[count + 2] = normal[2];
+
+            base_count += 3;
+            count += 3;
+        }
+
+        // Last corner point of the first row
+        createFaceNormal(terrainCoordinates,
+                         base_count,
+                         base_count - 3,
+                         base_count - width_inc);
+
+        terrainNormals[count] = normal[0];
+        terrainNormals[count + 1] = normal[1];
+        terrainNormals[count + 2] = normal[2];
+    }
+*/
+    /**
+     * Convenience method to calculate the average normal value between
+     * two quads - ie along the side of an object
+     *
+     * @param coords The coordinates to generate from
+     * @param p The centre point
+     * @param p1 The first point of the first side
+     * @param p2 The middle, shared side point
+     * @param p3 The last point of the second side
+     * @return The averaged vector
+     */
+    private void calcSideAverageNormal(float[] coords,
+                                       int p,
+                                       int p1,
+                                       int p2,
+                                       int p3)
+    {
+        float x, y, z;
+
+        // Normal first for the previous quad
+        createFaceNormal(coords, p, p1, p2);
+        x = normal[0];
+        y = normal[1];
+        z = normal[2];
+
+        // Normal for the next quad
+        createFaceNormal(coords, p, p2, p3);
+
+        // create the average of each compoenent for the final normal
+        normal[0] = (normal[0] + x) * 0.5f;
+        normal[1] = (normal[1] + y) * 0.5f;
+        normal[2] = (normal[2] + z) * 0.5f;
+
+        float mag = normal[0] * normal[0] +
+                    normal[1] * normal[1] +
+                    normal[2] * normal[2];
+
+        if(mag != 0.0f)
+        {
+            mag = 1.0f / ((float) Math.sqrt(mag));
+            normal[0] = normal[0] * mag;
+            normal[1] = normal[1] * mag;
+            normal[2] = normal[2] * mag;
+        }
+        else
+        {
+            normal[0] = 0;
+            normal[1] = 0;
+            normal[2] = 0;
+        }
+    }
+
+    /**
+     * Convenience method to create quad average normal amongst four
+     * quads based around a common centre point (the one having the normal
+     * calculated).
+     *
+     * @param coords The coordinates to generate from
+     * @param p The centre point
+     * @param p1 shared point between first and last quad
+     * @param p2 shared point between first and second quad
+     * @param p3 shared point between second and third quad
+     * @param p4 shared point between third and fourth quad
+     * @return The averaged vector
+     */
+    private void calcQuadAverageNormal(float[] coords,
+                                       int p,
+                                       int p1,
+                                       int p2,
+                                       int p3,
+                                       int p4)
+    {
+        float x, y, z;
+
+        // Normal first for quads 1 & 2
+        createFaceNormal(coords, p, p2, p1);
+        x = normal[0];
+        y = normal[1];
+        z = normal[2];
+
+        // Normal for the quads 2 & 3
+        createFaceNormal(coords, p, p2, p3);
+        x += normal[0];
+        y += normal[1];
+        z += normal[2];
+
+        // Normal for quads 3 & 4
+        createFaceNormal(coords, p, p3, p4);
+        x += normal[0];
+        y += normal[1];
+        z += normal[2];
+
+        // Normal for quads 1 & 4
+        createFaceNormal(coords, p, p4, p1);
+
+        // create the average of each compoenent for the final normal
+        normal[0] = (normal[0] + x) * 0.25f;
+        normal[1] = (normal[1] + y) * 0.25f;
+        normal[2] = (normal[2] + z) * 0.25f;
+
+        float mag = normal[0] * normal[0] +
+                    normal[1] * normal[1] +
+                    normal[2] * normal[2];
+
+        if(mag != 0.0f)
+        {
+            mag = 1.0f / ((float) Math.sqrt(mag));
+            normal[0] = normal[0] * mag;
+            normal[1] = normal[1] * mag;
+            normal[2] = normal[2] * mag;
+        }
+        else
+        {
+            normal[0] = 0;
+            normal[1] = 0;
+            normal[2] = 0;
+        }
+    }
+
+    /**
+     * Regenerate the texture coordinate points.
+     * Assumes regenerateBase has been called before this
+     */
+    private void regenerateTexcoords()
+    {
+        numTexcoordValues = widthPoints * depthPoints * 2;
+        terrainTexcoords = new float[numTexcoordValues];
+
+        float d = 0;
+        float w = 0;
+        float width_inc = 1.0f / (widthPoints - 1);
+        float depth_inc = 1.0f / (depthPoints - 1);
+
+        int count = 0;
+
+        if(flatHeights != null)
+        {
+            int num = numTerrainValues / 3;
+            for(int i = 1; i <= num; i++)
+            {
+
+                terrainTexcoords[count++] = w;
+                terrainTexcoords[count++] = d;
+                w += width_inc;
+
+                if(((i % (widthPoints)) == 0))
+                {
+                    d += depth_inc;
+                    w = 0;
+                }
+            }
+        }
+        else
+        {
+            for(int i = 0; i < depthPoints; i++)
+            {
+                for(int j = 0;  j < widthPoints; j++)
+                {
+
+                    terrainTexcoords[count++] = w;
+                    terrainTexcoords[count++] = d;
+
+
+                    w += width_inc;
+                }
+
+                d += depth_inc;
+                w = 0;
+            }
+        }
+    }
+
+    /**
+     * Convenience method to create a normal for the given vertex coordinates
+     * and normal array. This performs a cross product of the two vectors
+     * described by the middle and two end points.
+     *
+     * @param coords The coordinate array to read values from
+     * @param p The index of the middle point
+     * @param p1 The index of the first point
+     * @param p2 The index of the second point
+     * @return A temporary value containing the normal value
+     */
+    private void createFaceNormal(float[] coords, int p, int p1, int p2)
+    {
+        float x1 = coords[p1]     - coords[p];
+        float y1 = coords[p1 + 1] - coords[p + 1];
+        float z1 = coords[p1 + 2] - coords[p + 2];
+
+        float x2 = coords[p]     - coords[p2];
+        float y2 = coords[p + 1] - coords[p2 + 1];
+        float z2 = coords[p + 2] - coords[p2 + 2];
+
+        float x = y1 * z2 - z1 * y2;
+        float y = z1 * x2 - x1 * z2;
+        float z = x1 * y2 - y1 * x2;
+
+        float mag = x * x + y * y + z * z;
+
+// TODO: Flipping normals, not sure why this is needed
+        if(mag != 0.0f)
+        {
+            mag = 1.0f / ((float) Math.sqrt(mag));
+            normal[0] = -x * mag;
+            normal[1] = -y * mag;
+            normal[2] = -z * mag;
+        }
+        else
+        {
+            normal[0] = 0;
+            normal[1] = 0;
+            normal[2] = 0;
+        }
+    }
+
+    /**
+     * Regenerate the base normals points. These are the flat circle that
+     * makes up the base of the code. The normals are generated based the
+     * smoothing of normal averages for interior points. Around the edges,
+     * we use the average of the edge value polygons.
+     */
+    private void regenerateNormals(float[] coords, float[] normals)
+    {
+        int count = 0;
+        int base_count;
+        int i, j;
+        int width_inc = widthPoints * 3;
+
+        // The first edge
+        // corner point - normal based on only that face
+        createFaceNormal(coords, width_inc, 0, 3);
+
+        normals[count++] = normal[0];
+        normals[count++] = normal[1];
+        normals[count++] = normal[2];
+
+        base_count = 3;
+
+        for(i = 1; i < (widthPoints - 1); i++)
+        {
+            calcSideAverageNormal(coords,
+                                         base_count,
+                                         base_count + 3,
+                                         base_count + width_inc,
+                                         base_count - 3);
+
+            normals[count++] = normal[0];
+            normals[count++] = normal[1];
+            normals[count++] = normal[2];
+
+            base_count += 3;
+        }
+
+        // Last corner point of the first row
+        createFaceNormal(coords,
+                                base_count,
+                                base_count + width_inc,
+                                base_count - 3);
+
+        normals[count++] = normal[0];
+        normals[count++] = normal[1];
+        normals[count++] = normal[2];
+
+        base_count += 3;
+
+        // Now, process all of the internal points
+        for(i = 1; i < (depthPoints - 1); i++)
+        {
+
+            calcSideAverageNormal(coords,
+                                         base_count,
+                                         base_count - width_inc,
+                                         base_count + 3,
+                                         base_count + width_inc);
+
+            normals[count++] = normal[0];
+            normals[count++] = normal[1];
+            normals[count++] = normal[2];
+
+            base_count += 3;
+
+            for(j = 1; j < (widthPoints - 1); j++)
+            {
+
+                calcQuadAverageNormal(coords,
+                                             base_count,
+                                             base_count + 3,
+                                             base_count + width_inc,
+                                             base_count - 3,
+                                             base_count - width_inc);
+
+                normals[count++] = normal[0];
+                normals[count++] = normal[1];
+                normals[count++] = normal[2];
+
+                base_count += 3;
+            }
+
+            // Last point of the row
+            calcSideAverageNormal(coords,
+                                         base_count,
+                                         base_count + width_inc,
+                                         base_count - 3,
+                                         base_count - width_inc);
+
+            normals[count++] = normal[0];
+            normals[count++] = normal[1];
+            normals[count++] = normal[2];
+
+            base_count += 3;
+        }
+
+        // The last edge
+        // corner point - normal based on only that face
+        createFaceNormal(coords,
+                                base_count,
+                                base_count - width_inc,
+                                base_count + 3);
+
+        normals[count++] = normal[0];
+        normals[count++] = normal[1];
+        normals[count++] = normal[2];
+
+        base_count += 3;
+
+        for(i = 1; i < (widthPoints - 1); i++)
+        {
+            calcSideAverageNormal(coords,
+                                         base_count,
+                                         base_count - 3,
+                                         base_count - width_inc,
+                                         base_count + 3);
+
+            normals[count++] = normal[0];
+            normals[count++] = normal[1];
+            normals[count++] = normal[2];
+
+            base_count += 3;
+        }
+
+        // Last corner point of the first row
+        createFaceNormal(coords,
+                                base_count,
+                                base_count - 3,
+                                base_count - width_inc);
+
+        normals[count++] = normal[0];
+        normals[count++] = normal[1];
+        normals[count++] = normal[2];
+    }
+
+    // Float pretty printer
+
+    private String pp(float[] num, int places) {
+        StringBuilder buff = new StringBuilder();
+
+        for (int j=0; j < num.length; j++) {
+            String sfloat = Float.toString(num[j]);
+
+            int needs = places - sfloat.length();
+
+            if (needs == 0) {
+                buff.append(sfloat);
+                buff.append(" ");
+            } else if (needs < 0) {
+                buff.append(sfloat.substring(0,places));
+                buff.append(" ");
+            } else {
+                for(int i=0; i < needs; i++) {
+                    sfloat += " ";
+                }
+
+                buff.append(sfloat);
+                buff.append(" ");
+            }
+        }
+
+        return buff.toString();
+    }
+
+}
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/SceneWrapper.java b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/SceneWrapper.java
index 7bdd494812eef9fe5bbb127f8ca90abb8fceb8e3..6ff8c18b75d9a4d83c5c640bd0d99a9598ed04ce 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/SceneWrapper.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/geospatial/SceneWrapper.java
@@ -1,58 +1,58 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2005
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.renderer.common.nodes.geospatial;
-
-// External imports
-
-// Local imports
-import org.web3d.vrml.lang.*;
-import org.web3d.vrml.nodes.*;
-
-
-/**
- * Wraps a scene as a VRMLExecutionSpace.
- *
- * @author Alan Hudson
- * @version $Revision: 1.2 $
- */
-public class SceneWrapper implements VRMLExecutionSpace {
-
-    /** The scene being wrapped */
-    private BasicScene scene;
-
-    /**
-     *
-     * @param scene
-     */
-    public SceneWrapper(VRMLScene scene) {
-        this.scene = scene;
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by VRMLExecutionSpace
-    //----------------------------------------------------------
-
-    /**
-     * Get the contained scene graph that this instance has. This represents
-     * everything about the internal scene that the node declaration wraps.
-     * This is a real-time representation so that if it the nodes contains a
-     * script that changes the internal representation then this instance will
-     * be updated to reflect and changes made.
-     *
-     * @return The scene contained by this node instance
-     */
-    @Override
-    public BasicScene getContainedScene() {
-        return scene;
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2005
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.renderer.common.nodes.geospatial;
+
+// External imports
+
+// Local imports
+import org.web3d.vrml.lang.*;
+import org.web3d.vrml.nodes.*;
+
+
+/**
+ * Wraps a scene as a VRMLExecutionSpace.
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.2 $
+ */
+public class SceneWrapper implements VRMLExecutionSpace {
+
+    /** The scene being wrapped */
+    private BasicScene scene;
+
+    /**
+     *
+     * @param scene
+     */
+    public SceneWrapper(VRMLScene scene) {
+        this.scene = scene;
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by VRMLExecutionSpace
+    //----------------------------------------------------------
+
+    /**
+     * Get the contained scene graph that this instance has. This represents
+     * everything about the internal scene that the node declaration wraps.
+     * This is a real-time representation so that if it the nodes contains a
+     * script that changes the internal representation then this instance will
+     * be updated to reflect and changes made.
+     *
+     * @return The scene contained by this node instance
+     */
+    @Override
+    public BasicScene getContainedScene() {
+        return scene;
+    }
+}
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/group/BaseGroup.java b/src/java/org/web3d/vrml/renderer/common/nodes/group/BaseGroup.java
index 81502329443bd27aa376638bb4780901218e803d..4f8c87df8c7f7204a46c11a266f6e71591b866ed 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/group/BaseGroup.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/group/BaseGroup.java
@@ -25,6 +25,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseGroupingNode;
 
 /**
  * Common base implementation of a group node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.6 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/group/BaseOrderedGroup.java b/src/java/org/web3d/vrml/renderer/common/nodes/group/BaseOrderedGroup.java
index 782e165a781e8ab936746dc29845297e1598ed91..32f0c9c6e803783568eb2afee10ad92abab28825 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/group/BaseOrderedGroup.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/group/BaseOrderedGroup.java
@@ -25,6 +25,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseGroupingNode;
 
 /**
  * Common implementation of an ordered group node functionality.
+ * <p>
  *
  * An ordered group controls the order of rendering of the children. These
  * are rendered in the order given by the childOrder field. The children
@@ -34,6 +35,8 @@ import org.web3d.vrml.renderer.common.nodes.BaseGroupingNode;
  * the order list contains more items than the current children list, it will
  * silently ignore any items that are greater in index than the number of
  * items.
+ * <p>
+ *
  *
  * @author Justin Couch
  * @version $Revision: 1.7 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/group/BaseSwitch.java b/src/java/org/web3d/vrml/renderer/common/nodes/group/BaseSwitch.java
index 4ff2582ff615d8c42c954b195b25cd46ff915d3a..6313e8b78d80d1ca77861f3bae77e3186b740cb0 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/group/BaseSwitch.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/group/BaseSwitch.java
@@ -25,19 +25,18 @@ import org.web3d.vrml.nodes.VRMLFieldData;
 import org.web3d.vrml.renderer.common.nodes.BaseGroupingNode;
 
 /**
- * <p>
  * common version of a Switch node.
- * </p>
  * <p>
+ *
  * This code assigns a LOD node as the implGroup. As this code is a
  * grouping node, we allow the use of the children being specified as
  * either the <code>childre</code> field or the <code>level</code> field.
  * The former is VRML3.0 and the latter VRML 2.0
- * </p>
  * <p>
+ *
  * The LOD Behavior node is kept as a child of the group node that works
  * here. When the VRML node is removed from the scene, the behavior is too.
- * When the behavior is asked to be disabled, we just call the
+ * When the behaivor is asked to be disabled, we just call the
  * <code>setEnable</code> method on the behavior, we do not remove it.
  * <p>
  * If someone routes a range change to us, then we see if it is the same
@@ -47,6 +46,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseGroupingNode;
  * is greater than the number of children nodes, we disable the behavior until
  * the number of children increase to the correct amount. In the branchgroup,
  * the behavior is always
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.9 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/interpolator/BaseScalarInterpolator.java b/src/java/org/web3d/vrml/renderer/common/nodes/interpolator/BaseScalarInterpolator.java
index d76aca4acd778f3e138a9ef2978e9cd7e9ab1a00..7973c2d14442aca6ff128e5c99544d197efb795d 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/interpolator/BaseScalarInterpolator.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/interpolator/BaseScalarInterpolator.java
@@ -30,6 +30,8 @@ import org.web3d.vrml.renderer.common.nodes.BaseInterpolatorNode;
 /**
  * Abstract implementation of a scalar interpolator so that specific
  * renderer instances can derive from it.
+ * <p>
+ *
  *
  * @author Justin Couch
  * @version $Revision: 1.15 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/layout/BaseGridLayout.java b/src/java/org/web3d/vrml/renderer/common/nodes/layout/BaseGridLayout.java
index 5f9595bf416da1f95b0619c9c39fd5328e46ffa5..3192969d1943a0b0955b6044adc090957fa2fd94 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/layout/BaseGridLayout.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/layout/BaseGridLayout.java
@@ -28,6 +28,7 @@ import org.web3d.vrml.nodes.VRMLSurfaceLayoutNodeType;
 
 /**
  * Common implementation of a GridLayout node.
+ * <p>
  *
  * A grid layout places the contained children in a 2 dimensional grid of
  * rows and columns. The number of grid items can be changed on the fly.
@@ -35,6 +36,7 @@ import org.web3d.vrml.nodes.VRMLSurfaceLayoutNodeType;
  * the extra children are not rendered. If less children than the number
  * of cells defined are provided then it fills in across the row first and
  * then down the columns.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/layout/BaseGroupLayout.java b/src/java/org/web3d/vrml/renderer/common/nodes/layout/BaseGroupLayout.java
index 3e8a3b16b37d59529366618e868a368a9962ea2d..d8b955e50b19a2cbc12eb9c85333348b992fd335 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/layout/BaseGroupLayout.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/layout/BaseGroupLayout.java
@@ -25,11 +25,13 @@ import org.web3d.vrml.nodes.VRMLSurfaceChildNodeType;
 
 /**
  * Common implementation of a GroupLayout node.
+ * <p>
  *
  * A group layout is a container for allowing the use of more than one
  * child layout. Typically used to group a bunch of BorderLayouts together
  * under the Overlay node. It has no additional properties beyond the simple
  * layout capabilities.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/layout/BaseImage2D.java b/src/java/org/web3d/vrml/renderer/common/nodes/layout/BaseImage2D.java
index 11931337b9890e8c0168e74492b9dde04cc92518..6901e8a930f98eb2ddbcdbd6d4bad8452a42e5cd 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/layout/BaseImage2D.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/layout/BaseImage2D.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.nodes.*;
 
 /**
  * Common implementation of a Image2D node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/layout/BaseXYLayout.java b/src/java/org/web3d/vrml/renderer/common/nodes/layout/BaseXYLayout.java
index 6ee907481db60c119dd5ee80c19b430eec1e92be..e4cfaec3ab0c042493031f22fac781864c16388d 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/layout/BaseXYLayout.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/layout/BaseXYLayout.java
@@ -27,10 +27,13 @@ import org.web3d.vrml.nodes.VRMLSurfaceChildNodeType;
 
 /**
  * Common implementation of a XYLayout node.
+ * <p>
  *
  * An XY layout places its children in relative positions to its layout location.
  * So a position of 0,64 would place the child 64 units down from the layout 0,0.
  *
+ * <p>
+ *
  * @author Alan Hudson
  * @version $Revision: 1.2 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/lighting/BaseDirectionalLight.java b/src/java/org/web3d/vrml/renderer/common/nodes/lighting/BaseDirectionalLight.java
index 9164f6a7e36a92921300b8db84f2c8259593dc8e..5e14d2b93aedc4935bc9e02dc8287661d946a01a 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/lighting/BaseDirectionalLight.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/lighting/BaseDirectionalLight.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseLightNode;
 
 /**
  * Common implementation code of a directional light.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.11 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/lighting/BasePointLight.java b/src/java/org/web3d/vrml/renderer/common/nodes/lighting/BasePointLight.java
index cdc8c5d7f654dbb57ca2d5695bc87c79f30f56a2..d8266b781883ced680688e278279b235460d89f9 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/lighting/BasePointLight.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/lighting/BasePointLight.java
@@ -26,6 +26,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseLightNode;
 
 /**
  * Common base implementation of a PointLight node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.10 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/lighting/BaseSpotLight.java b/src/java/org/web3d/vrml/renderer/common/nodes/lighting/BaseSpotLight.java
index e3223b84e0c7b57754f86c62f5444074a766c50d..c334d75c5863d1dc1513c61649576619bdc09942 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/lighting/BaseSpotLight.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/lighting/BaseSpotLight.java
@@ -26,6 +26,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseLightNode;
 
 /**
  * Common implementation code for a SpotLight node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.13 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/marker/BaseScreenMarker.java b/src/java/org/web3d/vrml/renderer/common/nodes/marker/BaseScreenMarker.java
index 1e9f727bb8a7c9578cbf295efd7186df8d8ca744..b6d253d1484fa6b679ff482be597d1aff5edcaaa 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/marker/BaseScreenMarker.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/marker/BaseScreenMarker.java
@@ -28,6 +28,7 @@ import org.web3d.vrml.util.URLChecker;
 
 /**
  * Common implementation of a ScreenMarker node.
+ * <p>
  *
  * @author Rex Melton
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/navigation/BaseBillboard.java b/src/java/org/web3d/vrml/renderer/common/nodes/navigation/BaseBillboard.java
index a3032f714ced0b49f7b25dc9a752fab306eccd17..69ad6f769e46e0989aeba598fb4a97da01c1b477 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/navigation/BaseBillboard.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/navigation/BaseBillboard.java
@@ -27,6 +27,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseGroupingNode;
 
 /**
  * Common base implementation of a billboard node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.9 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/navigation/BaseCollision.java b/src/java/org/web3d/vrml/renderer/common/nodes/navigation/BaseCollision.java
index adfc8ff51bc55dfc2fa50a1a27ace40cdc48e157..eaab388d1a16bcc45cb6788f270bdd95b4fe7a1a 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/navigation/BaseCollision.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/navigation/BaseCollision.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseGroupingNode;
 
 /**
  * Common base implementation of a Collision node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.16 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/navigation/BaseNavigationInfo.java b/src/java/org/web3d/vrml/renderer/common/nodes/navigation/BaseNavigationInfo.java
index 2357fec1189bcfc729ad05018d15e957d566e97f..f8106b25f3eed635fe74d08a711bc536585dcb7a 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/navigation/BaseNavigationInfo.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/navigation/BaseNavigationInfo.java
@@ -31,7 +31,8 @@ import org.web3d.vrml.renderer.common.nodes.BaseBindableNode;
 
 /**
  * Common base implementation of a NavigationInfo node.
- * 
+ * <p>
+ *
  * @author Justin Couch
  * @version $Revision: 1.25 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/nurbs/BaseContourPolyline2D.java b/src/java/org/web3d/vrml/renderer/common/nodes/nurbs/BaseContourPolyline2D.java
index 26455a349620ac96760defa77ecb11f9da296666..1aff12f0f1ef2a0f7dbf2d9bb0c4776796adb447 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/nurbs/BaseContourPolyline2D.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/nurbs/BaseContourPolyline2D.java
@@ -1,468 +1,468 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.renderer.common.nodes.nurbs;
-
-// External imports
-import java.util.HashMap;
-import java.util.Map;
-
-// Local imports
-import org.web3d.vrml.lang.*;
-
-import org.web3d.vrml.nodes.*;
-import org.web3d.vrml.renderer.common.nodes.AbstractNode;
-
-/**
- * Common base implementation of the NurbsCurve node.
- * <p>
- *
- * Because NURBS implementations involve complex retessellation,
- * the implementation will automatically register itself with the
- * frame state manager whenever any field changes.
- *
- * @author Justin Couch
- * @version $Revision: 1.2 $
- */
-public abstract class BaseContourPolyline2D extends AbstractNode
-    implements VRMLParametricGeometryNodeType {
-
-    /** Field index for controlPoint */
-    protected static final int FIELD_CONTROL_POINT = LAST_NODE_INDEX + 1;
-
-    /** The last index in this node */
-    protected static final int LAST_CURVE_INDEX = FIELD_CONTROL_POINT;
-
-    /** Number of fields constant */
-    protected static final int NUM_FIELDS = LAST_CURVE_INDEX + 1;
-
-
-    /** Array of VRMLFieldDeclarations */
-    private static VRMLFieldDeclaration[] fieldDecl;
-
-    /** Hashmap between a field name and its index */
-    private static final Map<String, Integer> fieldMap;
-
-    /** Listing of field indexes that have nodes */
-    private static int[] nodeFields;
-
-    // VRML Field declarations
-
-    /** The value of the controlPoint field */
-    protected double[] vfControlPoint;
-
-
-    /** Flag indicating if the control points have changed since last update */
-    private boolean controlPointsChanged;
-
-    // Static constructor
-    static {
-        nodeFields = new int[] { FIELD_METADATA };
-
-        fieldDecl = new VRMLFieldDeclaration[NUM_FIELDS];
-        fieldMap = new HashMap<>(NUM_FIELDS);
-
-        fieldDecl[FIELD_METADATA] =
-            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
-                                     "SFNode",
-                                     "metadata");
-        fieldDecl[FIELD_CONTROL_POINT] =
-            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
-                                 "MFVec2d",
-                                 "controlPoint");
-
-        Integer idx = FIELD_METADATA;
-        fieldMap.put("metadata", idx);
-        fieldMap.put("set_metadata", idx);
-        fieldMap.put("metadata_changed", idx);
-
-        idx = FIELD_CONTROL_POINT;
-        fieldMap.put("controlPoint", idx);
-        fieldMap.put("set_controlPoint", idx);
-        fieldMap.put("controlPoint_changed", idx);
-
-    }
-
-    /**
-     * Create a new default instance of the node.
-     */
-    protected BaseContourPolyline2D() {
-        super("ContourPolyline2D");
-
-        hasChanged = new boolean[NUM_FIELDS];
-        vfControlPoint = new double[0];
-
-        controlPointsChanged = false;
-    }
-
-    /**
-     * Construct a new instance of this node based on the details from the
-     * given node. If the node is not a Box node, an exception will be
-     * thrown.
-     *
-     * @param node The node to copy
-     * @throws IllegalArgumentException The node is not a Group node
-     */
-    public BaseContourPolyline2D(VRMLNodeType node) {
-        this(); // invoke default constructor
-
-        checkNodeType(node);
-
-        try {
-            int index = node.getFieldIndex("controlPoint");
-            VRMLFieldData field = node.getFieldValue(index);
-            if(field.numElements != 0) {
-                vfControlPoint = new double[field.numElements * 4];
-                System.arraycopy(field.doubleArrayValues,
-                                 0,
-                                 vfControlPoint,
-                                 0,
-                                 field.numElements);
-            }
-
-        } catch(VRMLException ve) {
-            throw new IllegalArgumentException(ve.getMessage());
-        }
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by VRMLGeometryNodeType
-    //----------------------------------------------------------
-
-    /**
-     * Specified whether this node has color information.  If so, then it
-     * will be used for diffuse terms instead of materials.
-     *
-     * @return true Use local color information for diffuse lighting.
-     */
-    @Override
-    public boolean hasLocalColors() {
-        return false;
-    }
-
-    /**
-     * Specified whether this node has alpha values in the local colour
-     * information. If so, then it will be used for to override the material's
-     * transparency value.
-     *
-     * @return true when the local color value has inbuilt alpha
-     */
-    @Override
-    public boolean hasLocalColorAlpha() {
-        return false;
-    }
-
-    /**
-     * Add a listener for local color changes.  Nulls and duplicates will be ignored.
-     *
-     * @param l The listener.
-     */
-    @Override
-    public void addLocalColorsListener(LocalColorsListener l) {
-    }
-
-    /**
-     * Remove a listener for local color changes.  Nulls will be ignored.
-     *
-     * @param l The listener.
-     */
-    @Override
-    public void removeLocalColorsListener(LocalColorsListener l) {
-    }
-
-    /**
-     * Add a listener for texture coordinate generation mode changes.
-     * Nulls and duplicates will be ignored.
-     *
-     * @param l The listener.
-     */
-    @Override
-    public void addTexCoordGenModeChanged(TexCoordGenModeListener l) {
-    }
-
-    /**
-     * Remove a listener for texture coordinate generation mode changes.
-     * Nulls will be ignored.
-     *
-     * @param l The listener.
-     */
-    @Override
-    public void removeTexCoordGenModeChanged(TexCoordGenModeListener l) {
-    }
-
-    /**
-     * Get the texture coordinate generation mode.  NULL is returned
-     * if the texture coordinates are not generated.
-     *
-     * @param setNum The set which this tex gen mode refers
-     * @return The mode or NULL
-     */
-    @Override
-    public String getTexCoordGenMode(int setNum) {
-        return null;
-    }
-
-    /**
-     * Set the number of textures that were found on the accompanying Appearance
-     * node. Used to set the number of texture coordinates that need to be
-     * passed in to the renderer when no explicit texture coordinates were
-     * given.
-     *     * @param count The number of texture coordinate sets to add
-     */
-    @Override
-    public void setTextureCount(int count) {
-        // default implementation does nothing
-    }
-
-
-    /**
-     * Get the number of texture coordinate sets contained by this node
-     *
-     * @return the number of texture coordinate sets
-     */
-    @Override
-    public int getNumSets() {
-        return 0;
-    }
-
-    /**
-     * Get the value of the solid field.
-     *
-     * @return true This object is solid (ie single sided)
-     */
-    @Override
-    public boolean isSolid() {
-        return false;
-    }
-
-    /**
-     * Get the value of the CCW field. If the node does not have one, this will
-     * return true.
-     *
-     * @return true if the vertices are CCW ordered
-     */
-    @Override
-    public boolean isCCW() {
-        return true;
-    }
-
-    /**
-     * Specifies whether this node requires lighting.
-     *
-     * @return Should lighting be enabled
-     */
-    @Override
-    public boolean isLightingEnabled() {
-        return true;
-    }
-
-    //----------------------------------------------------------
-    // Methods required by the VRMLNodeType interface.
-    //----------------------------------------------------------
-
-    /**
-     * Get the index of the given field name. If the name does not exist for
-     * this node then return a value of -1.
-     *
-     * @param fieldName The name of the field we want the index from
-     * @return The index of the field name or -1
-     */
-    @Override
-    public int getFieldIndex(String fieldName) {
-        Integer index = fieldMap.get(fieldName);
-
-        return (index == null) ? -1 : index;
-    }
-
-    /**
-     * Get the list of indices that correspond to fields that contain nodes
-     * ie MFNode and SFNode). Used for blind scene graph traversal without
-     * needing to spend time querying for all fields etc. If a node does
-     * not have any fields that contain nodes, this shall return null. The
-     * field list covers all field types, regardless of whether they are
-     * readable or not at the VRML-level.
-     *
-     * @return The list of field indices that correspond to SF/MFnode fields
-     *    or null if none
-     */
-    @Override
-    public int[] getNodeFieldIndices() {
-        return nodeFields;
-    }
-
-    /**
-     * Get the declaration of the field at the given index. This allows for
-     * reverse lookup if needed. If the field does not exist, this will give
-     * a value of null.
-     *
-     * @param index The index of the field to get information
-     * @return A representation of this field's information
-     */
-    @Override
-    public VRMLFieldDeclaration getFieldDeclaration(int index) {
-        if(index < 0  || index > LAST_CURVE_INDEX)
-            return null;
-
-        return fieldDecl[index];
-    }
-
-    /**
-     * Get the number of fields.
-     *
-     * @return The number of fields.
-     */
-    @Override
-    public int getNumFields() {
-        return fieldDecl.length;
-    }
-
-    /**
-     * Get the primary type of this node.  Replaces the instanceof mechanism
-     * for use in switch statements.
-     *
-     * @return The primary type
-     */
-    @Override
-    public int getPrimaryType() {
-        return TypeConstants.ParametricGeometryNodeType;
-    }
-
-
-    /**
-     * Get the value of a field. If the field is a primitive type, it will
-     * return a class representing the value. For arrays or nodes it will
-     * return the instance directly.
-     *
-     * @param index The index of the field to change.
-     * @return The class representing the field value
-     * @throws InvalidFieldException The field index is not known
-     */
-    @Override
-    public VRMLFieldData getFieldValue(int index) throws InvalidFieldException {
-        VRMLFieldData fieldData = fieldLocalData.get();
-
-        switch(index) {
-            case FIELD_CONTROL_POINT:
-                fieldData.clear();
-                fieldData.doubleArrayValues = vfControlPoint;
-                fieldData.dataType = VRMLFieldData.DOUBLE_ARRAY_DATA;
-                fieldData.numElements = vfControlPoint == null ? 0 :
-                                        vfControlPoint.length / 4;
-                break;
-
-
-            default:
-                super.getFieldValue(index);
-        }
-
-        return fieldData;
-    }
-
-    /**
-     * Send a routed value from this node to the given destination node. The
-     * route should use the appropriate setValue() method of the destination
-     * node. It should not attempt to cast the node up to a higher level.
-     * Routing should also follow the standard rules for the loop breaking and
-     * other appropriate rules for the specification.
-     *
-     * @param time The time that this route occurred (not necessarily epoch
-     *   time. Should be treated as a relative value only)
-     * @param srcIndex The index of the field in this node that the value
-     *   should be sent from
-     * @param destNode The node reference that we will be sending the value to
-     * @param destIndex The index of the field in the destination node that
-     *   the value should be sent to.
-     */
-    @Override
-    public void sendRoute(double time,
-                          int srcIndex,
-                          VRMLNodeType destNode,
-                          int destIndex) {
-
-        // Simple impl for now.  ignores time and looping
-        try {
-            switch(srcIndex) {
-                case FIELD_CONTROL_POINT:
-                    destNode.setValue(destIndex, vfControlPoint, vfControlPoint.length);
-                    break;
-
-
-                default:
-                    super.sendRoute(time, srcIndex, destNode, destIndex);
-            }
-        } catch(InvalidFieldException ife) {
-            System.err.println("sendRoute: No field!" + ife.getFieldName());
-        } catch(InvalidFieldValueException ifve) {
-            System.err.println("sendRoute: Invalid field value: " +
-                ifve.getMessage());
-        }
-    }
-
-
-    /**
-     * Set the value of the field at the given index as an array of doubles.
-     * This would be used to set MFDouble field types.
-     *
-     * @param index The index of destination field to set
-     * @param value The new value to use for the node
-     * @throws InvalidFieldException The field index is not know
-     */
-    @Override
-    public void setValue(int index, double[] value, int numValid)
-        throws InvalidFieldException, InvalidFieldValueException {
-
-        switch(index) {
-
-            case FIELD_CONTROL_POINT:
-                setControlPoints(value);
-                break;
-
-            default:
-                super.setValue(index, value, numValid);
-        }
-    }
-
-
-	@Override
-	public void setupFinished() {
-        super.setupFinished();
-    }
-
-    //-------------------------------------------------------------
-    // Internal convenience methods
-    //-------------------------------------------------------------
-
-
-    /**
-     * Internal convenience method to setup the control points.
-     *
-     * @param points The new point array to use
-     */
-    private void setControlPoints(double[] points) {
-        int num_points = 0;
-        if(points != null) {
-            vfControlPoint = new double[points.length];
-            num_points = points.length;
-        }
-
-        if(num_points != 0)
-            System.arraycopy(points, 0, vfControlPoint, 0, num_points);
-
-        if(!inSetup) {
-            controlPointsChanged = true;
-            stateManager.addEndOfThisFrameListener(this);
-            hasChanged[FIELD_CONTROL_POINT] = true;
-            fireFieldChanged(FIELD_CONTROL_POINT);
-        }
-    }
-
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.renderer.common.nodes.nurbs;
+
+// External imports
+import java.util.HashMap;
+import java.util.Map;
+
+// Local imports
+import org.web3d.vrml.lang.*;
+
+import org.web3d.vrml.nodes.*;
+import org.web3d.vrml.renderer.common.nodes.AbstractNode;
+
+/**
+ * Common base implementation of the NurbsCurve node.
+ * <p>
+ *
+ * Because NURBS implementations involve complex retessellation,
+ * the implementation will automatically register itself with the
+ * frame state manager whenever any field changes.
+ *
+ * @author Justin Couch
+ * @version $Revision: 1.2 $
+ */
+public abstract class BaseContourPolyline2D extends AbstractNode
+    implements VRMLParametricGeometryNodeType {
+
+    /** Field index for controlPoint */
+    protected static final int FIELD_CONTROL_POINT = LAST_NODE_INDEX + 1;
+
+    /** The last index in this node */
+    protected static final int LAST_CURVE_INDEX = FIELD_CONTROL_POINT;
+
+    /** Number of fields constant */
+    protected static final int NUM_FIELDS = LAST_CURVE_INDEX + 1;
+
+
+    /** Array of VRMLFieldDeclarations */
+    private static VRMLFieldDeclaration[] fieldDecl;
+
+    /** Hashmap between a field name and its index */
+    private static final Map<String, Integer> fieldMap;
+
+    /** Listing of field indexes that have nodes */
+    private static int[] nodeFields;
+
+    // VRML Field declarations
+
+    /** The value of the controlPoint field */
+    protected double[] vfControlPoint;
+
+
+    /** Flag indicating if the control points have changed since last update */
+    private boolean controlPointsChanged;
+
+    // Static constructor
+    static {
+        nodeFields = new int[] { FIELD_METADATA };
+
+        fieldDecl = new VRMLFieldDeclaration[NUM_FIELDS];
+        fieldMap = new HashMap<>(NUM_FIELDS);
+
+        fieldDecl[FIELD_METADATA] =
+            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
+                                     "SFNode",
+                                     "metadata");
+        fieldDecl[FIELD_CONTROL_POINT] =
+            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
+                                 "MFVec2d",
+                                 "controlPoint");
+
+        Integer idx = FIELD_METADATA;
+        fieldMap.put("metadata", idx);
+        fieldMap.put("set_metadata", idx);
+        fieldMap.put("metadata_changed", idx);
+
+        idx = FIELD_CONTROL_POINT;
+        fieldMap.put("controlPoint", idx);
+        fieldMap.put("set_controlPoint", idx);
+        fieldMap.put("controlPoint_changed", idx);
+
+    }
+
+    /**
+     * Create a new default instance of the node.
+     */
+    protected BaseContourPolyline2D() {
+        super("ContourPolyline2D");
+
+        hasChanged = new boolean[NUM_FIELDS];
+        vfControlPoint = new double[0];
+
+        controlPointsChanged = false;
+    }
+
+    /**
+     * Construct a new instance of this node based on the details from the
+     * given node. If the node is not a Box node, an exception will be
+     * thrown.
+     *
+     * @param node The node to copy
+     * @throws IllegalArgumentException The node is not a Group node
+     */
+    public BaseContourPolyline2D(VRMLNodeType node) {
+        this(); // invoke default constructor
+
+        checkNodeType(node);
+
+        try {
+            int index = node.getFieldIndex("controlPoint");
+            VRMLFieldData field = node.getFieldValue(index);
+            if(field.numElements != 0) {
+                vfControlPoint = new double[field.numElements * 4];
+                System.arraycopy(field.doubleArrayValues,
+                                 0,
+                                 vfControlPoint,
+                                 0,
+                                 field.numElements);
+            }
+
+        } catch(VRMLException ve) {
+            throw new IllegalArgumentException(ve.getMessage());
+        }
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by VRMLGeometryNodeType
+    //----------------------------------------------------------
+
+    /**
+     * Specified whether this node has color information.  If so, then it
+     * will be used for diffuse terms instead of materials.
+     *
+     * @return true Use local color information for diffuse lighting.
+     */
+    @Override
+    public boolean hasLocalColors() {
+        return false;
+    }
+
+    /**
+     * Specified whether this node has alpha values in the local colour
+     * information. If so, then it will be used for to override the material's
+     * transparency value.
+     *
+     * @return true when the local color value has inbuilt alpha
+     */
+    @Override
+    public boolean hasLocalColorAlpha() {
+        return false;
+    }
+
+    /**
+     * Add a listener for local color changes.  Nulls and duplicates will be ignored.
+     *
+     * @param l The listener.
+     */
+    @Override
+    public void addLocalColorsListener(LocalColorsListener l) {
+    }
+
+    /**
+     * Remove a listener for local color changes.  Nulls will be ignored.
+     *
+     * @param l The listener.
+     */
+    @Override
+    public void removeLocalColorsListener(LocalColorsListener l) {
+    }
+
+    /**
+     * Add a listener for texture coordinate generation mode changes.
+     * Nulls and duplicates will be ignored.
+     *
+     * @param l The listener.
+     */
+    @Override
+    public void addTexCoordGenModeChanged(TexCoordGenModeListener l) {
+    }
+
+    /**
+     * Remove a listener for texture coordinate generation mode changes.
+     * Nulls will be ignored.
+     *
+     * @param l The listener.
+     */
+    @Override
+    public void removeTexCoordGenModeChanged(TexCoordGenModeListener l) {
+    }
+
+    /**
+     * Get the texture coordinate generation mode.  NULL is returned
+     * if the texture coordinates are not generated.
+     *
+     * @param setNum The set which this tex gen mode refers
+     * @return The mode or NULL
+     */
+    @Override
+    public String getTexCoordGenMode(int setNum) {
+        return null;
+    }
+
+    /**
+     * Set the number of textures that were found on the accompanying Appearance
+     * node. Used to set the number of texture coordinates that need to be
+     * passed in to the renderer when no explicit texture coordinates were
+     * given.
+     *     * @param count The number of texture coordinate sets to add
+     */
+    @Override
+    public void setTextureCount(int count) {
+        // default implementation does nothing
+    }
+
+
+    /**
+     * Get the number of texture coordinate sets contained by this node
+     *
+     * @return the number of texture coordinate sets
+     */
+    @Override
+    public int getNumSets() {
+        return 0;
+    }
+
+    /**
+     * Get the value of the solid field.
+     *
+     * @return true This object is solid (ie single sided)
+     */
+    @Override
+    public boolean isSolid() {
+        return false;
+    }
+
+    /**
+     * Get the value of the CCW field. If the node does not have one, this will
+     * return true.
+     *
+     * @return true if the vertices are CCW ordered
+     */
+    @Override
+    public boolean isCCW() {
+        return true;
+    }
+
+    /**
+     * Specifies whether this node requires lighting.
+     *
+     * @return Should lighting be enabled
+     */
+    @Override
+    public boolean isLightingEnabled() {
+        return true;
+    }
+
+    //----------------------------------------------------------
+    // Methods required by the VRMLNodeType interface.
+    //----------------------------------------------------------
+
+    /**
+     * Get the index of the given field name. If the name does not exist for
+     * this node then return a value of -1.
+     *
+     * @param fieldName The name of the field we want the index from
+     * @return The index of the field name or -1
+     */
+    @Override
+    public int getFieldIndex(String fieldName) {
+        Integer index = fieldMap.get(fieldName);
+
+        return (index == null) ? -1 : index;
+    }
+
+    /**
+     * Get the list of indices that correspond to fields that contain nodes
+     * ie MFNode and SFNode). Used for blind scene graph traversal without
+     * needing to spend time querying for all fields etc. If a node does
+     * not have any fields that contain nodes, this shall return null. The
+     * field list covers all field types, regardless of whether they are
+     * readable or not at the VRML-level.
+     *
+     * @return The list of field indices that correspond to SF/MFnode fields
+     *    or null if none
+     */
+    @Override
+    public int[] getNodeFieldIndices() {
+        return nodeFields;
+    }
+
+    /**
+     * Get the declaration of the field at the given index. This allows for
+     * reverse lookup if needed. If the field does not exist, this will give
+     * a value of null.
+     *
+     * @param index The index of the field to get information
+     * @return A representation of this field's information
+     */
+    @Override
+    public VRMLFieldDeclaration getFieldDeclaration(int index) {
+        if(index < 0  || index > LAST_CURVE_INDEX)
+            return null;
+
+        return fieldDecl[index];
+    }
+
+    /**
+     * Get the number of fields.
+     *
+     * @return The number of fields.
+     */
+    @Override
+    public int getNumFields() {
+        return fieldDecl.length;
+    }
+
+    /**
+     * Get the primary type of this node.  Replaces the instanceof mechanism
+     * for use in switch statements.
+     *
+     * @return The primary type
+     */
+    @Override
+    public int getPrimaryType() {
+        return TypeConstants.ParametricGeometryNodeType;
+    }
+
+
+    /**
+     * Get the value of a field. If the field is a primitive type, it will
+     * return a class representing the value. For arrays or nodes it will
+     * return the instance directly.
+     *
+     * @param index The index of the field to change.
+     * @return The class representing the field value
+     * @throws InvalidFieldException The field index is not known
+     */
+    @Override
+    public VRMLFieldData getFieldValue(int index) throws InvalidFieldException {
+        VRMLFieldData fieldData = fieldLocalData.get();
+
+        switch(index) {
+            case FIELD_CONTROL_POINT:
+                fieldData.clear();
+                fieldData.doubleArrayValues = vfControlPoint;
+                fieldData.dataType = VRMLFieldData.DOUBLE_ARRAY_DATA;
+                fieldData.numElements = vfControlPoint == null ? 0 :
+                                        vfControlPoint.length / 4;
+                break;
+
+
+            default:
+                super.getFieldValue(index);
+        }
+
+        return fieldData;
+    }
+
+    /**
+     * Send a routed value from this node to the given destination node. The
+     * route should use the appropriate setValue() method of the destination
+     * node. It should not attempt to cast the node up to a higher level.
+     * Routing should also follow the standard rules for the loop breaking and
+     * other appropriate rules for the specification.
+     *
+     * @param time The time that this route occurred (not necessarily epoch
+     *   time. Should be treated as a relative value only)
+     * @param srcIndex The index of the field in this node that the value
+     *   should be sent from
+     * @param destNode The node reference that we will be sending the value to
+     * @param destIndex The index of the field in the destination node that
+     *   the value should be sent to.
+     */
+    @Override
+    public void sendRoute(double time,
+                          int srcIndex,
+                          VRMLNodeType destNode,
+                          int destIndex) {
+
+        // Simple impl for now.  ignores time and looping
+        try {
+            switch(srcIndex) {
+                case FIELD_CONTROL_POINT:
+                    destNode.setValue(destIndex, vfControlPoint, vfControlPoint.length);
+                    break;
+
+
+                default:
+                    super.sendRoute(time, srcIndex, destNode, destIndex);
+            }
+        } catch(InvalidFieldException ife) {
+            System.err.println("sendRoute: No field!" + ife.getFieldName());
+        } catch(InvalidFieldValueException ifve) {
+            System.err.println("sendRoute: Invalid field value: " +
+                ifve.getMessage());
+        }
+    }
+
+
+    /**
+     * Set the value of the field at the given index as an array of doubles.
+     * This would be used to set MFDouble field types.
+     *
+     * @param index The index of destination field to set
+     * @param value The new value to use for the node
+     * @throws InvalidFieldException The field index is not know
+     */
+    @Override
+    public void setValue(int index, double[] value, int numValid)
+        throws InvalidFieldException, InvalidFieldValueException {
+
+        switch(index) {
+
+            case FIELD_CONTROL_POINT:
+                setControlPoints(value);
+                break;
+
+            default:
+                super.setValue(index, value, numValid);
+        }
+    }
+
+
+	@Override
+	public void setupFinished() {
+        super.setupFinished();
+    }
+
+    //-------------------------------------------------------------
+    // Internal convenience methods
+    //-------------------------------------------------------------
+
+
+    /**
+     * Internal convenience method to setup the control points.
+     *
+     * @param points The new point array to use
+     */
+    private void setControlPoints(double[] points) {
+        int num_points = 0;
+        if(points != null) {
+            vfControlPoint = new double[points.length];
+            num_points = points.length;
+        }
+
+        if(num_points != 0)
+            System.arraycopy(points, 0, vfControlPoint, 0, num_points);
+
+        if(!inSetup) {
+            controlPointsChanged = true;
+            stateManager.addEndOfThisFrameListener(this);
+            hasChanged[FIELD_CONTROL_POINT] = true;
+            fireFieldChanged(FIELD_CONTROL_POINT);
+        }
+    }
+
 }
\ No newline at end of file
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/nurbs/BaseNurbsCurve.java b/src/java/org/web3d/vrml/renderer/common/nodes/nurbs/BaseNurbsCurve.java
index f9681dd80dc0db8ed3632e82409fd1e0c1870914..e2f0fb7897a5608d4e6f871920d76271bc2b3e8e 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/nurbs/BaseNurbsCurve.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/nurbs/BaseNurbsCurve.java
@@ -1,876 +1,876 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.renderer.common.nodes.nurbs;
-
-// External imports
-import java.util.HashMap;
-import java.util.Map;
-
-import org.j3d.geom.GeometryData;
-
-// Local imports
-import org.web3d.vrml.lang.*;
-
-import org.web3d.vrml.nodes.*;
-import org.web3d.vrml.renderer.common.nodes.AbstractNode;
-
-/**
- * Common base implementation of the NurbsCurve node.
- * <p>
- *
- * Because NURBS implementations involve complex retessellation,
- * the implementation will automatically register itself with the
- * frame state manager whenever any field changes.
- *
- * @author Justin Couch
- * @version $Revision: 1.14 $
- */
-public abstract class BaseNurbsCurve extends AbstractNode
-    implements VRMLBREPCurve3DNode, VRMLBREPNodeType {
-
-    /** Field index for controlPoint */
-    protected static final int FIELD_CONTROL_POINT = LAST_NODE_INDEX + 1;
-
-    /** Field index for controlPoint */
-    protected static final int FIELD_TESSELLATION = LAST_NODE_INDEX + 2;
-
-    /** Field index for controlPoint */
-    protected static final int FIELD_WEIGHT = LAST_NODE_INDEX + 3;
-
-    /** Field index for controlPoint */
-    protected static final int FIELD_KNOT = LAST_NODE_INDEX + 4;
-
-    /** Field index for order */
-    protected static final int FIELD_ORDER = LAST_NODE_INDEX + 5;
-
-    /** Field index for order */
-    protected static final int FIELD_CLOSED = LAST_NODE_INDEX + 6;
-
-    /** The last index in this node */
-    protected static final int LAST_CURVE_INDEX = FIELD_CLOSED;
-
-    /** Number of fields constant */
-    protected static final int NUM_FIELDS = LAST_CURVE_INDEX + 1;
-
-    /** Message for when the node in setValue() is not a Geometry */
-    protected static final String COORDINATE_NODE_MSG =
-        "Node does not describe a Coordinate object";
-
-    /** Array of VRMLFieldDeclarations */
-    private static VRMLFieldDeclaration[] fieldDecl;
-
-    /** Hashmap between a field name and its index */
-    private static final Map<String, Integer> fieldMap;
-
-    /** Listing of field indexes that have nodes */
-    private static int[] nodeFields;
-
-    // VRML Field declarations
-
-    /** The value of the tessellation field  */
-    protected int vfTessellation;
-
-    /** exposedField SFNode coord */
-    protected VRMLCoordinateNodeType vfCoord;
-
-    /** The value of the weight field */
-    protected double[] vfWeight;
-
-    /** The value of the knot field */
-    protected double[] vfKnot;
-
-    /** The value of the order field */
-    protected int vfOrder;
-
-    /**
-     *
-     */
-    protected boolean vfClosed;
-
-    /** Generator used to tessellate the curve */
-//    private BSplineGenerator generator;
-
-    /** Data from the last tessellation run, LINE_STRIPS by default. */
-    protected GeometryData geometryData;
-
-    /** Flag indicating if the control points have changed since last update */
-    private boolean controlPointsChanged;
-
-    /** Flag indicating if the weights have changed since last update */
-    private boolean weightsChanged;
-
-    // Static constructor
-    static {
-        nodeFields = new int[] { FIELD_METADATA };
-
-        fieldDecl = new VRMLFieldDeclaration[NUM_FIELDS];
-        fieldMap = new HashMap<>(NUM_FIELDS);
-
-        fieldDecl[FIELD_METADATA] =
-            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
-                                     "SFNode",
-                                     "metadata");
-        fieldDecl[FIELD_CONTROL_POINT] =
-            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
-                                 "SFNode",
-                                 "controlPoint");
-        fieldDecl[FIELD_WEIGHT] =
-            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
-                                 "MFDouble",
-                                 "weight");
-        fieldDecl[FIELD_KNOT] =
-            new VRMLFieldDeclaration(FieldConstants.FIELD,
-                                 "MFDouble",
-                                 "knot");
-        fieldDecl[FIELD_ORDER] =
-            new VRMLFieldDeclaration(FieldConstants.FIELD,
-                                 "SFInt32",
-                                 "order");
-
-        fieldDecl[FIELD_CLOSED] =
-            new VRMLFieldDeclaration(FieldConstants.FIELD,
-                                 "SFBool",
-                                 "closed");
-
-        fieldDecl[FIELD_TESSELLATION] =
-            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
-                                 "SFInt32",
-                                 "tessellation");
-
-        Integer idx = FIELD_METADATA;
-        fieldMap.put("metadata", idx);
-        fieldMap.put("set_metadata", idx);
-        fieldMap.put("metadata_changed", idx);
-
-        idx = FIELD_TESSELLATION;
-        fieldMap.put("tessellation", idx);
-        fieldMap.put("set_tessellation", idx);
-        fieldMap.put("tessellation_changed", idx);
-
-        idx = FIELD_CONTROL_POINT;
-        fieldMap.put("controlPoint", idx);
-        fieldMap.put("set_controlPoint", idx);
-        fieldMap.put("controlPoint_changed", idx);
-
-        idx = FIELD_WEIGHT;
-        fieldMap.put("weight", idx);
-        fieldMap.put("set_weight", idx);
-        fieldMap.put("weight_changed", idx);
-
-        fieldMap.put("knot", FIELD_KNOT);
-        fieldMap.put("order", FIELD_ORDER);
-        fieldMap.put("closed", FIELD_CLOSED);
-    }
-
-    /**
-     * Create a new default instance of the node.
-     */
-    protected BaseNurbsCurve() {
-        super("NurbsCurve");
-
-        hasChanged = new boolean[NUM_FIELDS];
-        vfOrder = 2;
-        vfClosed=false;
-
-//        generator = new BSplineGenerator();
-        geometryData = new GeometryData();
-        geometryData.geometryType = GeometryData.LINE_STRIPS;
-
-        controlPointsChanged = false;
-        weightsChanged = false;
-    }
-
-    /**
-     * Construct a new instance of this node based on the details from the
-     * given node. If the node is not a Box node, an exception will be
-     * thrown.
-     *
-     * @param node The node to copy
-     * @throws IllegalArgumentException The node is not a Group node
-     */
-
-    public BaseNurbsCurve(VRMLNodeType node) {
-        this(); // invoke default constructor
-
-        checkNodeType(node);
-
-        try {
-//            int index = node.getFieldIndex("controlPoint");
-//            VRMLFieldData field = node.getFieldValue(index);
-            //vfCoord = field.nodeValue;
-
-            int index = node.getFieldIndex("order");
-            VRMLFieldData field = node.getFieldValue(index);
-            vfOrder = field.intValue;
-
-            index = node.getFieldIndex("tessellation");
-            field = node.getFieldValue(index);
-            vfTessellation = field.intValue;
-
-            index = node.getFieldIndex("closed");
-            field = node.getFieldValue(index);
-            vfClosed = field.booleanValue;
-
-            index = node.getFieldIndex("weight");
-            field = node.getFieldValue(index);
-            if(field.numElements != 0) {
-                vfWeight = new double[field.numElements];
-                System.arraycopy(field.doubleArrayValues,
-                                 0,
-                                 vfWeight,
-                                 0,
-                                 field.numElements);
-            }
-
-
-            index = node.getFieldIndex("knot");
-            field = node.getFieldValue(index);
-            if(field.numElements != 0) {
-                vfKnot = new double[field.numElements];
-                System.arraycopy(field.doubleArrayValues,
-                                 0,
-                                 vfKnot,
-                                 0,
-                                 field.numElements);
-            }
-        } catch(VRMLException ve) {
-            throw new IllegalArgumentException(ve.getMessage());
-        }
-    }
-
-
-    //----------------------------------------------------------
-    // Methods defined by VRMLGeometryNodeType
-    //----------------------------------------------------------
-
-    /**
-     * Specified whether this node has color information.  If so, then it
-     * will be used for diffuse terms instead of materials.
-     *
-     * @return true Use local color information for diffuse lighting.
-     */
-    @Override
-    public boolean hasLocalColors() {
-        return false;
-    }
-
-    /**
-     * Specified whether this node has alpha values in the local colour
-     * information. If so, then it will be used for to override the material's
-     * transparency value.
-     *
-     * @return true when the local color value has inbuilt alpha
-     */
-    @Override
-    public boolean hasLocalColorAlpha() {
-        return false;
-    }
-
-    /**
-     * Add a listener for local color changes.  Nulls and duplicates will be ignored.
-     *
-     * @param l The listener.
-     */
-    @Override
-    public void addLocalColorsListener(LocalColorsListener l) {
-    }
-
-    /**
-     * Remove a listener for local color changes.  Nulls will be ignored.
-     *
-     * @param l The listener.
-     */
-    @Override
-    public void removeLocalColorsListener(LocalColorsListener l) {
-    }
-
-    /**
-     * Add a listener for texture coordinate generation mode changes.
-     * Nulls and duplicates will be ignored.
-     *
-     * @param l The listener.
-     */
-    @Override
-    public void addTexCoordGenModeChanged(TexCoordGenModeListener l) {
-    }
-
-    /**
-     * Remove a listener for texture coordinate generation mode changes.
-     * Nulls will be ignored.
-     *
-     * @param l The listener.
-     */
-    @Override
-    public void removeTexCoordGenModeChanged(TexCoordGenModeListener l) {
-    }
-
-    /**
-     * Get the texture coordinate generation mode.  NULL is returned
-     * if the texture coordinates are not generated.
-     *
-     * @param setNum The set which this tex gen mode refers
-     * @return The mode or NULL
-     */
-    @Override
-    public String getTexCoordGenMode(int setNum) {
-        return null;
-    }
-
-    /**
-     * Set the number of textures that were found on the accompanying Appearance
-     * node. Used to set the number of texture coordinates that need to be
-     * passed in to the renderer when no explicit texture coordinates were
-     * given.
-     *     * @param count The number of texture coordinate sets to add
-     */
-    @Override
-    public void setTextureCount(int count) {
-        // default implementation does nothing
-    }
-
-    /**
-     * Get the number of texture coordinate sets contained by this node
-     *
-     * @return the number of texture coordinate sets
-     */
-    @Override
-    public int getNumSets() {
-        return 0;
-    }
-
-    /**
-     * Get the value of the solid field.
-     *
-     * @return true This object is solid (ie single sided)
-     */
-    @Override
-    public boolean isSolid() {
-        return false;
-    }
-
-    /**
-     * Get the value of the CCW field. If the node does not have one, this will
-     * return true.
-     *
-     * @return true if the vertices are CCW ordered
-     */
-    @Override
-    public boolean isCCW() {
-        return true;
-    }
-
-    /**
-     * Specifies whether this node requires lighting.
-     *
-     * @return Should lighting be enabled
-     */
-    @Override
-    public boolean isLightingEnabled() {
-        return true;
-    }
-
-    //----------------------------------------------------------
-    // Methods required by the NRVRMLNodeTypeType interface.
-    //----------------------------------------------------------
-
-    /**
-     * Notification that the construction phase of this node has finished.
-     * If the node would like to do any internal processing, such as setting
-     * up geometry, then go for it now.
-     */
-    @Override
-    public void setupFinished() {
-        if(!inSetup)
-            return;
-
-        super.setupFinished();
-
-//        boolean valid_data = true;
-//
-//        if(vfControlPoint != null)
-//            generator.setControlPoints(vfControlPoint);
-//        else
-//            valid_data = false;
-//
-//        if(vfKnot != null &&
-//           (vfKnot.length >= ((vfControlPoint.length / 4) + vfOrder)))
-//            generator.setKnots(vfOrder - 1, vfKnot);
-//        else
-//            valid_data = false;
-//
-//        if(vfWeight != null)
-//            generator.setWeights(vfWeight);
-//
-//        if(!valid_data || vfOrder < 2)
-//            geometryData.vertexCount = 0;
-//
-//        updateFacetCount();
-    }
-
-    //----------------------------------------------------------
-    // Methods required by the VRMLNodeType interface.
-    //----------------------------------------------------------
-
-    /**
-     * Get the index of the given field name. If the name does not exist for
-     * this node then return a value of -1.
-     *
-     * @param fieldName The name of the field we want the index from
-     * @return The index of the field name or -1
-     */
-    @Override
-    public int getFieldIndex(String fieldName) {
-        Integer index = fieldMap.get(fieldName);
-
-        return (index == null) ? -1 : index;
-    }
-
-    /**
-     * Get the list of indices that correspond to fields that contain nodes
-     * ie MFNode and SFNode). Used for blind scene graph traversal without
-     * needing to spend time querying for all fields etc. If a node does
-     * not have any fields that contain nodes, this shall return null. The
-     * field list covers all field types, regardless of whether they are
-     * readable or not at the VRML-level.
-     *
-     * @return The list of field indices that correspond to SF/MFnode fields
-     *    or null if none
-     */
-    @Override
-    public int[] getNodeFieldIndices() {
-        return nodeFields;
-    }
-
-    /**
-     * Get the declaration of the field at the given index. This allows for
-     * reverse lookup if needed. If the field does not exist, this will give
-     * a value of null.
-     *
-     * @param index The index of the field to get information
-     * @return A representation of this field's information
-     */
-    @Override
-    public VRMLFieldDeclaration getFieldDeclaration(int index) {
-        if(index < 0  || index > LAST_CURVE_INDEX)
-            return null;
-
-        return fieldDecl[index];
-    }
-
-    /**
-     * Get the number of fields.
-     *
-     * @return The number of fields.
-     */
-    @Override
-    public int getNumFields() {
-        return fieldDecl.length;
-    }
-
-    /**
-     * Get the primary type of this node.  Replaces the instanceof mechanism
-     * for use in switch statements.
-     *
-     * @return The primary type
-     */
-    @Override
-    public int getPrimaryType() {
-        return TypeConstants.ParametricGeometryNodeType;
-    }
-
-
-    /**
-     * Get the value of a field. If the field is a primitive type, it will
-     * return a class representing the value. For arrays or nodes it will
-     * return the instance directly.
-     *
-     * @param index The index of the field to change.
-     * @return The class representing the field value
-     * @throws InvalidFieldException The field index is not known
-     */
-    @Override
-    public VRMLFieldData getFieldValue(int index) throws InvalidFieldException {
-        VRMLFieldData fieldData = fieldLocalData.get();
-
-        switch(index) {
-            case FIELD_CONTROL_POINT:
-                fieldData.clear();
-                fieldData.nodeValue = vfCoord;
-                fieldData.dataType = VRMLFieldData.NODE_DATA;
-                break;
-
-            case FIELD_WEIGHT:
-                fieldData.clear();
-                fieldData.doubleArrayValues = vfWeight;
-                fieldData.dataType = VRMLFieldData.DOUBLE_ARRAY_DATA;
-                fieldData.numElements = vfWeight == null ? 0 : vfWeight.length;
-                break;
-
-            case FIELD_KNOT:
-                fieldData.clear();
-                fieldData.doubleArrayValues = vfKnot;
-                fieldData.dataType = VRMLFieldData.DOUBLE_ARRAY_DATA;
-                fieldData.numElements = vfKnot == null ? 0 : vfKnot.length;
-                break;
-
-            case FIELD_ORDER:
-                fieldData.clear();
-                fieldData.intValue = vfOrder;
-                fieldData.dataType = VRMLFieldData.INT_DATA;
-                break;
-
-            case FIELD_TESSELLATION:
-                fieldData.clear();
-                fieldData.intValue = vfTessellation;
-                fieldData.dataType = VRMLFieldData.INT_DATA;
-                break;
-
-            case FIELD_CLOSED:
-                fieldData.clear();
-                fieldData.booleanValue = vfClosed;
-                fieldData.dataType = VRMLFieldData.BOOLEAN_DATA;
-                break;
-
-            default:
-                super.getFieldValue(index);
-        }
-
-        return fieldData;
-    }
-
-    /**
-     * Send a routed value from this node to the given destination node. The
-     * route should use the appropriate setValue() method of the destination
-     * node. It should not attempt to cast the node up to a higher level.
-     * Routing should also follow the standard rules for the loop breaking and
-     * other appropriate rules for the specification.
-     *
-     * @param time The time that this route occurred (not necessarily epoch
-     *   time. Should be treated as a relative value only)
-     * @param srcIndex The index of the field in this node that the value
-     *   should be sent from
-     * @param destNode The node reference that we will be sending the value to
-     * @param destIndex The index of the field in the destination node that
-     *   the value should be sent to.
-     */
-    @Override
-    public void sendRoute(double time,
-                          int srcIndex,
-                          VRMLNodeType destNode,
-                          int destIndex) {
-
-        // Simple impl for now.  ignores time and looping
-        try {
-            switch(srcIndex) {
-                case FIELD_CONTROL_POINT:
-                    destNode.setValue(destIndex, vfCoord);
-                    break;
-
-                case FIELD_TESSELLATION:
-                    destNode.setValue(destIndex, vfTessellation);
-                    break;
-
-                case FIELD_ORDER:
-                    destNode.setValue(destIndex, vfOrder);
-                    break;
-
-                case FIELD_CLOSED:
-                    destNode.setValue(destIndex, vfClosed);
-                    break;
-
-
-                case FIELD_KNOT:
-                    destNode.setValue(destIndex, vfKnot, vfKnot.length);
-                    break;
-
-                case FIELD_WEIGHT:
-                    destNode.setValue(destIndex, vfWeight, vfWeight.length);
-                    break;
-
-                default:
-                    super.sendRoute(time, srcIndex, destNode, destIndex);
-            }
-        } catch(InvalidFieldException ife) {
-            System.err.println("sendRoute: No field!" + ife.getFieldName());
-        } catch(InvalidFieldValueException ifve) {
-            System.err.println("sendRoute: Invalid field value: " +
-                ifve.getMessage());
-        }
-    }
-
-    /**
-     * Set the value of the field at the given index as an int.
-     * This would be used to set SFInt32 field types.
-     *
-     * @param index The index of destination field to set
-     * @param value The new value to use for the node
-     * @throws InvalidFieldException The field index is not know
-     */
-    @Override
-    public void setValue(int index, int value)
-        throws InvalidFieldException, InvalidFieldValueException {
-
-        switch(index) {
-            case FIELD_ORDER:
-                if(!inSetup)
-                    throw new InvalidFieldAccessException("Cannot set field order");
-
-                vfOrder = value;
-                if(vfOrder < 2)
-                    throw new InvalidFieldValueException("Order < 2: "+value);
-                break;
-
-            case FIELD_TESSELLATION:
-                vfTessellation = value;
-                updateFacetCount();
-                break;
-
-            default:
-                super.setValue(index, value);
-        }
-
-        if(!inSetup) {
-            stateManager.addEndOfThisFrameListener(this);
-
-            hasChanged[index] = true;
-            fireFieldChanged(index);
-        }
-    }
-
-    /**
-     * Set the value of the field at the given index as an boolean.
-     * This would be used to set SFBool field types.
-     *
-     * @param index The index of destination field to set
-     * @param value The new value to use for the node
-     * @throws InvalidFieldException The field index is not know
-     */
-    @Override
-    public void setValue(int index, boolean value)
-        throws InvalidFieldException, InvalidFieldValueException {
-
-        switch(index) {
-
-            case FIELD_CLOSED:
-                vfClosed = value;
-                updateFacetCount();
-                break;
-
-            default:
-                super.setValue(index, value);
-        }
-
-        if(!inSetup) {
-            stateManager.addEndOfThisFrameListener(this);
-
-            hasChanged[index] = true;
-            fireFieldChanged(index);
-        }
-    }
-
-    /**
-     * Set the value of the field at the given index as an array of doubles.
-     * This would be used to set MFDouble field types.
-     *
-     * @param index The index of destination field to set
-     * @param value The new value to use for the node
-     * @throws InvalidFieldException The field index is not know
-     */
-    @Override
-    public void setValue(int index, double[] value, int numValid)
-        throws InvalidFieldException, InvalidFieldValueException {
-
-        switch(index) {
-            case FIELD_WEIGHT:
-                setWeight(value, numValid);
-                break;
-
-            case FIELD_KNOT:
-                if(!inSetup)
-                    throw new InvalidFieldAccessException("Cannot set field knot");
-
-                setKnot(value);
-                break;
-
-
-            default:
-                super.setValue(index, value, numValid);
-        }
-    }
-
-    /**
-     * Set the value of the field at the given index as an Node
-     *
-     * @param index The index of destination field to set
-     * @param child The new value to use for the node
-     * @throws InvalidFieldException The field index is not know
-     */
-    @Override
-    public void setValue(int index, VRMLNodeType child)
-        throws InvalidFieldException, InvalidFieldValueException {
-
-        switch(index) {
-            case FIELD_CONTROL_POINT:
-                setControlPoints(child);
-                break;
-
-
-            default:
-                super.setValue(index, child);
-        }
-    }
-
-    //-------------------------------------------------------------
-    // Internal convenience methods
-    //-------------------------------------------------------------
-
-    /**
-     * Internal convenience method to update the knot values. Note that it
-     * assumes that the knots cannot be changed after setup is complete.
-     *
-     * @param knots The list of knot values to use
-     */
-    private void setKnot(double[] knots) {
-
-        // Always reallocate the array. We're going to assume that this
-        // very rarely changes so optimise for this case.
-        if(knots != null) {
-            if(vfKnot==null || knots.length > vfKnot.length)
-                vfKnot = new double[knots.length];
-
-            System.arraycopy(knots, 0, vfKnot, 0, knots.length);
-        } else {
-            vfKnot = null;
-        }
-    }
-
-    /**
-     * Internal convenience method to update the weight values.
-     *
-     * @param weights The list of weight values to use
-     */
-    private void setWeight(double[] weights, int numValid) {
-
-        // Always reallocate the array. We're going to assume that this
-        // very rarely changes so optimise for this case.
-        if(numValid != 0) {
-            if(vfWeight == null || numValid > vfWeight.length)
-                vfWeight = new double[numValid];
-
-            System.arraycopy(weights, 0, vfWeight, 0, numValid);
-        } else {
-            vfWeight = null;
-        }
-
-        if(!inSetup) {
-            weightsChanged = true;
-            stateManager.addEndOfThisFrameListener(this);
-            hasChanged[FIELD_WEIGHT] = true;
-            fireFieldChanged(FIELD_WEIGHT);
-        }
-    }
-
-    /**
-     * Internal convenience method to setup the control points.
-     *
-     * @param points The new point array to use
-     */
-    private void setControlPoints(VRMLNodeType node)
-        throws InvalidFieldValueException{
-        VRMLNodeType old_node = vfCoord;    // save previous value
-
-        if (node != null){
-            if (node instanceof VRMLCoordinateNodeType)
-                vfCoord = (VRMLCoordinateNodeType) node;
-            else
-                throw new InvalidFieldValueException(COORDINATE_NODE_MSG);
-            updateRefs(node,true);
-        }
-
-        if (old_node != null) updateRefs(old_node, true);
-
-        if (!inSetup) {
-            if(old_node != null)
-                stateManager.registerRemovedNode(old_node);
-
-            if(node != null)
-                stateManager.registerAddedNode(node);
-
-            hasChanged[FIELD_CONTROL_POINT] = true;
-            fireFieldChanged(FIELD_CONTROL_POINT);
-        }
-
-    }
-
-    /**
-     * Calculate the facetCount needed for the current state of the curve. The
-     * spec states:
-     * <p>
-     * 1. if a tessellation value is greater than 0, the number of tessellation
-     * points is tessellation+1;
-     * <br>
-     * 2. if a tessellation value is smaller than 0, the number of tessellation
-     * points is (-tessellation * (number of control points)+1)
-     * <br>
-     * 3. if a tessellation value is 0, the number of tessellation points is
-     * (2 * (number of control points)+1.
-     */
-    private void updateFacetCount() {
-//        int facets = 0;
-//
-//        if(vfTessellation > 0)
-//            facets = vfTessellation;
-//        else if(vfTessellation < 0)
-//            facets = -vfTessellation * vfControlPoint.length / 4;
-//        else
-//            facets = 2 * vfControlPoint.length / 4;
-//
-//        generator.setFacetCount(facets);
-    }
-
-    /**
-     * Request to regenerate the curve data now. The regenerated data will end
-     * up in the geometryData object. If some of the data is invalid, then the
-     * generation will create a curve with zero points in it and return false.
-     *
-     * @return true The generation succeeded
-     */
-    protected boolean regenerateCurve() {
-
-//        // sanity check to make sure all the data is valid before attempting to
-//        if(vfControlPoint == null || vfKnot == null || vfOrder < 2) {
-//            geometryData.vertexCount = 0;
-//            return false;
-//        }
-//
-//        if(controlPointsChanged) {
-//            generator.setControlPoints(vfControlPoint);
-//            controlPointsChanged = false;
-//        }
-//
-//        if(weightsChanged) {
-//            generator.setWeights(vfWeight);
-//            weightsChanged = false;
-//        }
-//
-//        generator.generate(geometryData);
-        return true;
-    }
-
-    /**
-     *
-     * @return
-     */
-    @Override
-    public Object getNurbsImpl(){return null;}
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.renderer.common.nodes.nurbs;
+
+// External imports
+import java.util.HashMap;
+import java.util.Map;
+
+import org.j3d.geom.GeometryData;
+
+// Local imports
+import org.web3d.vrml.lang.*;
+
+import org.web3d.vrml.nodes.*;
+import org.web3d.vrml.renderer.common.nodes.AbstractNode;
+
+/**
+ * Common base implementation of the NurbsCurve node.
+ * <p>
+ *
+ * Because NURBS implementations involve complex retessellation,
+ * the implementation will automatically register itself with the
+ * frame state manager whenever any field changes.
+ *
+ * @author Justin Couch
+ * @version $Revision: 1.14 $
+ */
+public abstract class BaseNurbsCurve extends AbstractNode
+    implements VRMLBREPCurve3DNode, VRMLBREPNodeType {
+
+    /** Field index for controlPoint */
+    protected static final int FIELD_CONTROL_POINT = LAST_NODE_INDEX + 1;
+
+    /** Field index for controlPoint */
+    protected static final int FIELD_TESSELLATION = LAST_NODE_INDEX + 2;
+
+    /** Field index for controlPoint */
+    protected static final int FIELD_WEIGHT = LAST_NODE_INDEX + 3;
+
+    /** Field index for controlPoint */
+    protected static final int FIELD_KNOT = LAST_NODE_INDEX + 4;
+
+    /** Field index for order */
+    protected static final int FIELD_ORDER = LAST_NODE_INDEX + 5;
+
+    /** Field index for order */
+    protected static final int FIELD_CLOSED = LAST_NODE_INDEX + 6;
+
+    /** The last index in this node */
+    protected static final int LAST_CURVE_INDEX = FIELD_CLOSED;
+
+    /** Number of fields constant */
+    protected static final int NUM_FIELDS = LAST_CURVE_INDEX + 1;
+
+    /** Message for when the node in setValue() is not a Geometry */
+    protected static final String COORDINATE_NODE_MSG =
+        "Node does not describe a Coordinate object";
+
+    /** Array of VRMLFieldDeclarations */
+    private static VRMLFieldDeclaration[] fieldDecl;
+
+    /** Hashmap between a field name and its index */
+    private static final Map<String, Integer> fieldMap;
+
+    /** Listing of field indexes that have nodes */
+    private static int[] nodeFields;
+
+    // VRML Field declarations
+
+    /** The value of the tessellation field  */
+    protected int vfTessellation;
+
+    /** exposedField SFNode coord */
+    protected VRMLCoordinateNodeType vfCoord;
+
+    /** The value of the weight field */
+    protected double[] vfWeight;
+
+    /** The value of the knot field */
+    protected double[] vfKnot;
+
+    /** The value of the order field */
+    protected int vfOrder;
+
+    /**
+     *
+     */
+    protected boolean vfClosed;
+
+    /** Generator used to tessellate the curve */
+//    private BSplineGenerator generator;
+
+    /** Data from the last tessellation run, LINE_STRIPS by default. */
+    protected GeometryData geometryData;
+
+    /** Flag indicating if the control points have changed since last update */
+    private boolean controlPointsChanged;
+
+    /** Flag indicating if the weights have changed since last update */
+    private boolean weightsChanged;
+
+    // Static constructor
+    static {
+        nodeFields = new int[] { FIELD_METADATA };
+
+        fieldDecl = new VRMLFieldDeclaration[NUM_FIELDS];
+        fieldMap = new HashMap<>(NUM_FIELDS);
+
+        fieldDecl[FIELD_METADATA] =
+            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
+                                     "SFNode",
+                                     "metadata");
+        fieldDecl[FIELD_CONTROL_POINT] =
+            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
+                                 "SFNode",
+                                 "controlPoint");
+        fieldDecl[FIELD_WEIGHT] =
+            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
+                                 "MFDouble",
+                                 "weight");
+        fieldDecl[FIELD_KNOT] =
+            new VRMLFieldDeclaration(FieldConstants.FIELD,
+                                 "MFDouble",
+                                 "knot");
+        fieldDecl[FIELD_ORDER] =
+            new VRMLFieldDeclaration(FieldConstants.FIELD,
+                                 "SFInt32",
+                                 "order");
+
+        fieldDecl[FIELD_CLOSED] =
+            new VRMLFieldDeclaration(FieldConstants.FIELD,
+                                 "SFBool",
+                                 "closed");
+
+        fieldDecl[FIELD_TESSELLATION] =
+            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
+                                 "SFInt32",
+                                 "tessellation");
+
+        Integer idx = FIELD_METADATA;
+        fieldMap.put("metadata", idx);
+        fieldMap.put("set_metadata", idx);
+        fieldMap.put("metadata_changed", idx);
+
+        idx = FIELD_TESSELLATION;
+        fieldMap.put("tessellation", idx);
+        fieldMap.put("set_tessellation", idx);
+        fieldMap.put("tessellation_changed", idx);
+
+        idx = FIELD_CONTROL_POINT;
+        fieldMap.put("controlPoint", idx);
+        fieldMap.put("set_controlPoint", idx);
+        fieldMap.put("controlPoint_changed", idx);
+
+        idx = FIELD_WEIGHT;
+        fieldMap.put("weight", idx);
+        fieldMap.put("set_weight", idx);
+        fieldMap.put("weight_changed", idx);
+
+        fieldMap.put("knot", FIELD_KNOT);
+        fieldMap.put("order", FIELD_ORDER);
+        fieldMap.put("closed", FIELD_CLOSED);
+    }
+
+    /**
+     * Create a new default instance of the node.
+     */
+    protected BaseNurbsCurve() {
+        super("NurbsCurve");
+
+        hasChanged = new boolean[NUM_FIELDS];
+        vfOrder = 2;
+        vfClosed=false;
+
+//        generator = new BSplineGenerator();
+        geometryData = new GeometryData();
+        geometryData.geometryType = GeometryData.LINE_STRIPS;
+
+        controlPointsChanged = false;
+        weightsChanged = false;
+    }
+
+    /**
+     * Construct a new instance of this node based on the details from the
+     * given node. If the node is not a Box node, an exception will be
+     * thrown.
+     *
+     * @param node The node to copy
+     * @throws IllegalArgumentException The node is not a Group node
+     */
+
+    public BaseNurbsCurve(VRMLNodeType node) {
+        this(); // invoke default constructor
+
+        checkNodeType(node);
+
+        try {
+//            int index = node.getFieldIndex("controlPoint");
+//            VRMLFieldData field = node.getFieldValue(index);
+            //vfCoord = field.nodeValue;
+
+            int index = node.getFieldIndex("order");
+            VRMLFieldData field = node.getFieldValue(index);
+            vfOrder = field.intValue;
+
+            index = node.getFieldIndex("tessellation");
+            field = node.getFieldValue(index);
+            vfTessellation = field.intValue;
+
+            index = node.getFieldIndex("closed");
+            field = node.getFieldValue(index);
+            vfClosed = field.booleanValue;
+
+            index = node.getFieldIndex("weight");
+            field = node.getFieldValue(index);
+            if(field.numElements != 0) {
+                vfWeight = new double[field.numElements];
+                System.arraycopy(field.doubleArrayValues,
+                                 0,
+                                 vfWeight,
+                                 0,
+                                 field.numElements);
+            }
+
+
+            index = node.getFieldIndex("knot");
+            field = node.getFieldValue(index);
+            if(field.numElements != 0) {
+                vfKnot = new double[field.numElements];
+                System.arraycopy(field.doubleArrayValues,
+                                 0,
+                                 vfKnot,
+                                 0,
+                                 field.numElements);
+            }
+        } catch(VRMLException ve) {
+            throw new IllegalArgumentException(ve.getMessage());
+        }
+    }
+
+
+    //----------------------------------------------------------
+    // Methods defined by VRMLGeometryNodeType
+    //----------------------------------------------------------
+
+    /**
+     * Specified whether this node has color information.  If so, then it
+     * will be used for diffuse terms instead of materials.
+     *
+     * @return true Use local color information for diffuse lighting.
+     */
+    @Override
+    public boolean hasLocalColors() {
+        return false;
+    }
+
+    /**
+     * Specified whether this node has alpha values in the local colour
+     * information. If so, then it will be used for to override the material's
+     * transparency value.
+     *
+     * @return true when the local color value has inbuilt alpha
+     */
+    @Override
+    public boolean hasLocalColorAlpha() {
+        return false;
+    }
+
+    /**
+     * Add a listener for local color changes.  Nulls and duplicates will be ignored.
+     *
+     * @param l The listener.
+     */
+    @Override
+    public void addLocalColorsListener(LocalColorsListener l) {
+    }
+
+    /**
+     * Remove a listener for local color changes.  Nulls will be ignored.
+     *
+     * @param l The listener.
+     */
+    @Override
+    public void removeLocalColorsListener(LocalColorsListener l) {
+    }
+
+    /**
+     * Add a listener for texture coordinate generation mode changes.
+     * Nulls and duplicates will be ignored.
+     *
+     * @param l The listener.
+     */
+    @Override
+    public void addTexCoordGenModeChanged(TexCoordGenModeListener l) {
+    }
+
+    /**
+     * Remove a listener for texture coordinate generation mode changes.
+     * Nulls will be ignored.
+     *
+     * @param l The listener.
+     */
+    @Override
+    public void removeTexCoordGenModeChanged(TexCoordGenModeListener l) {
+    }
+
+    /**
+     * Get the texture coordinate generation mode.  NULL is returned
+     * if the texture coordinates are not generated.
+     *
+     * @param setNum The set which this tex gen mode refers
+     * @return The mode or NULL
+     */
+    @Override
+    public String getTexCoordGenMode(int setNum) {
+        return null;
+    }
+
+    /**
+     * Set the number of textures that were found on the accompanying Appearance
+     * node. Used to set the number of texture coordinates that need to be
+     * passed in to the renderer when no explicit texture coordinates were
+     * given.
+     *     * @param count The number of texture coordinate sets to add
+     */
+    @Override
+    public void setTextureCount(int count) {
+        // default implementation does nothing
+    }
+
+    /**
+     * Get the number of texture coordinate sets contained by this node
+     *
+     * @return the number of texture coordinate sets
+     */
+    @Override
+    public int getNumSets() {
+        return 0;
+    }
+
+    /**
+     * Get the value of the solid field.
+     *
+     * @return true This object is solid (ie single sided)
+     */
+    @Override
+    public boolean isSolid() {
+        return false;
+    }
+
+    /**
+     * Get the value of the CCW field. If the node does not have one, this will
+     * return true.
+     *
+     * @return true if the vertices are CCW ordered
+     */
+    @Override
+    public boolean isCCW() {
+        return true;
+    }
+
+    /**
+     * Specifies whether this node requires lighting.
+     *
+     * @return Should lighting be enabled
+     */
+    @Override
+    public boolean isLightingEnabled() {
+        return true;
+    }
+
+    //----------------------------------------------------------
+    // Methods required by the NRVRMLNodeTypeType interface.
+    //----------------------------------------------------------
+
+    /**
+     * Notification that the construction phase of this node has finished.
+     * If the node would like to do any internal processing, such as setting
+     * up geometry, then go for it now.
+     */
+    @Override
+    public void setupFinished() {
+        if(!inSetup)
+            return;
+
+        super.setupFinished();
+
+//        boolean valid_data = true;
+//
+//        if(vfControlPoint != null)
+//            generator.setControlPoints(vfControlPoint);
+//        else
+//            valid_data = false;
+//
+//        if(vfKnot != null &&
+//           (vfKnot.length >= ((vfControlPoint.length / 4) + vfOrder)))
+//            generator.setKnots(vfOrder - 1, vfKnot);
+//        else
+//            valid_data = false;
+//
+//        if(vfWeight != null)
+//            generator.setWeights(vfWeight);
+//
+//        if(!valid_data || vfOrder < 2)
+//            geometryData.vertexCount = 0;
+//
+//        updateFacetCount();
+    }
+
+    //----------------------------------------------------------
+    // Methods required by the VRMLNodeType interface.
+    //----------------------------------------------------------
+
+    /**
+     * Get the index of the given field name. If the name does not exist for
+     * this node then return a value of -1.
+     *
+     * @param fieldName The name of the field we want the index from
+     * @return The index of the field name or -1
+     */
+    @Override
+    public int getFieldIndex(String fieldName) {
+        Integer index = fieldMap.get(fieldName);
+
+        return (index == null) ? -1 : index;
+    }
+
+    /**
+     * Get the list of indices that correspond to fields that contain nodes
+     * ie MFNode and SFNode). Used for blind scene graph traversal without
+     * needing to spend time querying for all fields etc. If a node does
+     * not have any fields that contain nodes, this shall return null. The
+     * field list covers all field types, regardless of whether they are
+     * readable or not at the VRML-level.
+     *
+     * @return The list of field indices that correspond to SF/MFnode fields
+     *    or null if none
+     */
+    @Override
+    public int[] getNodeFieldIndices() {
+        return nodeFields;
+    }
+
+    /**
+     * Get the declaration of the field at the given index. This allows for
+     * reverse lookup if needed. If the field does not exist, this will give
+     * a value of null.
+     *
+     * @param index The index of the field to get information
+     * @return A representation of this field's information
+     */
+    @Override
+    public VRMLFieldDeclaration getFieldDeclaration(int index) {
+        if(index < 0  || index > LAST_CURVE_INDEX)
+            return null;
+
+        return fieldDecl[index];
+    }
+
+    /**
+     * Get the number of fields.
+     *
+     * @return The number of fields.
+     */
+    @Override
+    public int getNumFields() {
+        return fieldDecl.length;
+    }
+
+    /**
+     * Get the primary type of this node.  Replaces the instanceof mechanism
+     * for use in switch statements.
+     *
+     * @return The primary type
+     */
+    @Override
+    public int getPrimaryType() {
+        return TypeConstants.ParametricGeometryNodeType;
+    }
+
+
+    /**
+     * Get the value of a field. If the field is a primitive type, it will
+     * return a class representing the value. For arrays or nodes it will
+     * return the instance directly.
+     *
+     * @param index The index of the field to change.
+     * @return The class representing the field value
+     * @throws InvalidFieldException The field index is not known
+     */
+    @Override
+    public VRMLFieldData getFieldValue(int index) throws InvalidFieldException {
+        VRMLFieldData fieldData = fieldLocalData.get();
+
+        switch(index) {
+            case FIELD_CONTROL_POINT:
+                fieldData.clear();
+                fieldData.nodeValue = vfCoord;
+                fieldData.dataType = VRMLFieldData.NODE_DATA;
+                break;
+
+            case FIELD_WEIGHT:
+                fieldData.clear();
+                fieldData.doubleArrayValues = vfWeight;
+                fieldData.dataType = VRMLFieldData.DOUBLE_ARRAY_DATA;
+                fieldData.numElements = vfWeight == null ? 0 : vfWeight.length;
+                break;
+
+            case FIELD_KNOT:
+                fieldData.clear();
+                fieldData.doubleArrayValues = vfKnot;
+                fieldData.dataType = VRMLFieldData.DOUBLE_ARRAY_DATA;
+                fieldData.numElements = vfKnot == null ? 0 : vfKnot.length;
+                break;
+
+            case FIELD_ORDER:
+                fieldData.clear();
+                fieldData.intValue = vfOrder;
+                fieldData.dataType = VRMLFieldData.INT_DATA;
+                break;
+
+            case FIELD_TESSELLATION:
+                fieldData.clear();
+                fieldData.intValue = vfTessellation;
+                fieldData.dataType = VRMLFieldData.INT_DATA;
+                break;
+
+            case FIELD_CLOSED:
+                fieldData.clear();
+                fieldData.booleanValue = vfClosed;
+                fieldData.dataType = VRMLFieldData.BOOLEAN_DATA;
+                break;
+
+            default:
+                super.getFieldValue(index);
+        }
+
+        return fieldData;
+    }
+
+    /**
+     * Send a routed value from this node to the given destination node. The
+     * route should use the appropriate setValue() method of the destination
+     * node. It should not attempt to cast the node up to a higher level.
+     * Routing should also follow the standard rules for the loop breaking and
+     * other appropriate rules for the specification.
+     *
+     * @param time The time that this route occurred (not necessarily epoch
+     *   time. Should be treated as a relative value only)
+     * @param srcIndex The index of the field in this node that the value
+     *   should be sent from
+     * @param destNode The node reference that we will be sending the value to
+     * @param destIndex The index of the field in the destination node that
+     *   the value should be sent to.
+     */
+    @Override
+    public void sendRoute(double time,
+                          int srcIndex,
+                          VRMLNodeType destNode,
+                          int destIndex) {
+
+        // Simple impl for now.  ignores time and looping
+        try {
+            switch(srcIndex) {
+                case FIELD_CONTROL_POINT:
+                    destNode.setValue(destIndex, vfCoord);
+                    break;
+
+                case FIELD_TESSELLATION:
+                    destNode.setValue(destIndex, vfTessellation);
+                    break;
+
+                case FIELD_ORDER:
+                    destNode.setValue(destIndex, vfOrder);
+                    break;
+
+                case FIELD_CLOSED:
+                    destNode.setValue(destIndex, vfClosed);
+                    break;
+
+
+                case FIELD_KNOT:
+                    destNode.setValue(destIndex, vfKnot, vfKnot.length);
+                    break;
+
+                case FIELD_WEIGHT:
+                    destNode.setValue(destIndex, vfWeight, vfWeight.length);
+                    break;
+
+                default:
+                    super.sendRoute(time, srcIndex, destNode, destIndex);
+            }
+        } catch(InvalidFieldException ife) {
+            System.err.println("sendRoute: No field!" + ife.getFieldName());
+        } catch(InvalidFieldValueException ifve) {
+            System.err.println("sendRoute: Invalid field value: " +
+                ifve.getMessage());
+        }
+    }
+
+    /**
+     * Set the value of the field at the given index as an int.
+     * This would be used to set SFInt32 field types.
+     *
+     * @param index The index of destination field to set
+     * @param value The new value to use for the node
+     * @throws InvalidFieldException The field index is not know
+     */
+    @Override
+    public void setValue(int index, int value)
+        throws InvalidFieldException, InvalidFieldValueException {
+
+        switch(index) {
+            case FIELD_ORDER:
+                if(!inSetup)
+                    throw new InvalidFieldAccessException("Cannot set field order");
+
+                vfOrder = value;
+                if(vfOrder < 2)
+                    throw new InvalidFieldValueException("Order < 2: "+value);
+                break;
+
+            case FIELD_TESSELLATION:
+                vfTessellation = value;
+                updateFacetCount();
+                break;
+
+            default:
+                super.setValue(index, value);
+        }
+
+        if(!inSetup) {
+            stateManager.addEndOfThisFrameListener(this);
+
+            hasChanged[index] = true;
+            fireFieldChanged(index);
+        }
+    }
+
+    /**
+     * Set the value of the field at the given index as an boolean.
+     * This would be used to set SFBool field types.
+     *
+     * @param index The index of destination field to set
+     * @param value The new value to use for the node
+     * @throws InvalidFieldException The field index is not know
+     */
+    @Override
+    public void setValue(int index, boolean value)
+        throws InvalidFieldException, InvalidFieldValueException {
+
+        switch(index) {
+
+            case FIELD_CLOSED:
+                vfClosed = value;
+                updateFacetCount();
+                break;
+
+            default:
+                super.setValue(index, value);
+        }
+
+        if(!inSetup) {
+            stateManager.addEndOfThisFrameListener(this);
+
+            hasChanged[index] = true;
+            fireFieldChanged(index);
+        }
+    }
+
+    /**
+     * Set the value of the field at the given index as an array of doubles.
+     * This would be used to set MFDouble field types.
+     *
+     * @param index The index of destination field to set
+     * @param value The new value to use for the node
+     * @throws InvalidFieldException The field index is not know
+     */
+    @Override
+    public void setValue(int index, double[] value, int numValid)
+        throws InvalidFieldException, InvalidFieldValueException {
+
+        switch(index) {
+            case FIELD_WEIGHT:
+                setWeight(value, numValid);
+                break;
+
+            case FIELD_KNOT:
+                if(!inSetup)
+                    throw new InvalidFieldAccessException("Cannot set field knot");
+
+                setKnot(value);
+                break;
+
+
+            default:
+                super.setValue(index, value, numValid);
+        }
+    }
+
+    /**
+     * Set the value of the field at the given index as an Node
+     *
+     * @param index The index of destination field to set
+     * @param child The new value to use for the node
+     * @throws InvalidFieldException The field index is not know
+     */
+    @Override
+    public void setValue(int index, VRMLNodeType child)
+        throws InvalidFieldException, InvalidFieldValueException {
+
+        switch(index) {
+            case FIELD_CONTROL_POINT:
+                setControlPoints(child);
+                break;
+
+
+            default:
+                super.setValue(index, child);
+        }
+    }
+
+    //-------------------------------------------------------------
+    // Internal convenience methods
+    //-------------------------------------------------------------
+
+    /**
+     * Internal convenience method to update the knot values. Note that it
+     * assumes that the knots cannot be changed after setup is complete.
+     *
+     * @param knots The list of knot values to use
+     */
+    private void setKnot(double[] knots) {
+
+        // Always reallocate the array. We're going to assume that this
+        // very rarely changes so optimise for this case.
+        if(knots != null) {
+            if(vfKnot==null || knots.length > vfKnot.length)
+                vfKnot = new double[knots.length];
+
+            System.arraycopy(knots, 0, vfKnot, 0, knots.length);
+        } else {
+            vfKnot = null;
+        }
+    }
+
+    /**
+     * Internal convenience method to update the weight values.
+     *
+     * @param weights The list of weight values to use
+     */
+    private void setWeight(double[] weights, int numValid) {
+
+        // Always reallocate the array. We're going to assume that this
+        // very rarely changes so optimise for this case.
+        if(numValid != 0) {
+            if(vfWeight == null || numValid > vfWeight.length)
+                vfWeight = new double[numValid];
+
+            System.arraycopy(weights, 0, vfWeight, 0, numValid);
+        } else {
+            vfWeight = null;
+        }
+
+        if(!inSetup) {
+            weightsChanged = true;
+            stateManager.addEndOfThisFrameListener(this);
+            hasChanged[FIELD_WEIGHT] = true;
+            fireFieldChanged(FIELD_WEIGHT);
+        }
+    }
+
+    /**
+     * Internal convenience method to setup the control points.
+     *
+     * @param points The new point array to use
+     */
+    private void setControlPoints(VRMLNodeType node)
+        throws InvalidFieldValueException{
+        VRMLNodeType old_node = vfCoord;    // save previous value
+
+        if (node != null){
+            if (node instanceof VRMLCoordinateNodeType)
+                vfCoord = (VRMLCoordinateNodeType) node;
+            else
+                throw new InvalidFieldValueException(COORDINATE_NODE_MSG);
+            updateRefs(node,true);
+        }
+
+        if (old_node != null) updateRefs(old_node, true);
+
+        if (!inSetup) {
+            if(old_node != null)
+                stateManager.registerRemovedNode(old_node);
+
+            if(node != null)
+                stateManager.registerAddedNode(node);
+
+            hasChanged[FIELD_CONTROL_POINT] = true;
+            fireFieldChanged(FIELD_CONTROL_POINT);
+        }
+
+    }
+
+    /**
+     * Calculate the facetCount needed for the current state of the curve. The
+     * spec states:
+     * <p>
+     * 1. if a tessellation value is greater than 0, the number of tessellation
+     * points is tessellation+1;
+     * <br>
+     * 2. if a tessellation value is smaller than 0, the number of tessellation
+     * points is (-tessellation * (number of control points)+1)
+     * <br>
+     * 3. if a tessellation value is 0, the number of tessellation points is
+     * (2 * (number of control points)+1.
+     */
+    private void updateFacetCount() {
+//        int facets = 0;
+//
+//        if(vfTessellation > 0)
+//            facets = vfTessellation;
+//        else if(vfTessellation < 0)
+//            facets = -vfTessellation * vfControlPoint.length / 4;
+//        else
+//            facets = 2 * vfControlPoint.length / 4;
+//
+//        generator.setFacetCount(facets);
+    }
+
+    /**
+     * Request to regenerate the curve data now. The regenerated data will end
+     * up in the geometryData object. If some of the data is invalid, then the
+     * generation will create a curve with zero points in it and return false.
+     *
+     * @return true The generation succeeded
+     */
+    protected boolean regenerateCurve() {
+
+//        // sanity check to make sure all the data is valid before attempting to
+//        if(vfControlPoint == null || vfKnot == null || vfOrder < 2) {
+//            geometryData.vertexCount = 0;
+//            return false;
+//        }
+//
+//        if(controlPointsChanged) {
+//            generator.setControlPoints(vfControlPoint);
+//            controlPointsChanged = false;
+//        }
+//
+//        if(weightsChanged) {
+//            generator.setWeights(vfWeight);
+//            weightsChanged = false;
+//        }
+//
+//        generator.generate(geometryData);
+        return true;
+    }
+
+    /**
+     *
+     * @return
+     */
+    @Override
+    public Object getNurbsImpl(){return null;}
+}
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/particle/BaseEmitter.java b/src/java/org/web3d/vrml/renderer/common/nodes/particle/BaseEmitter.java
index af8e6fb5bb0146162cdcae80b156d3fe14a3c23d..0ef0e5c08b8408109ffec9acdac6ab007f831f54 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/particle/BaseEmitter.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/particle/BaseEmitter.java
@@ -23,7 +23,9 @@ import org.web3d.vrml.renderer.common.nodes.AbstractNode;
 
 /**
  * Common implementation of all Emitter nodes.
- * 
+ * <p>
+ *
+ *
  * @author Justin Couch
  * @version $Revision: 2.1 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/particle/BaseExplosionEmitter.java b/src/java/org/web3d/vrml/renderer/common/nodes/particle/BaseExplosionEmitter.java
index 6e12ef21548e53c5197f2164dac6e30a8c66485e..44ea1407fb1f4424c2bc53d513a097ee5de6a86e 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/particle/BaseExplosionEmitter.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/particle/BaseExplosionEmitter.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.nodes.*;
 
 /**
  * Common implementation of a ExplosionEmitter node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 2.2 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/particle/BaseGravityPhysicsModel.java b/src/java/org/web3d/vrml/renderer/common/nodes/particle/BaseGravityPhysicsModel.java
index 1e7266b1039c8bf0e47c7e78babc3942b06cf875..e1c66c9ae7817d1fe995de8d53fe5d2a9b5fa6c6 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/particle/BaseGravityPhysicsModel.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/particle/BaseGravityPhysicsModel.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.nodes.*;
 
 /**
  * Common implementation of a GravityPhysicsModel node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 2.2 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/particle/BasePhysicsModel.java b/src/java/org/web3d/vrml/renderer/common/nodes/particle/BasePhysicsModel.java
index b294f4bf85879c12b51795a71a20ddbb379ef50e..6c009ebbedd5718b3e2df22d8e535961e45d85b9 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/particle/BasePhysicsModel.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/particle/BasePhysicsModel.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.common.nodes.AbstractNode;
 
 /**
  * Common implementation of a GravityPhysics node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 2.2 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/particle/BasePointEmitter.java b/src/java/org/web3d/vrml/renderer/common/nodes/particle/BasePointEmitter.java
index c0bea54ecc85fd4abfbbddebf7053fb87a8268ce..14bd8defb1af13262f42da8ad65fe89edcc47893 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/particle/BasePointEmitter.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/particle/BasePointEmitter.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.nodes.*;
 
 /**
  * Common implementation of a PointEmitter node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 2.3 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/particle/BasePolylineEmitter.java b/src/java/org/web3d/vrml/renderer/common/nodes/particle/BasePolylineEmitter.java
index 68c154b17a16b81f04624827a5046bb9de47fbc5..fba25de1a4c27c16bea203854d443cb7d8b1b497 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/particle/BasePolylineEmitter.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/particle/BasePolylineEmitter.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.nodes.*;
 
 /**
  * Common implementation of a PolylineEmitter node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 2.3 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/particle/BaseWindPhysicsModel.java b/src/java/org/web3d/vrml/renderer/common/nodes/particle/BaseWindPhysicsModel.java
index c9b7ecc632e34577f73b7a804c36d9fb73a37c73..437cdabf45d3b5b75e8e749ad73edfb53949923d 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/particle/BaseWindPhysicsModel.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/particle/BaseWindPhysicsModel.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.nodes.*;
 
 /**
  * Common implementation of a WindPhysicsModel node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 2.3 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/picking/BaseLinePicker.java b/src/java/org/web3d/vrml/renderer/common/nodes/picking/BaseLinePicker.java
index fdf93ff98cc72e464f252d1d5e47a0ad969bd23a..59e77a13347c90fd12699bb31fa21a88087f48ca 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/picking/BaseLinePicker.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/picking/BaseLinePicker.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.nodes.*;
 
 /**
  * Implementation of the common LinePicker node for all renderers.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.11 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/picking/BasePickableGroup.java b/src/java/org/web3d/vrml/renderer/common/nodes/picking/BasePickableGroup.java
index 8865b2fe2973a5d62131db4eda7983568ee20ed9..89fb6149f8b57611cb2c8cbcd3ac606488a86737 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/picking/BasePickableGroup.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/picking/BasePickableGroup.java
@@ -26,7 +26,8 @@ import org.web3d.vrml.nodes.VRMLPickableNodeType;
 import org.web3d.vrml.renderer.common.nodes.BaseGroupingNode;
 
 /**
- * Common implementation of a PickGroup extension node
+ * Common implementation of a PickGroup extension node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/picking/BasePickingNode.java b/src/java/org/web3d/vrml/renderer/common/nodes/picking/BasePickingNode.java
index 028e3ffaecb07020d84fd29929d0d224c6066db3..3e85b0382fa08b5201d6bd783ba3a321bcc2acce 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/picking/BasePickingNode.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/picking/BasePickingNode.java
@@ -27,6 +27,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseSensorNode;
 
 /**
  * Implementation of the abstract X3DPickingNode type.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.15 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/picking/BasePointPicker.java b/src/java/org/web3d/vrml/renderer/common/nodes/picking/BasePointPicker.java
index 3fc5f93c35d63e82cb3f0929e833589a5fa52fd9..b962c246fc49c28f69905fc064f85bbf0d193b35 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/picking/BasePointPicker.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/picking/BasePointPicker.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.nodes.*;
 
 /**
  * Implementation of the common PointPicker node for all renderers.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.7 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/picking/BasePrimitivePicker.java b/src/java/org/web3d/vrml/renderer/common/nodes/picking/BasePrimitivePicker.java
index 0dd8a8f05ce76f2fa71b5e6654100f4c339870d5..2f72901fe0e351e746dce3a070cbda97bba9d34b 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/picking/BasePrimitivePicker.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/picking/BasePrimitivePicker.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.nodes.*;
 
 /**
  * Implementation of the common PrimitivePicker node for all renderers.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.6 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/picking/BaseVolumePicker.java b/src/java/org/web3d/vrml/renderer/common/nodes/picking/BaseVolumePicker.java
index 547a8b4f46161e79b4c8f7407b70b33787a03349..d36a9633195c9c7a38fabc931205079e4c74f459 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/picking/BaseVolumePicker.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/picking/BaseVolumePicker.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.nodes.*;
 
 /**
  * Implementation of the common VolumePicker node for all renderers.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/render/BaseIndexedLineSet.java b/src/java/org/web3d/vrml/renderer/common/nodes/render/BaseIndexedLineSet.java
index e2b22e45fa9761840685b3e885f43ffbb11941bd..272b45567b952f96f383ab033261009f2376c31d 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/render/BaseIndexedLineSet.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/render/BaseIndexedLineSet.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseIndexedGeometryNode;
 
 /**
  * An abstract implementation of an IndexedLineSet
+ * <p>
  *
  *
  * @author Justin Couch
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/render/BaseLineSet.java b/src/java/org/web3d/vrml/renderer/common/nodes/render/BaseLineSet.java
index eaef318d3cb7020509b531c85f221cf7ea965816..ba7ed8a41346eda29096e168d46427360ac8f938 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/render/BaseLineSet.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/render/BaseLineSet.java
@@ -24,7 +24,9 @@ import org.web3d.vrml.renderer.common.nodes.BaseComponentGeometryNode;
 
 /**
  * An abstract implementation of the LineSet node.
- * 
+ * <p>
+ *
+ *
  * @author Justin Couch
  * @version $Revision: 1.7 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/render/BasePointSet.java b/src/java/org/web3d/vrml/renderer/common/nodes/render/BasePointSet.java
index 4ea0e4b1ac22c5c201dcf74f6e773c45e80e26d2..7d80479b6505ebb53a39adfa6ce0f92a66668456 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/render/BasePointSet.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/render/BasePointSet.java
@@ -24,6 +24,8 @@ import org.web3d.vrml.renderer.common.nodes.BasePointSetGeometryNode;
 
 /**
  * An abstract implementation of the PointSet node.
+ * <p>
+ *
  *
  * @author Justin Couch
  * @version $Revision: 1.8 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/render/BaseTriangleSet.java b/src/java/org/web3d/vrml/renderer/common/nodes/render/BaseTriangleSet.java
index f3fe2e8ee50fc0ede5663b1c03406d6297a1c7a8..8bf0b621de87c689d4c1fb60f71d9644cf6b5e6d 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/render/BaseTriangleSet.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/render/BaseTriangleSet.java
@@ -25,6 +25,8 @@ import org.web3d.vrml.renderer.common.nodes.BaseTriangleGeometryNode;
 /**
  * An abstract implementation of any node that uses component nodes to provide
  * coordinate, normal and texture information.
+ * <p>
+ *
  *
  * @author Justin Couch, Alan Hudson
  * @version $Revision: 1.9 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseBallJoint.java b/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseBallJoint.java
index f0ecd6094cb0380bc7d84d94a10dfcbf67b1ab8c..8d37f97cd799d910b1a2780ecbb4197adcfdf5f2 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseBallJoint.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseBallJoint.java
@@ -27,7 +27,8 @@ import org.web3d.vrml.nodes.*;
 
 /**
  * Implementation of the BallJoint node.
- * 
+ * <p>
+ *
  * @author Justin Couch
  * @version $Revision: 1.9 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseContact.java b/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseContact.java
index b8b37c10452acd51e7161f24c0621e3599076b05..f27364f72c31d6caf8ba011a42ec1d42643a354b 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseContact.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseContact.java
@@ -30,6 +30,7 @@ import org.j3d.util.IntHashMap;
 
 /**
  * Implementation of the Contact node for rigid body physics.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.12 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseDoubleAxisHingeJoint.java b/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseDoubleAxisHingeJoint.java
index 40469563a0366adac74161cedb67360ac12425d0..25aae259706aec520e3e89923b09f2386aef6318 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseDoubleAxisHingeJoint.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseDoubleAxisHingeJoint.java
@@ -27,6 +27,7 @@ import org.web3d.vrml.nodes.*;
 
 /**
  * Implementation of the DoubleAxisHingeJoint node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.15 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseJointNode.java b/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseJointNode.java
index 562e4a5b02487f5d7c2a19b7e885d656af8f9344..d5b0a58c4424a21486ab2c492508d505e703edb6 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseJointNode.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseJointNode.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.common.nodes.AbstractNode;
 
 /**
  * Implementation of the abstract X3DRigidJointNode type.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseMotorJoint.java b/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseMotorJoint.java
index fbe38d290d3a781cbfaf3c503c14d707d678d58e..687bd7f3e8e6a897dd4d9246ae1a8179a50542e7 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseMotorJoint.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseMotorJoint.java
@@ -28,6 +28,7 @@ import org.web3d.vrml.nodes.*;
 
 /**
  * Implementation of the MotorJoint node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.10 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseSingleAxisHingeJoint.java b/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseSingleAxisHingeJoint.java
index b5733209de9e004681b41c9ff552b85843b7a292..209cf815d68906ea3ff02737b2d02e6b97787d1c 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseSingleAxisHingeJoint.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseSingleAxisHingeJoint.java
@@ -27,6 +27,7 @@ import org.web3d.vrml.nodes.*;
 
 /**
  * Implementation of the SingleAxisHingeJoint node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.8 $
@@ -404,7 +405,7 @@ public abstract class BaseSingleAxisHingeJoint extends BaseJointNode {
             odeJoint.setAnchor(vfAnchorPoint[0],
                                vfAnchorPoint[1],
                                vfAnchorPoint[2]);
-            odeJoint.setAxis1(vfAxis[0], vfAxis[1], vfAxis[2]);
+            odeJoint.setAxis(vfAxis[0], vfAxis[1], vfAxis[2]);
             odeJoint.setMinAngleStop(vfMinAngle);
             odeJoint.setMaxAngleStop(vfMaxAngle);
             odeJoint.setStopBounce(vfStopBounce);
@@ -505,7 +506,7 @@ public abstract class BaseSingleAxisHingeJoint extends BaseJointNode {
             odeJoint.setAnchor(vfAnchorPoint[0],
                                vfAnchorPoint[1],
                                vfAnchorPoint[2]);
-            odeJoint.setAxis1(vfAxis[0], vfAxis[1], vfAxis[2]);
+            odeJoint.setAxis(vfAxis[0], vfAxis[1], vfAxis[2]);
             odeJoint.setMinAngleStop(vfMinAngle);
             odeJoint.setMaxAngleStop(vfMaxAngle);
             odeJoint.setStopBounce(vfStopBounce);
@@ -899,7 +900,7 @@ public abstract class BaseSingleAxisHingeJoint extends BaseJointNode {
 
         if(!inSetup) {
             if(odeJoint != null)
-                odeJoint.setAxis1(axis[0], axis[1], axis[2]);
+                odeJoint.setAxis(axis[0], axis[1], axis[2]);
             hasChanged[FIELD_AXIS] = true;
             fireFieldChanged(FIELD_AXIS);
         }
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseSliderJoint.java b/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseSliderJoint.java
index b6781fa27f6098b6f7b37b75859b7bdfb1628878..ba499aa325e69692a99a3f63e8b964543d576bab 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseSliderJoint.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseSliderJoint.java
@@ -27,6 +27,7 @@ import org.web3d.vrml.nodes.*;
 
 /**
  * Implementation of the SliderJoint node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.7 $
@@ -341,7 +342,7 @@ public abstract class BaseSliderJoint extends BaseJointNode {
                 body_2 = vfBody2.getODEBody();
 
             odeJoint.attach(body_1, body_2);
-            odeJoint.setAxis1(vfAxis[0], vfAxis[1], vfAxis[2]);
+            odeJoint.setAxis(vfAxis[0], vfAxis[1], vfAxis[2]);
 
             odeJoint.setMinimumPosition(vfMinSeparation);
             odeJoint.setMaximumPosition(vfMaxSeparation);
@@ -504,7 +505,7 @@ public abstract class BaseSliderJoint extends BaseJointNode {
             body_2 = vfBody2.getODEBody();
 
         odeJoint.attach(body_1, body_2);
-        odeJoint.setAxis1(vfAxis[0], vfAxis[1], vfAxis[2]);
+        odeJoint.setAxis(vfAxis[0], vfAxis[1], vfAxis[2]);
 
         odeJoint.setMinimumPosition(vfMinSeparation);
         odeJoint.setMaximumPosition(vfMaxSeparation);
@@ -761,7 +762,7 @@ public abstract class BaseSliderJoint extends BaseJointNode {
         vfAxis[2] = pos[2];
 
         if(!inSetup) {
-            odeJoint.setAxis1(pos[0], pos[1], pos[2]);
+            odeJoint.setAxis(pos[0], pos[1], pos[2]);
             hasChanged[FIELD_AXIS] = true;
             fireFieldChanged(FIELD_AXIS);
         }
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseUniversalJoint.java b/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseUniversalJoint.java
index 4130717edbeb5fdfbbbdfaf0a8765f976d41a6e0..0720e0522681596cced2038e9298726738377877 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseUniversalJoint.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/rigidphysics/BaseUniversalJoint.java
@@ -28,6 +28,7 @@ import org.web3d.vrml.nodes.*;
 
 /**
  * Implementation of the UniversalJoint node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.7 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/sensor/BaseCylinderSensor.java b/src/java/org/web3d/vrml/renderer/common/nodes/sensor/BaseCylinderSensor.java
index 97b48e8499321cb5bb46f23af6f54cdfbc51eeae..5b5aa7b7195b3848b9c5fd3e598ef797575759d9 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/sensor/BaseCylinderSensor.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/sensor/BaseCylinderSensor.java
@@ -30,6 +30,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseDragSensorNode;
 
 /**
  * Implementation of a CylinderSensor node.
+ * <p>
  *
  * @author Alan Hudson, Justin Couch
  * @version $Revision: 1.16 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/sensor/BasePlaneSensor.java b/src/java/org/web3d/vrml/renderer/common/nodes/sensor/BasePlaneSensor.java
index 296448ab66352c7110ca48b2e149e454245b0d04..c09c7506f60a06a0e73e5451e758232243156aad 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/sensor/BasePlaneSensor.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/sensor/BasePlaneSensor.java
@@ -27,6 +27,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseDragSensorNode;
 
 /**
  * Implementation of a PlaneSensor node.
+ * <p>
  *
  * @author Alan Hudson, Justin Couch
  * @version $Revision: 1.14 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/sensor/BaseSphereSensor.java b/src/java/org/web3d/vrml/renderer/common/nodes/sensor/BaseSphereSensor.java
index f7ee6836b9e0ed55d8a8a363126b6d793aeeaca7..32bcaeb2f96a9eb21b30e3f9b8594f4cdd67d571 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/sensor/BaseSphereSensor.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/sensor/BaseSphereSensor.java
@@ -27,6 +27,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseDragSensorNode;
 
 /**
  * Java3D implementation of a SphereSensor node.
+ * <p>
  *
  * @author Alan Hudson, Justin Couch
  * @version $Revision: 1.12 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/sensor/BaseTouchSensor.java b/src/java/org/web3d/vrml/renderer/common/nodes/sensor/BaseTouchSensor.java
index 67774cec8e9d497456cb10dc046ea2f2cc580480..cae3b7b5b69302a75d19c0d9b0c93aad64112384 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/sensor/BaseTouchSensor.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/sensor/BaseTouchSensor.java
@@ -28,6 +28,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseSensorNode;
 
 /**
  * Common base implementation of a TouchSensor node.
+ * <p>
  *
  * @author Alan Hudson, Justin Couch
  * @version $Revision: 1.17 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/shape/BaseFillProperties.java b/src/java/org/web3d/vrml/renderer/common/nodes/shape/BaseFillProperties.java
index 856afa97f1ea45adb3442727d91b21f5fe01eb17..19032594cb241592fc874d74cfb2b9688ef852ec 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/shape/BaseFillProperties.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/shape/BaseFillProperties.java
@@ -29,6 +29,7 @@ import org.web3d.vrml.util.FieldValidator;
 
 /**
  * Common base implementation of a FillProperties node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.6 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/shape/BaseLineProperties.java b/src/java/org/web3d/vrml/renderer/common/nodes/shape/BaseLineProperties.java
index ec43a16b56e2119526461ef569f137fb7bc7aa5d..f8529fd81384061d4316a8369e15c5d11fcde834 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/shape/BaseLineProperties.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/shape/BaseLineProperties.java
@@ -27,6 +27,7 @@ import org.web3d.vrml.renderer.common.nodes.AbstractNode;
 
 /**
  * Common base implementation of a LineProperties node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.10 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/shape/BaseMaterial.java b/src/java/org/web3d/vrml/renderer/common/nodes/shape/BaseMaterial.java
index 61810c20f46852c4f33937e8044b77407da170d9..6e1823919158c088fa24999bb9b5b7bdee97b277 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/shape/BaseMaterial.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/shape/BaseMaterial.java
@@ -25,6 +25,7 @@ import org.web3d.vrml.util.FieldValidator;
 
 /**
  * Common base implementation of a material node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.12 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/shape/BasePointProperties.java b/src/java/org/web3d/vrml/renderer/common/nodes/shape/BasePointProperties.java
index e9ab5a0a2b3ca7514e94ce3843710f0ae1b3de56..7b492179218b4ee0a7aa4da0b19233978a93052b 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/shape/BasePointProperties.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/shape/BasePointProperties.java
@@ -1,631 +1,632 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.renderer.common.nodes.shape;
-
-// Standard imports
-import java.util.HashMap;
-import java.util.Map;
-
-// Application specific imports
-import org.web3d.vrml.lang.*;
-
-import org.web3d.vrml.nodes.VRMLNodeType;
-import org.web3d.vrml.nodes.VRMLFieldData;
-import org.web3d.vrml.nodes.VRMLPointPropertiesNodeType;
-
-import org.web3d.vrml.renderer.common.nodes.AbstractNode;
-
-/**
- * Common base implementation of a PointProperties node.
- *
- * @author Justin Couch
- * @version $Revision: 1.1 $
- */
-public abstract class BasePointProperties extends AbstractNode
-    implements VRMLPointPropertiesNodeType {
-
-    /** Field index for pointsizeScaleFactor */
-    protected static final int FIELD_POINTSIZE_SCALE_FACTOR = LAST_NODE_INDEX + 1;
-
-    /** Field index for pointsizeMinValue */
-    protected static final int FIELD_POINTSIZE_MIN_VALUE = LAST_NODE_INDEX + 2;
-
-    /** Field index for pointsizeMaxValue */
-    protected static final int FIELD_POINTSIZE_MAX_VALUE = LAST_NODE_INDEX + 3;
-
-    /** Field index for pointsizeAttenuation */
-    protected static final int FIELD_POINTSIZE_ATTENUATION = LAST_NODE_INDEX + 4;
-
-    /** Field index for colorMode */
-    protected static final int FIELD_COLOR_MODE = LAST_NODE_INDEX + 5;
-
-    /** Number of fields constant */
-    protected static final int NUM_FIELDS = FIELD_COLOR_MODE + 1;
-
-    /** Error message when the user code barfs */
-    private static final String COLOR_MODE_ERROR_MSG =
-        "Error sending color mode changed notification to: ";
-
-    /** Message for when the color mode is invalid */
-    private static final String UNKNOWN_TYPE_MSG =
-        "The color mode provided is not recognised";
-
-    /** Array of VRMLFieldDeclarations */
-    private static VRMLFieldDeclaration[] fieldDecl;
-
-    /** Hashmap between a field name and its index */
-    private static final Map<String, Integer> fieldMap;
-
-    /** Listing of field indexes that have nodes */
-    private static int[] nodeFields;
-
-    // VRML Field declarations
-
-    /** exposedField SFFloat pointsizeScaleFactor 0 */
-    protected float vfPointsizeScaleFactor;
-
-    /** exposedField SFFloat pointsizeMinValue 0 */
-    protected float vfPointsizeMinValue;
-
-    /** exposedField SFFloat pointsizeMaxValue 0 */
-    protected float vfPointsizeMaxValue;
-
-    /** exposedField SFVec3f pointsizeAttenuation 1 0 0 */
-    protected float[] vfPointsizeAttenuation;
-
-    /** exposedField SFString colorMode 0 */
-    protected String vfColorMode;
-
-    /** Constant representing the mode used */
-    protected int colorMode;
-
-    /** Constant describing texture color mode */
-    protected static final String TEXTURE_COLORMODE = "TEXTURE_COLOR";
-
-    /** Constant describing point color mode */
-    protected static final String POINT_COLORMODE = "POINT_COLOR";
-
-    /** Constant describing texture and point mode */
-    protected static final String TEXTURE_AND_POINT_COLORMODE = "TEXTURE_AND_POINT_COLOR";
-
-    /** Mapping between type string and type ints */
-    private static final Map<String, Integer> typeMap;
-
-    // Static constructor
-    static {
-        nodeFields = new int[] { FIELD_METADATA };
-
-        fieldDecl = new VRMLFieldDeclaration[NUM_FIELDS];
-        fieldMap = new HashMap<>(NUM_FIELDS*3);
-
-        fieldDecl[FIELD_METADATA] =
-            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
-                                     "SFNode",
-                                     "metadata");
-        fieldDecl[FIELD_POINTSIZE_SCALE_FACTOR] =
-            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
-                                     "SFFloat",
-                                     "pointsizeScaleFactor");
-        fieldDecl[FIELD_POINTSIZE_MIN_VALUE] =
-            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
-                                     "SFFloat",
-                                     "pointsizeMinValue");
-        fieldDecl[FIELD_POINTSIZE_MAX_VALUE] =
-            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
-                                     "SFFloat",
-                                     "pointsizeMaxValue");
-        fieldDecl[FIELD_POINTSIZE_ATTENUATION] =
-            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
-                                     "SFVec3f",
-                                     "pointsizeAttenuation");
-        fieldDecl[FIELD_COLOR_MODE] =
-            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
-                                     "SFString",
-                                     "colorMode");
-
-        Integer idx = FIELD_METADATA;
-        fieldMap.put("metadata", idx);
-        fieldMap.put("set_metadata", idx);
-        fieldMap.put("metadata_changed", idx);
-
-        idx = FIELD_POINTSIZE_SCALE_FACTOR;
-        fieldMap.put("pointsizeScaleFactor", idx);
-        fieldMap.put("set_pointsizeScaleFactor", idx);
-        fieldMap.put("pointsizeScaleFactor_changed", idx);
-
-        idx = FIELD_POINTSIZE_MIN_VALUE;
-        fieldMap.put("pointsizeMinValue", idx);
-        fieldMap.put("set_pointsizeMinValue", idx);
-        fieldMap.put("pointsizeMinValue_changed", idx);
-
-        idx = FIELD_POINTSIZE_MAX_VALUE;
-        fieldMap.put("pointsizeMaxValue", idx);
-        fieldMap.put("set_pointsizeMaxValue", idx);
-        fieldMap.put("pointsizeMaxValue_changed", idx);
-
-        idx = FIELD_POINTSIZE_ATTENUATION;
-        fieldMap.put("pointsizeAttenuation", idx);
-        fieldMap.put("set_pointsizeAttenuation", idx);
-        fieldMap.put("pointsizeAttenuation_changed", idx);
-
-        idx = FIELD_COLOR_MODE;
-        fieldMap.put("colorMode", idx);
-        fieldMap.put("set_colorMode", idx);
-        fieldMap.put("colorMode_changed", idx);
-
-        typeMap = new HashMap<>();
-        typeMap.put(TEXTURE_COLORMODE, TEXTURE_COLOR_MODE);
-        typeMap.put(POINT_COLORMODE, POINT_COLOR_MODE);
-        typeMap.put(TEXTURE_AND_POINT_COLORMODE, TEXTURE_AND_POINT_COLOR_MODE);
-
-    }
-
-    /**
-     * Construct a default instance of the material
-     */
-    protected BasePointProperties() {
-        super("PointProperties");
-
-        hasChanged = new boolean[NUM_FIELDS];
-
-        vfPointsizeScaleFactor = 1;
-        vfPointsizeMinValue = 1;
-        vfPointsizeMaxValue = 1;
-        vfPointsizeAttenuation = new float[] { 1, 0, 0 };
-        vfColorMode = TEXTURE_COLORMODE;
-        colorMode = TEXTURE_COLOR_MODE;
-    }
-
-    /**
-     * Construct a new instance of this node based on the details from the
-     * given node. If the node is not the right type, an exception will be
-     * thrown.
-     *
-     * @param node The node to copy
-     * @throws IllegalArgumentException The node is not a Group node
-     */
-    protected BasePointProperties(VRMLNodeType node) {
-        this(); // invoke default constructor
-
-        checkNodeType(node);
-
-        try {
-            int index = node.getFieldIndex("pointsizeScaleFactor");
-            VRMLFieldData field = node.getFieldValue(index);
-            vfPointsizeScaleFactor = field.floatValue;
-
-            index = node.getFieldIndex("pointsizeMinValue");
-            field = node.getFieldValue(index);
-            vfPointsizeMinValue = field.floatValue;
-
-            index = node.getFieldIndex("pointsizeMaxValue");
-            field = node.getFieldValue(index);
-            vfPointsizeMaxValue = field.floatValue;
-
-            index = node.getFieldIndex("pointsizeAttenuation");
-            field = node.getFieldValue(index);
-            if (field.numElements != 0) {
-                vfPointsizeAttenuation[0] = field.floatArrayValues[0];
-                vfPointsizeAttenuation[1] = field.floatArrayValues[1];
-                vfPointsizeAttenuation[2] = field.floatArrayValues[2];
-            }
-
-            index = node.getFieldIndex("colorMode");
-            field = node.getFieldValue(index);
-            vfColorMode = field.stringValue;
-            colorMode = typeMap.get(vfColorMode);
-        } catch(VRMLException ve) {
-            throw new IllegalArgumentException(ve.getMessage());
-        }
-    }
-
-    //----------------------------------------------------------
-    // Methods required by the VRMLNodeType interface.
-    //----------------------------------------------------------
-
-    /**
-     * Get the index of the given field name. If the name does not exist for
-     * this node then return a value of -1.
-     *
-     * @param fieldName The name of the field we want the index from
-     * @return The index of the field name or -1
-     */
-    @Override
-    public int getFieldIndex(String fieldName) {
-        Integer index = fieldMap.get(fieldName);
-
-        return (index == null) ? -1 : index;
-    }
-
-    /**
-     * Get the list of indices that correspond to fields that contain nodes
-     * ie MFNode and SFNode). Used for blind scene graph traversal without
-     * needing to spend time querying for all fields etc. If a node does
-     * not have any fields that contain nodes, this shall return null. The
-     * field list covers all field types, regardless of whether they are
-     * readable or not at the VRML-level.
-     *
-     * @return The list of field indices that correspond to SF/MFnode fields
-     *    or null if none
-     */
-    @Override
-    public int[] getNodeFieldIndices() {
-        return nodeFields;
-    }
-
-    /**
-     * Get the declaration of the field at the given index. This allows for
-     * reverse lookup if needed. If the field does not exist, this will give
-     * a value of null.
-     *
-     * @param index The index of the field to get information
-     * @return A representation of this field's information
-     */
-    @Override
-    public VRMLFieldDeclaration getFieldDeclaration(int index) {
-        if (index < 0  || index > NUM_FIELDS - 1)
-            return null;
-
-        return fieldDecl[index];
-    }
-
-    /**
-     * Get the number of fields.
-     *
-     * @return The number of fields.
-     */
-    @Override
-    public int getNumFields() {
-        return fieldDecl.length;
-    }
-
-    /**
-     * Get the primary type of this node.  Replaces the instanceof mechanism
-     * for use in switch statements.
-     *
-     * @return The primary type
-     */
-    @Override
-    public int getPrimaryType() {
-        return TypeConstants.PointPropertiesNodeType;
-    }
-
-    /**
-     * Get the value of a field. If the field is a primitive type, it will
-     * return a class representing the value. For arrays or nodes it will
-     * return the instance directly.
-     *
-     * @param index The index of the field to change.
-     * @return The class representing the field value
-     * @throws InvalidFieldException The field index is not known
-     */
-    @Override
-    public VRMLFieldData getFieldValue(int index) throws InvalidFieldException {
-        VRMLFieldData fieldData = fieldLocalData.get();
-
-        switch(index) {
-            case FIELD_POINTSIZE_SCALE_FACTOR:
-                fieldData.clear();
-                fieldData.floatValue = vfPointsizeScaleFactor;
-                fieldData.dataType = VRMLFieldData.FLOAT_DATA;
-                break;
-
-            case FIELD_POINTSIZE_MIN_VALUE:
-                fieldData.clear();
-                fieldData.floatValue = vfPointsizeMinValue;
-                fieldData.dataType = VRMLFieldData.FLOAT_DATA;
-                break;
-
-            case FIELD_POINTSIZE_MAX_VALUE:
-                fieldData.clear();
-                fieldData.floatValue = vfPointsizeMaxValue;
-                fieldData.dataType = VRMLFieldData.FLOAT_DATA;
-                break;
-
-            case FIELD_POINTSIZE_ATTENUATION:
-                fieldData.clear();
-                fieldData.floatArrayValues = vfPointsizeAttenuation;
-                fieldData.dataType = VRMLFieldData.FLOAT_ARRAY_DATA;
-                fieldData.numElements = 1;
-                break;
-
-            case FIELD_COLOR_MODE:
-                fieldData.clear();
-                fieldData.stringValue = vfColorMode;
-                fieldData.dataType = VRMLFieldData.STRING_DATA;
-                break;
-
-            default:
-                super.getFieldValue(index);
-        }
-
-        return fieldData;
-    }
-
-    /**
-     * Send a routed value from this node to the given destination node. The
-     * route should use the appropriate setValue() method of the destination
-     * node. It should not attempt to cast the node up to a higher level.
-     * Routing should also follow the standard rules for the loop breaking and
-     * other appropriate rules for the specification.
-     *
-     * @param time The time that this route occurred (not necessarily epoch
-     *   time. Should be treated as a relative value only)
-     * @param srcIndex The index of the field in this node that the value
-     *   should be sent from
-     * @param destNode The node reference that we will be sending the value to
-     * @param destIndex The index of the field in the destination node that
-     *   the value should be sent to.
-     */
-    @Override
-    public void sendRoute(double time,
-                          int srcIndex,
-                          VRMLNodeType destNode,
-                          int destIndex) {
-
-        // Simple impl for now.  ignores time and looping
-
-        try {
-            switch(srcIndex) {
-                case FIELD_POINTSIZE_SCALE_FACTOR:
-                    destNode.setValue(destIndex, vfPointsizeScaleFactor);
-                    break;
-
-                case FIELD_POINTSIZE_MIN_VALUE:
-                    destNode.setValue(destIndex, vfPointsizeMinValue);
-                    break;
-
-                case FIELD_POINTSIZE_MAX_VALUE:
-                    destNode.setValue(destIndex, vfPointsizeMaxValue);
-                    break;
-
-                case FIELD_POINTSIZE_ATTENUATION:
-                    destNode.setValue(destIndex, vfPointsizeAttenuation, 3);
-                    break;
-
-                case FIELD_COLOR_MODE:
-                    destNode.setValue(destIndex, vfColorMode);
-                    break;
-
-                default:
-                    super.sendRoute(time, srcIndex, destNode, destIndex);
-            }
-        } catch(InvalidFieldException ife) {
-            System.err.println("sendRoute: No field!" + ife.getFieldName());
-        } catch(InvalidFieldValueException ifve) {
-            System.err.println("sendRoute: Invalid field Value: " +
-                ifve.getMessage());
-        }
-    }
-
-    /**
-     * Set the value of the field at the given index as an int.
-     * This would be used to set String field types.
-     *
-     * @param index The index of destination field to set
-     * @param value The new value to use for the node
-     * @throws InvalidFieldException The field index is not known
-     * @throws InvalidFieldValueException The value provided is not in range
-     *    or not appropriate for this field
-     */
-    @Override
-    public void setValue(int index, String value)
-        throws InvalidFieldException, InvalidFieldValueException {
-
-        switch(index) {
-            case FIELD_COLOR_MODE:
-                setColorMode(value);
-                break;
-
-            default:
-                super.setValue(index, value);
-        }
-    }
-
-
-    /**
-     * Set the value of the field at the given index as a float.
-     * This would be used to set SFFloat field types.
-     *
-     * @param index The index of destination field to set
-     * @param value The new value to use for the node
-     * @throws InvalidFieldException The field index is not known
-     * @throws InvalidFieldValueException The value provided is not in range
-     *    or not appropriate for this field
-     */
-    @Override
-    public void setValue(int index, float value)
-        throws InvalidFieldException, InvalidFieldValueException {
-
-        switch(index) {
-            case FIELD_POINTSIZE_SCALE_FACTOR:
-                setPointSizeScale(value);
-                break;
-
-            case FIELD_POINTSIZE_MIN_VALUE:
-                setPointSizeMin(value);
-                break;
-
-            case FIELD_POINTSIZE_MAX_VALUE:
-                setPointSizeMax(value);
-                break;
-
-            default:
-                super.setValue(index, value);
-        }
-    }
-
-    /**
-     * Set the value of the field at the given index as an array of floats.
-     * This would be used to set SFColor and SFVec3f field types.
-     *
-     * @param index The index of destination field to set
-     * @param value The new value to use for the node
-     * @param numValid The number of valid values to copy from the array
-     */
-    @Override
-    public void setValue(int index, float[] value, int numValid)
-        throws InvalidFieldException, InvalidFieldValueException {
-
-        switch(index) {
-            case FIELD_POINTSIZE_ATTENUATION:
-                setPointSizeAttenuation(value);
-                break;
-
-            default:
-                super.setValue(index, value, numValid);
-        }
-    }
-
-    /**
-     * Set the point size scale factor to the new value.
-     *
-     * @param value The scale value to check
-     * @throws InvalidFieldValueException One of the colour components are out
-     *     of range
-     */
-    protected void setPointSizeScale(float value)
-        throws InvalidFieldValueException {
-
-        if(value <= 0)
-            throw new InvalidFieldValueException(
-                "The pointsizeScaleFactor is <= 0: " + value);
-
-        vfPointsizeScaleFactor = value;
-
-        if(!inSetup) {
-            hasChanged[FIELD_POINTSIZE_SCALE_FACTOR] = true;
-            fireFieldChanged(FIELD_POINTSIZE_SCALE_FACTOR);
-        }
-    }
-
-   /**
-     * Set the point size min value to the new value.
-     *
-     * @param value The min value to set
-     * @throws InvalidFieldValueException The submitted value is out
-     *     of range
-     */
-    protected void setPointSizeMin(float value)
-        throws InvalidFieldValueException {
-
-        if(value < 0)
-            throw new InvalidFieldValueException(
-                "The pointsizeMinValue is < 0: " + value);
-
-        vfPointsizeMinValue = (value == 0) ? 1 : value;
-
-        if(!inSetup) {
-            hasChanged[FIELD_POINTSIZE_MIN_VALUE] = true;
-            fireFieldChanged(FIELD_POINTSIZE_MIN_VALUE);
-        }
-    }
-
-   /**
-     * Set the point size max value to the new value.
-     *
-     * @param value The max value to set
-     * @throws InvalidFieldValueException The submitted value is out
-     *     of range
-     */
-    protected void setPointSizeMax(float value)
-        throws InvalidFieldValueException {
-
-        if(value < 0)
-            throw new InvalidFieldValueException(
-                "The pointsizeMaxValue is < 0: " + value);
-
-        vfPointsizeMaxValue = (value == 0) ? 1 : value;
-
-        if(!inSetup) {
-            hasChanged[FIELD_POINTSIZE_MAX_VALUE] = true;
-            fireFieldChanged(FIELD_POINTSIZE_MAX_VALUE);
-        }
-    }
-
-    /**
-     * Set the attenuation factor of the point size.
-     *
-     * @param factor The new attenuation factor to use
-     * @throws InvalidFieldValueException Attenuation was not [0,1]
-     */
-    protected void setPointSizeAttenuation(float[] factor)
-        throws InvalidFieldValueException {
-
-        if((factor[0] < 0) || (factor[1] < 0) || (factor[2] < 0) ||
-           (factor[0] > 1) || (factor[1] > 1) || (factor[2] > 1))
-            throw new InvalidFieldValueException("attenuation value out of range [0,1]");
-
-        if((factor[0] == 0) && (factor[1] == 0) && (factor[2] == 0))
-            factor[0] = 1;
-
-        vfPointsizeAttenuation[0] = factor[0];
-        vfPointsizeAttenuation[1] = factor[1];
-        vfPointsizeAttenuation[2] = factor[2];
-
-        if(!inSetup) {
-            hasChanged[FIELD_POINTSIZE_ATTENUATION] = true;
-            fireFieldChanged(FIELD_POINTSIZE_ATTENUATION);
-        }
-    }
-
-    /**
-     * Get the currently set color mode. Will be one of the above
-     * constant values.
-     *
-     * @return One of TEXTURE_COLORMODE, COLOR_COLORMODE, TEXTURE_AND_POINT_COLORMODE
-     */
-    @Override
-    public int getColorMode() {
-        return colorMode;
-    }
-
-    /**
-     * Set the color mode to one of the new values. If the value is not known,
-     * issue an exception and leave the value at the current.
-     *
-     * @param mode Constant indicating the mode.
-     * @throws InvalidFieldValueException The value type is unknown
-     */
-    public void setColorMode(int mode) throws InvalidFieldValueException {
-
-        if(mode < DISABLE_COLOR_MODE && mode > TEXTURE_AND_POINT_COLOR_MODE)
-            throw new InvalidFieldValueException(UNKNOWN_TYPE_MSG);
-
-        colorMode = mode;
-
-        if(!inSetup) {
-            hasChanged[FIELD_COLOR_MODE] = true;
-            fireFieldChanged(FIELD_COLOR_MODE);
-        }
-    }
-
-   /**
-     * Set the color mode to the new value.
-     *
-     * @param mode The color mode to set
-     * @throws InvalidFieldValueException The submitted value is out
-     *     of range
-     */
-    @Override
-    public void setColorMode(String mode)
-        throws InvalidFieldValueException {
-
-        if (typeMap.get(mode) != null) {
-            vfColorMode = mode;
-            Integer i_mode = typeMap.get(mode);
-            setColorMode(i_mode);
-        } else
-            throw new InvalidFieldValueException(UNKNOWN_TYPE_MSG + ": " + mode);
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.renderer.common.nodes.shape;
+
+// Standard imports
+import java.util.HashMap;
+import java.util.Map;
+
+// Application specific imports
+import org.web3d.vrml.lang.*;
+
+import org.web3d.vrml.nodes.VRMLNodeType;
+import org.web3d.vrml.nodes.VRMLFieldData;
+import org.web3d.vrml.nodes.VRMLPointPropertiesNodeType;
+
+import org.web3d.vrml.renderer.common.nodes.AbstractNode;
+
+/**
+ * Common base implementation of a PointProperties node.
+ * <p>
+ *
+ * @author Justin Couch
+ * @version $Revision: 1.1 $
+ */
+public abstract class BasePointProperties extends AbstractNode
+    implements VRMLPointPropertiesNodeType {
+
+    /** Field index for pointsizeScaleFactor */
+    protected static final int FIELD_POINTSIZE_SCALE_FACTOR = LAST_NODE_INDEX + 1;
+
+    /** Field index for pointsizeMinValue */
+    protected static final int FIELD_POINTSIZE_MIN_VALUE = LAST_NODE_INDEX + 2;
+
+    /** Field index for pointsizeMaxValue */
+    protected static final int FIELD_POINTSIZE_MAX_VALUE = LAST_NODE_INDEX + 3;
+
+    /** Field index for pointsizeAttenuation */
+    protected static final int FIELD_POINTSIZE_ATTENUATION = LAST_NODE_INDEX + 4;
+
+    /** Field index for colorMode */
+    protected static final int FIELD_COLOR_MODE = LAST_NODE_INDEX + 5;
+
+    /** Number of fields constant */
+    protected static final int NUM_FIELDS = FIELD_COLOR_MODE + 1;
+
+    /** Error message when the user code barfs */
+    private static final String COLOR_MODE_ERROR_MSG =
+        "Error sending color mode changed notification to: ";
+
+    /** Message for when the color mode is invalid */
+    private static final String UNKNOWN_TYPE_MSG =
+        "The color mode provided is not recognised";
+
+    /** Array of VRMLFieldDeclarations */
+    private static VRMLFieldDeclaration[] fieldDecl;
+
+    /** Hashmap between a field name and its index */
+    private static final Map<String, Integer> fieldMap;
+
+    /** Listing of field indexes that have nodes */
+    private static int[] nodeFields;
+
+    // VRML Field declarations
+
+    /** exposedField SFFloat pointsizeScaleFactor 0 */
+    protected float vfPointsizeScaleFactor;
+
+    /** exposedField SFFloat pointsizeMinValue 0 */
+    protected float vfPointsizeMinValue;
+
+    /** exposedField SFFloat pointsizeMaxValue 0 */
+    protected float vfPointsizeMaxValue;
+
+    /** exposedField SFVec3f pointsizeAttenuation 1 0 0 */
+    protected float[] vfPointsizeAttenuation;
+
+    /** exposedField SFString colorMode 0 */
+    protected String vfColorMode;
+
+    /** Constant representing the mode used */
+    protected int colorMode;
+
+    /** Constant describing texture color mode */
+    protected static final String TEXTURE_COLORMODE = "TEXTURE_COLOR";
+
+    /** Constant describing point color mode */
+    protected static final String POINT_COLORMODE = "POINT_COLOR";
+
+    /** Constant describing texture and point mode */
+    protected static final String TEXTURE_AND_POINT_COLORMODE = "TEXTURE_AND_POINT_COLOR";
+
+    /** Mapping between type string and type ints */
+    private static final Map<String, Integer> typeMap;
+
+    // Static constructor
+    static {
+        nodeFields = new int[] { FIELD_METADATA };
+
+        fieldDecl = new VRMLFieldDeclaration[NUM_FIELDS];
+        fieldMap = new HashMap<>(NUM_FIELDS*3);
+
+        fieldDecl[FIELD_METADATA] =
+            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
+                                     "SFNode",
+                                     "metadata");
+        fieldDecl[FIELD_POINTSIZE_SCALE_FACTOR] =
+            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
+                                     "SFFloat",
+                                     "pointsizeScaleFactor");
+        fieldDecl[FIELD_POINTSIZE_MIN_VALUE] =
+            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
+                                     "SFFloat",
+                                     "pointsizeMinValue");
+        fieldDecl[FIELD_POINTSIZE_MAX_VALUE] =
+            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
+                                     "SFFloat",
+                                     "pointsizeMaxValue");
+        fieldDecl[FIELD_POINTSIZE_ATTENUATION] =
+            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
+                                     "SFVec3f",
+                                     "pointsizeAttenuation");
+        fieldDecl[FIELD_COLOR_MODE] =
+            new VRMLFieldDeclaration(FieldConstants.EXPOSEDFIELD,
+                                     "SFString",
+                                     "colorMode");
+
+        Integer idx = FIELD_METADATA;
+        fieldMap.put("metadata", idx);
+        fieldMap.put("set_metadata", idx);
+        fieldMap.put("metadata_changed", idx);
+
+        idx = FIELD_POINTSIZE_SCALE_FACTOR;
+        fieldMap.put("pointsizeScaleFactor", idx);
+        fieldMap.put("set_pointsizeScaleFactor", idx);
+        fieldMap.put("pointsizeScaleFactor_changed", idx);
+
+        idx = FIELD_POINTSIZE_MIN_VALUE;
+        fieldMap.put("pointsizeMinValue", idx);
+        fieldMap.put("set_pointsizeMinValue", idx);
+        fieldMap.put("pointsizeMinValue_changed", idx);
+
+        idx = FIELD_POINTSIZE_MAX_VALUE;
+        fieldMap.put("pointsizeMaxValue", idx);
+        fieldMap.put("set_pointsizeMaxValue", idx);
+        fieldMap.put("pointsizeMaxValue_changed", idx);
+
+        idx = FIELD_POINTSIZE_ATTENUATION;
+        fieldMap.put("pointsizeAttenuation", idx);
+        fieldMap.put("set_pointsizeAttenuation", idx);
+        fieldMap.put("pointsizeAttenuation_changed", idx);
+
+        idx = FIELD_COLOR_MODE;
+        fieldMap.put("colorMode", idx);
+        fieldMap.put("set_colorMode", idx);
+        fieldMap.put("colorMode_changed", idx);
+
+        typeMap = new HashMap<>();
+        typeMap.put(TEXTURE_COLORMODE, TEXTURE_COLOR_MODE);
+        typeMap.put(POINT_COLORMODE, POINT_COLOR_MODE);
+        typeMap.put(TEXTURE_AND_POINT_COLORMODE, TEXTURE_AND_POINT_COLOR_MODE);
+
+    }
+
+    /**
+     * Construct a default instance of the material
+     */
+    protected BasePointProperties() {
+        super("PointProperties");
+
+        hasChanged = new boolean[NUM_FIELDS];
+
+        vfPointsizeScaleFactor = 1;
+        vfPointsizeMinValue = 1;
+        vfPointsizeMaxValue = 1;
+        vfPointsizeAttenuation = new float[] { 1, 0, 0 };
+        vfColorMode = TEXTURE_COLORMODE;
+        colorMode = TEXTURE_COLOR_MODE;
+    }
+
+    /**
+     * Construct a new instance of this node based on the details from the
+     * given node. If the node is not the right type, an exception will be
+     * thrown.
+     *
+     * @param node The node to copy
+     * @throws IllegalArgumentException The node is not a Group node
+     */
+    protected BasePointProperties(VRMLNodeType node) {
+        this(); // invoke default constructor
+
+        checkNodeType(node);
+
+        try {
+            int index = node.getFieldIndex("pointsizeScaleFactor");
+            VRMLFieldData field = node.getFieldValue(index);
+            vfPointsizeScaleFactor = field.floatValue;
+
+            index = node.getFieldIndex("pointsizeMinValue");
+            field = node.getFieldValue(index);
+            vfPointsizeMinValue = field.floatValue;
+
+            index = node.getFieldIndex("pointsizeMaxValue");
+            field = node.getFieldValue(index);
+            vfPointsizeMaxValue = field.floatValue;
+
+            index = node.getFieldIndex("pointsizeAttenuation");
+            field = node.getFieldValue(index);
+            if (field.numElements != 0) {
+                vfPointsizeAttenuation[0] = field.floatArrayValues[0];
+                vfPointsizeAttenuation[1] = field.floatArrayValues[1];
+                vfPointsizeAttenuation[2] = field.floatArrayValues[2];
+            }
+
+            index = node.getFieldIndex("colorMode");
+            field = node.getFieldValue(index);
+            vfColorMode = field.stringValue;
+            colorMode = typeMap.get(vfColorMode);
+        } catch(VRMLException ve) {
+            throw new IllegalArgumentException(ve.getMessage());
+        }
+    }
+
+    //----------------------------------------------------------
+    // Methods required by the VRMLNodeType interface.
+    //----------------------------------------------------------
+
+    /**
+     * Get the index of the given field name. If the name does not exist for
+     * this node then return a value of -1.
+     *
+     * @param fieldName The name of the field we want the index from
+     * @return The index of the field name or -1
+     */
+    @Override
+    public int getFieldIndex(String fieldName) {
+        Integer index = fieldMap.get(fieldName);
+
+        return (index == null) ? -1 : index;
+    }
+
+    /**
+     * Get the list of indices that correspond to fields that contain nodes
+     * ie MFNode and SFNode). Used for blind scene graph traversal without
+     * needing to spend time querying for all fields etc. If a node does
+     * not have any fields that contain nodes, this shall return null. The
+     * field list covers all field types, regardless of whether they are
+     * readable or not at the VRML-level.
+     *
+     * @return The list of field indices that correspond to SF/MFnode fields
+     *    or null if none
+     */
+    @Override
+    public int[] getNodeFieldIndices() {
+        return nodeFields;
+    }
+
+    /**
+     * Get the declaration of the field at the given index. This allows for
+     * reverse lookup if needed. If the field does not exist, this will give
+     * a value of null.
+     *
+     * @param index The index of the field to get information
+     * @return A representation of this field's information
+     */
+    @Override
+    public VRMLFieldDeclaration getFieldDeclaration(int index) {
+        if (index < 0  || index > NUM_FIELDS - 1)
+            return null;
+
+        return fieldDecl[index];
+    }
+
+    /**
+     * Get the number of fields.
+     *
+     * @return The number of fields.
+     */
+    @Override
+    public int getNumFields() {
+        return fieldDecl.length;
+    }
+
+    /**
+     * Get the primary type of this node.  Replaces the instanceof mechanism
+     * for use in switch statements.
+     *
+     * @return The primary type
+     */
+    @Override
+    public int getPrimaryType() {
+        return TypeConstants.PointPropertiesNodeType;
+    }
+
+    /**
+     * Get the value of a field. If the field is a primitive type, it will
+     * return a class representing the value. For arrays or nodes it will
+     * return the instance directly.
+     *
+     * @param index The index of the field to change.
+     * @return The class representing the field value
+     * @throws InvalidFieldException The field index is not known
+     */
+    @Override
+    public VRMLFieldData getFieldValue(int index) throws InvalidFieldException {
+        VRMLFieldData fieldData = fieldLocalData.get();
+
+        switch(index) {
+            case FIELD_POINTSIZE_SCALE_FACTOR:
+                fieldData.clear();
+                fieldData.floatValue = vfPointsizeScaleFactor;
+                fieldData.dataType = VRMLFieldData.FLOAT_DATA;
+                break;
+
+            case FIELD_POINTSIZE_MIN_VALUE:
+                fieldData.clear();
+                fieldData.floatValue = vfPointsizeMinValue;
+                fieldData.dataType = VRMLFieldData.FLOAT_DATA;
+                break;
+
+            case FIELD_POINTSIZE_MAX_VALUE:
+                fieldData.clear();
+                fieldData.floatValue = vfPointsizeMaxValue;
+                fieldData.dataType = VRMLFieldData.FLOAT_DATA;
+                break;
+
+            case FIELD_POINTSIZE_ATTENUATION:
+                fieldData.clear();
+                fieldData.floatArrayValues = vfPointsizeAttenuation;
+                fieldData.dataType = VRMLFieldData.FLOAT_ARRAY_DATA;
+                fieldData.numElements = 1;
+                break;
+
+            case FIELD_COLOR_MODE:
+                fieldData.clear();
+                fieldData.stringValue = vfColorMode;
+                fieldData.dataType = VRMLFieldData.STRING_DATA;
+                break;
+
+            default:
+                super.getFieldValue(index);
+        }
+
+        return fieldData;
+    }
+
+    /**
+     * Send a routed value from this node to the given destination node. The
+     * route should use the appropriate setValue() method of the destination
+     * node. It should not attempt to cast the node up to a higher level.
+     * Routing should also follow the standard rules for the loop breaking and
+     * other appropriate rules for the specification.
+     *
+     * @param time The time that this route occurred (not necessarily epoch
+     *   time. Should be treated as a relative value only)
+     * @param srcIndex The index of the field in this node that the value
+     *   should be sent from
+     * @param destNode The node reference that we will be sending the value to
+     * @param destIndex The index of the field in the destination node that
+     *   the value should be sent to.
+     */
+    @Override
+    public void sendRoute(double time,
+                          int srcIndex,
+                          VRMLNodeType destNode,
+                          int destIndex) {
+
+        // Simple impl for now.  ignores time and looping
+
+        try {
+            switch(srcIndex) {
+                case FIELD_POINTSIZE_SCALE_FACTOR:
+                    destNode.setValue(destIndex, vfPointsizeScaleFactor);
+                    break;
+
+                case FIELD_POINTSIZE_MIN_VALUE:
+                    destNode.setValue(destIndex, vfPointsizeMinValue);
+                    break;
+
+                case FIELD_POINTSIZE_MAX_VALUE:
+                    destNode.setValue(destIndex, vfPointsizeMaxValue);
+                    break;
+
+                case FIELD_POINTSIZE_ATTENUATION:
+                    destNode.setValue(destIndex, vfPointsizeAttenuation, 3);
+                    break;
+
+                case FIELD_COLOR_MODE:
+                    destNode.setValue(destIndex, vfColorMode);
+                    break;
+
+                default:
+                    super.sendRoute(time, srcIndex, destNode, destIndex);
+            }
+        } catch(InvalidFieldException ife) {
+            System.err.println("sendRoute: No field!" + ife.getFieldName());
+        } catch(InvalidFieldValueException ifve) {
+            System.err.println("sendRoute: Invalid field Value: " +
+                ifve.getMessage());
+        }
+    }
+
+    /**
+     * Set the value of the field at the given index as an int.
+     * This would be used to set String field types.
+     *
+     * @param index The index of destination field to set
+     * @param value The new value to use for the node
+     * @throws InvalidFieldException The field index is not known
+     * @throws InvalidFieldValueException The value provided is not in range
+     *    or not appropriate for this field
+     */
+    @Override
+    public void setValue(int index, String value)
+        throws InvalidFieldException, InvalidFieldValueException {
+
+        switch(index) {
+            case FIELD_COLOR_MODE:
+                setColorMode(value);
+                break;
+
+            default:
+                super.setValue(index, value);
+        }
+    }
+
+
+    /**
+     * Set the value of the field at the given index as a float.
+     * This would be used to set SFFloat field types.
+     *
+     * @param index The index of destination field to set
+     * @param value The new value to use for the node
+     * @throws InvalidFieldException The field index is not known
+     * @throws InvalidFieldValueException The value provided is not in range
+     *    or not appropriate for this field
+     */
+    @Override
+    public void setValue(int index, float value)
+        throws InvalidFieldException, InvalidFieldValueException {
+
+        switch(index) {
+            case FIELD_POINTSIZE_SCALE_FACTOR:
+                setPointSizeScale(value);
+                break;
+
+            case FIELD_POINTSIZE_MIN_VALUE:
+                setPointSizeMin(value);
+                break;
+
+            case FIELD_POINTSIZE_MAX_VALUE:
+                setPointSizeMax(value);
+                break;
+
+            default:
+                super.setValue(index, value);
+        }
+    }
+
+    /**
+     * Set the value of the field at the given index as an array of floats.
+     * This would be used to set SFColor and SFVec3f field types.
+     *
+     * @param index The index of destination field to set
+     * @param value The new value to use for the node
+     * @param numValid The number of valid values to copy from the array
+     */
+    @Override
+    public void setValue(int index, float[] value, int numValid)
+        throws InvalidFieldException, InvalidFieldValueException {
+
+        switch(index) {
+            case FIELD_POINTSIZE_ATTENUATION:
+                setPointSizeAttenuation(value);
+                break;
+
+            default:
+                super.setValue(index, value, numValid);
+        }
+    }
+
+    /**
+     * Set the point size scale factor to the new value.
+     *
+     * @param value The scale value to check
+     * @throws InvalidFieldValueException One of the colour components are out
+     *     of range
+     */
+    protected void setPointSizeScale(float value)
+        throws InvalidFieldValueException {
+
+        if(value <= 0)
+            throw new InvalidFieldValueException(
+                "The pointsizeScaleFactor is <= 0: " + value);
+
+        vfPointsizeScaleFactor = value;
+
+        if(!inSetup) {
+            hasChanged[FIELD_POINTSIZE_SCALE_FACTOR] = true;
+            fireFieldChanged(FIELD_POINTSIZE_SCALE_FACTOR);
+        }
+    }
+
+   /**
+     * Set the point size min value to the new value.
+     *
+     * @param value The min value to set
+     * @throws InvalidFieldValueException The submitted value is out
+     *     of range
+     */
+    protected void setPointSizeMin(float value)
+        throws InvalidFieldValueException {
+
+        if(value < 0)
+            throw new InvalidFieldValueException(
+                "The pointsizeMinValue is < 0: " + value);
+
+        vfPointsizeMinValue = (value == 0) ? 1 : value;
+
+        if(!inSetup) {
+            hasChanged[FIELD_POINTSIZE_MIN_VALUE] = true;
+            fireFieldChanged(FIELD_POINTSIZE_MIN_VALUE);
+        }
+    }
+
+   /**
+     * Set the point size max value to the new value.
+     *
+     * @param value The max value to set
+     * @throws InvalidFieldValueException The submitted value is out
+     *     of range
+     */
+    protected void setPointSizeMax(float value)
+        throws InvalidFieldValueException {
+
+        if(value < 0)
+            throw new InvalidFieldValueException(
+                "The pointsizeMaxValue is < 0: " + value);
+
+        vfPointsizeMaxValue = (value == 0) ? 1 : value;
+
+        if(!inSetup) {
+            hasChanged[FIELD_POINTSIZE_MAX_VALUE] = true;
+            fireFieldChanged(FIELD_POINTSIZE_MAX_VALUE);
+        }
+    }
+
+    /**
+     * Set the attenuation factor of the point size.
+     *
+     * @param factor The new attenuation factor to use
+     * @throws InvalidFieldValueException Attenuation was not [0,1]
+     */
+    protected void setPointSizeAttenuation(float[] factor)
+        throws InvalidFieldValueException {
+
+        if((factor[0] < 0) || (factor[1] < 0) || (factor[2] < 0) ||
+           (factor[0] > 1) || (factor[1] > 1) || (factor[2] > 1))
+            throw new InvalidFieldValueException("attenuation value out of range [0,1]");
+
+        if((factor[0] == 0) && (factor[1] == 0) && (factor[2] == 0))
+            factor[0] = 1;
+
+        vfPointsizeAttenuation[0] = factor[0];
+        vfPointsizeAttenuation[1] = factor[1];
+        vfPointsizeAttenuation[2] = factor[2];
+
+        if(!inSetup) {
+            hasChanged[FIELD_POINTSIZE_ATTENUATION] = true;
+            fireFieldChanged(FIELD_POINTSIZE_ATTENUATION);
+        }
+    }
+
+    /**
+     * Get the currently set color mode. Will be one of the above
+     * constant values.
+     *
+     * @return One of TEXTURE_COLORMODE, COLOR_COLORMODE, TEXTURE_AND_POINT_COLORMODE
+     */
+    @Override
+    public int getColorMode() {
+        return colorMode;
+    }
+
+    /**
+     * Set the color mode to one of the new values. If the value is not known,
+     * issue an exception and leave the value at the current.
+     *
+     * @param mode Constant indicating the mode.
+     * @throws InvalidFieldValueException The value type is unknown
+     */
+    public void setColorMode(int mode) throws InvalidFieldValueException {
+
+        if(mode < DISABLE_COLOR_MODE && mode > TEXTURE_AND_POINT_COLOR_MODE)
+            throw new InvalidFieldValueException(UNKNOWN_TYPE_MSG);
+
+        colorMode = mode;
+
+        if(!inSetup) {
+            hasChanged[FIELD_COLOR_MODE] = true;
+            fireFieldChanged(FIELD_COLOR_MODE);
+        }
+    }
+
+   /**
+     * Set the color mode to the new value.
+     *
+     * @param mode The color mode to set
+     * @throws InvalidFieldValueException The submitted value is out
+     *     of range
+     */
+    @Override
+    public void setColorMode(String mode)
+        throws InvalidFieldValueException {
+
+        if (typeMap.get(mode) != null) {
+            vfColorMode = mode;
+            Integer i_mode = typeMap.get(mode);
+            setColorMode(i_mode);
+        } else
+            throw new InvalidFieldValueException(UNKNOWN_TYPE_MSG + ": " + mode);
+    }
+}
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/shape/BaseShape.java b/src/java/org/web3d/vrml/renderer/common/nodes/shape/BaseShape.java
index 80288b3baaa6e4e006813b5d778638b3f43ad76c..964c635cc5cc33a487ba8f4deb6788917009e4a6 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/shape/BaseShape.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/shape/BaseShape.java
@@ -26,6 +26,7 @@ import org.web3d.vrml.util.FieldValidator;
 
 /**
  * Common base renderer implementation of a shape node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.22 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/shape/BaseTwoSidedMaterial.java b/src/java/org/web3d/vrml/renderer/common/nodes/shape/BaseTwoSidedMaterial.java
index c8a784f20e9b17cf9f7b8f56140182566cf32d88..4ed2ad320331ffa128b0b9a8eef0e344394b7724 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/shape/BaseTwoSidedMaterial.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/shape/BaseTwoSidedMaterial.java
@@ -25,6 +25,7 @@ import org.web3d.vrml.util.FieldValidator;
 
 /**
  * Common base implementation of a two-sided material extension node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.4 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/shape/TextureStage.java b/src/java/org/web3d/vrml/renderer/common/nodes/shape/TextureStage.java
index fa16e8874ee17a1b50e1c1c049b372c80f1c052e..3b71f1daf1d0b9ba5cc5c3e4ad1040bf5df3c707 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/shape/TextureStage.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/shape/TextureStage.java
@@ -1,137 +1,139 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2007
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.renderer.common.nodes.shape;
-
-// External imports
-// none
-
-// Local imports
-import org.web3d.image.NIOBufferImage;
-
-import org.web3d.vrml.lang.TextureConstants;
-
-/**
- * Texture Stage information holder used by the Appearance node.
- * 
- * @author Alan Hudson
- * @version $Revision: 1.5 $
- */
-public class TextureStage {
-    // Common setup information
-
-    /** Which stage number this belongs to. Allows for back referencing */
-    public final int stageNumber;
-
-    /** List of image(s) for this stage */
-    public NIOBufferImage[] images;
-
-    /** The texture transform for this stage. Object is renderer-specific */
-    public Object transform;
-
-    /** The texture coordinate generator for this stage. Object is renderer-specific */
-    public Object texCoordGeneration;
-
-    /** The colour of the boundary, if set. */
-    public float[] boundaryColor;
-
-    /** How many pixels wide to make the boundary */
-    public int boundaryWidth;
-
-    /** Boundary mode in the S coordinate direction */
-    public int boundaryModeS;
-
-    /** Boundary mode in the T coordinate direction */
-    public int boundaryModeT;
-
-    /** Minification filter setting */
-    public int minFilter;
-
-    /** Magnification filter setting */
-    public int magFilter;
-
-    /** Flag indicating whether we should generate mipmaps */
-    public boolean generateMipMaps;
-
-    /**
-     *
-     */
-    public int anisotropicMode;
-
-    /**
-     *
-     */
-    public float anisotropicDegree;
-
-    // Multitexture Setup Information
-
-    /**
-     *
-     */
-        public int mode;
-
-    /**
-     *
-     */
-    public int source;
-
-    /**
-     *
-     */
-    public int function;
-
-    /**
-     *
-     */
-    public float alpha;
-
-    /**
-     *
-     */
-    public float[] color;
-
-    // 3D Texture setup information
-    /** How deep is the texture in the 3rd dimension */
-    public int depth;
-
-    /** Boundary mode in the R coordinate direction */
-    public int boundaryModeR;
-
-    /**
-     * Create a default instance of this class with the fields set to:
-     *  <p>
-     *  generateMipMaps: false <br>
-     *  minFilter: TextureConstants.MINFILTER_NICEST <br>
-     *  magFilter: TextureConstants.MAGFILTER_NICEST <br>
-     *  boundaryModeS: TextureConstants.BM_WRAP <br>
-     *  boundaryModeT: TextureConstants.BM_WRAP <br>
-     *  boundaryModeR: TextureConstants.BM_WRAP <br>
-     *  anisotropicMode: TextureConstants.ANISOTROPIC_MODE_NONE <br>
-     *  anisotropicDegree: 1.0f <br>
-     *
-     * @param stage The number of the stage
-     */
-    public TextureStage(int stage) {
-        stageNumber = stage;
-
-        generateMipMaps = false;
-        minFilter = TextureConstants.MINFILTER_NICEST;
-        magFilter = TextureConstants.MAGFILTER_NICEST;
-        boundaryModeS = TextureConstants.BM_WRAP;
-        boundaryModeT = TextureConstants.BM_WRAP;
-        boundaryModeR = TextureConstants.BM_WRAP;
-        anisotropicMode = TextureConstants.ANISOTROPIC_MODE_NONE;
-        anisotropicDegree = 1.0f;
-        depth = 1;
-        color = new float[3];
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001 - 2007
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.renderer.common.nodes.shape;
+
+// External imports
+// none
+
+// Local imports
+import org.web3d.image.NIOBufferImage;
+
+import org.web3d.vrml.lang.TextureConstants;
+
+/**
+ * Texture Stage information holder used by the Appearance node.
+ * <p>
+ *
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.5 $
+ */
+public class TextureStage {
+    // Common setup information
+
+    /** Which stage number this belongs to. Allows for back referencing */
+    public final int stageNumber;
+
+    /** List of image(s) for this stage */
+    public NIOBufferImage[] images;
+
+    /** The texture transform for this stage. Object is renderer-specific */
+    public Object transform;
+
+    /** The texture coordinate generator for this stage. Object is renderer-specific */
+    public Object texCoordGeneration;
+
+    /** The colour of the boundary, if set. */
+    public float[] boundaryColor;
+
+    /** How many pixels wide to make the boundary */
+    public int boundaryWidth;
+
+    /** Boundary mode in the S coordinate direction */
+    public int boundaryModeS;
+
+    /** Boundary mode in the T coordinate direction */
+    public int boundaryModeT;
+
+    /** Minification filter setting */
+    public int minFilter;
+
+    /** Magnification filter setting */
+    public int magFilter;
+
+    /** Flag indicating whether we should generate mipmaps */
+    public boolean generateMipMaps;
+
+    /**
+     *
+     */
+    public int anisotropicMode;
+
+    /**
+     *
+     */
+    public float anisotropicDegree;
+
+    // Multitexture Setup Information
+
+    /**
+     *
+     */
+        public int mode;
+
+    /**
+     *
+     */
+    public int source;
+
+    /**
+     *
+     */
+    public int function;
+
+    /**
+     *
+     */
+    public float alpha;
+
+    /**
+     *
+     */
+    public float[] color;
+
+    // 3D Texture setup information
+    /** How deep is the texture in the 3rd dimension */
+    public int depth;
+
+    /** Boundary mode in the R coordinate direction */
+    public int boundaryModeR;
+
+    /**
+     * Create a default instance of this class with the fields set to:
+     *  <p>
+     *  generateMipMaps: false <br>
+     *  minFilter: TextureConstants.MINFILTER_NICEST <br>
+     *  magFilter: TextureConstants.MAGFILTER_NICEST <br>
+     *  boundaryModeS: TextureConstants.BM_WRAP <br>
+     *  boundaryModeT: TextureConstants.BM_WRAP <br>
+     *  boundaryModeR: TextureConstants.BM_WRAP <br>
+     *  anisotropicMode: TextureConstants.ANISOTROPIC_MODE_NONE <br>
+     *  anisotropicDegree: 1.0f <br>
+     *
+     * @param stage The number of the stage
+     */
+    public TextureStage(int stage) {
+        stageNumber = stage;
+
+        generateMipMaps = false;
+        minFilter = TextureConstants.MINFILTER_NICEST;
+        magFilter = TextureConstants.MAGFILTER_NICEST;
+        boundaryModeS = TextureConstants.BM_WRAP;
+        boundaryModeT = TextureConstants.BM_WRAP;
+        boundaryModeR = TextureConstants.BM_WRAP;
+        anisotropicMode = TextureConstants.ANISOTROPIC_MODE_NONE;
+        anisotropicDegree = 1.0f;
+        depth = 1;
+        color = new float[3];
+    }
+}
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/sound/BaseAudioClip.java b/src/java/org/web3d/vrml/renderer/common/nodes/sound/BaseAudioClip.java
index cc9d8621aca62c28d92c549954213a58d2ca5432..5d7606fe48529059b48fd3f1701d507acf7de78d 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/sound/BaseAudioClip.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/sound/BaseAudioClip.java
@@ -27,6 +27,8 @@ import org.web3d.vrml.renderer.common.nodes.BaseTimeControlledNode;
 
 /**
  * AudioClip node implementation.
+ * <p>
+ *
  *
  * @author Guy Carpenter
  * @version $Revision: 1.23 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/sound/BaseMidiSource.java b/src/java/org/web3d/vrml/renderer/common/nodes/sound/BaseMidiSource.java
index 1cc766735f5d036009078d6d87095b12c1b38a7a..20711a0c3fb85c694e2c29d7563866fef5da84a1 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/sound/BaseMidiSource.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/sound/BaseMidiSource.java
@@ -28,6 +28,7 @@ import org.web3d.vrml.renderer.common.nodes.AbstractNode;
 
 /**
  * Common implementation of a MIDI Event Source.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.11 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/surface/BaseGridLayout.java b/src/java/org/web3d/vrml/renderer/common/nodes/surface/BaseGridLayout.java
index c2949624f4c300570a27c807e6a614b5d8ff96c6..3825ebdfba01f20263cc1b2b54b1be88f2da2d5b 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/surface/BaseGridLayout.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/surface/BaseGridLayout.java
@@ -28,6 +28,7 @@ import org.web3d.vrml.nodes.VRMLSurfaceLayoutNodeType;
 
 /**
  * Common implementation of a GridLayout node.
+ * <p>
  *
  * A grid layout places the contained children in a 2 dimensional grid of
  * rows and columns. The number of grid items can be changed on the fly.
@@ -35,6 +36,7 @@ import org.web3d.vrml.nodes.VRMLSurfaceLayoutNodeType;
  * the extra children are not rendered. If less children than the number
  * of cells defined are provided then it fills in across the row first and
  * then down the columns.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.13 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/surface/BaseGroupLayout.java b/src/java/org/web3d/vrml/renderer/common/nodes/surface/BaseGroupLayout.java
index e99bacabdc8e856010381719e16c3d2e68683f9c..30b8a1133c3da95053606c2acd099284f85ffdd1 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/surface/BaseGroupLayout.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/surface/BaseGroupLayout.java
@@ -25,11 +25,13 @@ import org.web3d.vrml.nodes.VRMLSurfaceChildNodeType;
 
 /**
  * Common implementation of a GroupLayout node.
+ * <p>
  *
  * A group layout is a container for allowing the use of more than one
  * child layout. Typically used to group a bunch of BorderLayouts together
  * under the Overlay node. It has no additional properties beyond the simple
  * layout capabilities.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/surface/BaseImage2D.java b/src/java/org/web3d/vrml/renderer/common/nodes/surface/BaseImage2D.java
index f3ea72a99eba06c6378fdf0971014732bb14aeef..2e52949436e48b20f4670c0872344c8154fa2a3a 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/surface/BaseImage2D.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/surface/BaseImage2D.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.nodes.*;
 
 /**
  * Common implementation of a Image2D node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.12 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/surface/BaseOverlay.java b/src/java/org/web3d/vrml/renderer/common/nodes/surface/BaseOverlay.java
index 858f2b09682d4e68951b39c226bdb2b9a412488e..4540e0273abdf7c609f62bb2eb4c0ccaa5fa8cd7 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/surface/BaseOverlay.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/surface/BaseOverlay.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.common.nodes.AbstractNode;
 
 /**
  * Common implementation of an Overlay node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.13 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/surface/BaseXYLayout.java b/src/java/org/web3d/vrml/renderer/common/nodes/surface/BaseXYLayout.java
index 335cfb1a9115ef314d95a69b098fc1b0185c909a..5c62b7be2002c6ae359016eb9c21c2dbb83c2a2f 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/surface/BaseXYLayout.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/surface/BaseXYLayout.java
@@ -28,10 +28,13 @@ import org.web3d.vrml.nodes.VRMLSurfaceLayoutNodeType;
 
 /**
  * Common implementation of a XYLayout node.
+ * <p>
  *
  * An XY layout places its children in relative positions to its layout location.
  * So a position of 0,64 would place the child 64 units down from the layout 0,0.
  *
+ * <p>
+ *
  * @author Alan Hudson
  * @version $Revision: 1.7 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseComposedCubeMapTexture.java b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseComposedCubeMapTexture.java
index 24974fc8c7648033842ac7ab6f7616d53c1fe119..b27d0a222df9efb64136e291ef392ce9dd4dce89 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseComposedCubeMapTexture.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseComposedCubeMapTexture.java
@@ -27,6 +27,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseTextureNode;
 
 /**
  * Base implementation of a ComposedCubeMapTexture node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseImageCubeMapTexture.java b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseImageCubeMapTexture.java
index dc7314d1b329851c150ee58ba313278867e2bcc8..763066f67ccb124c4c4d9c5e41f7d83a0534ac66 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseImageCubeMapTexture.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseImageCubeMapTexture.java
@@ -27,6 +27,7 @@ import org.web3d.vrml.util.URLChecker;
 
 /**
  * Common implementation of a ImageCubeMapTexture node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseImageTexture.java b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseImageTexture.java
index 07e747b44828a7e40872b3ea231128ba501d23e4..3f4903a5d5032ce5efc94b58e2ba179bb9a5bec9 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseImageTexture.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseImageTexture.java
@@ -31,6 +31,7 @@ import org.web3d.vrml.util.URLChecker;
 
 /**
  * Common implementation of a ImageTexture node.
+ * <p>
  *
  * @author Alan Hudson, Justin Couch
  * @version $Revision: 1.20 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseMovieTexture.java b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseMovieTexture.java
index 00d5d6c9d4f982309fe8011c5d31a8d6386e90c5..643008980a2e2fcca290854e25ea92cadac9416a 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseMovieTexture.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseMovieTexture.java
@@ -33,6 +33,8 @@ import org.web3d.vrml.renderer.common.input.movie.VideoStreamHandler;
 
 /**
  * MovieTexture node implementation.
+ * <p>
+ *
  *
  * @author Guy Carpenter
  * @version $Revision: 1.21 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseMultiTexture.java b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseMultiTexture.java
index ed3663ff96beb43831e95fb8cffaef655195c9c6..868a73e34db82a3088c43b25a453afddbaa07670 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseMultiTexture.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseMultiTexture.java
@@ -31,7 +31,8 @@ import org.web3d.vrml.renderer.common.nodes.BaseTextureNode;
 
 /**
  * Base implementation of a MultiTexture node.
- * 
+ * <p>
+ *
  * @author Alan Hudson
  * @version $Revision: 1.14 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseMultiTextureCoordinate.java b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseMultiTextureCoordinate.java
index d60619df544ca70fed33aea3be4199552aa6b9fe..7665ccb827d178a73b86dc4f95649902440acd2a 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseMultiTextureCoordinate.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseMultiTextureCoordinate.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseGeometricPropertyNode;
 
 /**
  * Base implementation of a multi texture coordinate.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.11 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseMultiTextureTransform.java b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseMultiTextureTransform.java
index 46c69a051d476ce701deb3daa9d420b8892e6e8b..5eb5a4928e8163958812b03ad01e35212c3b848d 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseMultiTextureTransform.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseMultiTextureTransform.java
@@ -26,6 +26,7 @@ import org.web3d.vrml.renderer.common.nodes.AbstractNode;
 
 /**
  * Base implementation of a multi texture transform.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.10 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BasePixelCubeMapTexture.java b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BasePixelCubeMapTexture.java
index 8c4191046e2727d87c6388e98c5d9ca1f2ae534d..aea4843499c5a53238040144b7fe9ef18a0de15c 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BasePixelCubeMapTexture.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BasePixelCubeMapTexture.java
@@ -27,6 +27,7 @@ import org.web3d.vrml.renderer.common.nodes.BaseTextureNode;
 
 /**
  * Common implementation of a PixelCubeMapTexture node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseRenderedTexture.java b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseRenderedTexture.java
index 4b27ec6dff346858bf3d47126975bfa2ac652f6c..ebe4a6a6f3a34909456232f9e01e58f5695bd042 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseRenderedTexture.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseRenderedTexture.java
@@ -24,6 +24,8 @@ import org.web3d.vrml.renderer.common.nodes.BaseTexture2DNode;
 
 /**
  * RenderedTexture node implementation.
+ * <p>
+ *
  *
  * @author Justin Couch
  * @version $Revision: 1.10 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseTextureCoordinate4D.java b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseTextureCoordinate4D.java
index c691b10d08a1052bc9913d5c5b9a0c5c1978f262..f2d410f50a784ff59303d7e467a8fda4e5b8fa17 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseTextureCoordinate4D.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseTextureCoordinate4D.java
@@ -27,11 +27,13 @@ import org.web3d.vrml.renderer.common.nodes.BaseGeometricPropertyNode;
 /**
  * Common base implementation of a texture coordinate node for 4D (homogeneous)
  * coordinates.
+ * <p>
  *
  * Points are held internally as a flat array of values. The point list
  * returned will always be flat. We do this because renderers like point values
  * as a single flat array. The array returned will always contain exactly the
  * number of points specified.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseTextureCoordinateGenerator.java b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseTextureCoordinateGenerator.java
index 9aa0bae0beb10c77859e0300c5b3f1b40a9c1551..16e6bb8ca2f26df66d435d7443e6e7c3da02dd76 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseTextureCoordinateGenerator.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseTextureCoordinateGenerator.java
@@ -25,6 +25,7 @@ import org.web3d.vrml.nodes.VRMLTextureCoordinateNodeType;
 import org.web3d.vrml.renderer.common.nodes.BaseGeometricPropertyNode;
 /**
  * Common base implementation of a texture coordinate generator node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.11 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseTextureProperties.java b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseTextureProperties.java
index 3a7ef37613412babb5575b9086570da304049a0a..c2c92312a5ff8619edc902c51d28e2282ce7bd1b 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseTextureProperties.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseTextureProperties.java
@@ -25,6 +25,7 @@ import org.web3d.vrml.renderer.common.nodes.AbstractNode;
 
 /**
  * Common base implementation of a TextureProperties node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseTextureTransform.java b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseTextureTransform.java
index 1ed7c682f201ad1d3ba2c28e8e10e8ccd1266bed..29c255a8d890410f7856edf4f7141fdabba7930b 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseTextureTransform.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseTextureTransform.java
@@ -32,7 +32,8 @@ import javax.vecmath.Vector3f;
 
 /**
  * norender implementation of a texture transform.
- * 
+ * <p>
+ *
  * @author Alan Hudson
  * @version $Revision: 1.12 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseTextureTransform3D.java b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseTextureTransform3D.java
index 7f12c6cc70968e3b7bce714a8ec1dfa6fdeab665..910954c545cd5f10b31973d0c14bd252bf6743da 100644
--- a/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseTextureTransform3D.java
+++ b/src/java/org/web3d/vrml/renderer/common/nodes/texture/BaseTextureTransform3D.java
@@ -26,6 +26,7 @@ import org.web3d.vrml.renderer.common.nodes.AbstractNode;
 
 /**
  * Base implementation of a texture transform for 3D textures.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.7 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/NRExternProtoBuilder.java b/src/java/org/web3d/vrml/renderer/norender/NRExternProtoBuilder.java
index 2937137d861e6024b0f44da92c459b4d20dc0f98..50165b7fcf4820bbc9d7046d089738ca82b049c7 100644
--- a/src/java/org/web3d/vrml/renderer/norender/NRExternProtoBuilder.java
+++ b/src/java/org/web3d/vrml/renderer/norender/NRExternProtoBuilder.java
@@ -24,9 +24,11 @@ import org.web3d.vrml.renderer.CRExternProtoBuilder;
 
 /**
  * A SAV interface for dealing with building a single extern proto.
+ * <p>
  *
  * The builder is designed to create a single proto. However, that single proto
  * may well have nested protos as part of it, so we must deal with that too.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.6 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/NRSceneBuilderFactory.java b/src/java/org/web3d/vrml/renderer/norender/NRSceneBuilderFactory.java
index fbe80323d92ff66c61b35e1c12f6c832b36032d3..6230d520568e4db9737af5d68cba8e3805045c18 100644
--- a/src/java/org/web3d/vrml/renderer/norender/NRSceneBuilderFactory.java
+++ b/src/java/org/web3d/vrml/renderer/norender/NRSceneBuilderFactory.java
@@ -22,6 +22,8 @@ import org.xj3d.core.loading.SceneBuilderFactory;
 /**
  * Null renderer factory used to create new instances of the scene builder
  * on demand.
+ * <p>
+ *
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/NRTexture2DNodeType.java b/src/java/org/web3d/vrml/renderer/norender/nodes/NRTexture2DNodeType.java
index 9a65f8abea1a6397ac3295cc782d64b567710fbd..00bba5d51f646622e7b31e2e8e570323a42d1d78 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/NRTexture2DNodeType.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/NRTexture2DNodeType.java
@@ -19,7 +19,8 @@ import org.web3d.vrml.nodes.VRMLTexture2DNodeType;
 
 /**
  * Defines a 2D texture.
- * 
+ * <p>
+ *
  * @author Justin Couch
  * @version $Revision: 1.2 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/NRTextureNodeType.java b/src/java/org/web3d/vrml/renderer/norender/nodes/NRTextureNodeType.java
index 6b18e5c9a8d3673e7d21fbd69bec6190fe3061b9..dbd4add8c6946a9ee43d0271385d82bc301c569f 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/NRTextureNodeType.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/NRTextureNodeType.java
@@ -19,6 +19,7 @@ import org.web3d.vrml.nodes.VRMLTextureNodeType;
 
 /**
  * Abstract implementation of a texture object.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/NRVRMLNode.java b/src/java/org/web3d/vrml/renderer/norender/nodes/NRVRMLNode.java
index fa63db66aa3b1d7040d76d0f9c74dd171667aa85..765c6cedccb7d949d50db696caadf1b64f651944 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/NRVRMLNode.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/NRVRMLNode.java
@@ -20,6 +20,7 @@ import org.web3d.vrml.nodes.VRMLNodeType;
 /**
  * Representation of the basic VRMLNodeType specific to the null render
  * rendering system.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRCADAssembly.java b/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRCADAssembly.java
index 1dcc336d2d3ad4a2443e23d4d817321954cb11f1..b9c9c45b940ebb5400831a88c1a38ce40907f326 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRCADAssembly.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRCADAssembly.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null-renderer implementation of the CADAssembly node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRCADFace.java b/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRCADFace.java
index 2ffbf879b0830d45a63da03bbbdba1266a136472..d6e092ce1a8ee0bff720e7c0dc05bae54e091fd3 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRCADFace.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRCADFace.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null-renderer implementation of the CADFace node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRCADLayer.java b/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRCADLayer.java
index 91b3e87d00beedd7074fa4306120093a370a7be8..458e9170e377818b34fa90470754bfcbe8009043 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRCADLayer.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRCADLayer.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null-renderer implementation of the CADLayer node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRCADPart.java b/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRCADPart.java
index bb5ecfe56cc7dc5b2337d8b9012188fac88f0ede..009e286b78ab29092d30f504ba05f69125418497 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRCADPart.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRCADPart.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null-renderer implementation of the CADPart node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRIndexedQuadSet.java b/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRIndexedQuadSet.java
index 598e4c74ae05dcdf0623ffe3dfb83a1372774cff..55f6912a240a269dc690e8ee50e267505320a85a 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRIndexedQuadSet.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRIndexedQuadSet.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null-renderer implementation of the IndexedQuadSet node.
+ * <p>
  *
  * @author Vincent Marchetti
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRQuadSet.java b/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRQuadSet.java
index ba6baa563059d00eee0789a1714ea81528e55e85..f19365856c2b165c87bb04dd79c7741a534fb9f8 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRQuadSet.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/cadgeometry/NRQuadSet.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null-renderer implementation of the CADPart node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/core/NRMetadataInteger.java b/src/java/org/web3d/vrml/renderer/norender/nodes/core/NRMetadataInteger.java
index df4562973fcc7daa3f13b484a1d3091bc2d58725..c5bd47c76791c62da8ac63331bcd51c7ac0ef46b 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/core/NRMetadataInteger.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/core/NRMetadataInteger.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of the MetadataInteger node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/dis/NREspduTransform.java b/src/java/org/web3d/vrml/renderer/norender/nodes/dis/NREspduTransform.java
index 9194703fd14909aac8ce69173765713c7424c277..7156734fff55020a925eeb8f655d8742faf19bf5 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/dis/NREspduTransform.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/dis/NREspduTransform.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * NoRender implementation of a EspduTransform node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/enveffects/NRBackground.java b/src/java/org/web3d/vrml/renderer/norender/nodes/enveffects/NRBackground.java
index 4f7a89925c9d478b09b78f5bfbfe91a330a05c4e..81b131d5f8b719bdd665c39a593bb5134605272e 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/enveffects/NRBackground.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/enveffects/NRBackground.java
@@ -22,10 +22,12 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * A node that can represents a VRML Background node.
+ * <p>
  *
  * A background node in VRML is quite different to the Java3D background. It
  * is represented by a 6 sided box inside a sphere at a nominal infinite
  * distance. Each side of the box may have a different image on it.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/enveffects/NRFog.java b/src/java/org/web3d/vrml/renderer/norender/nodes/enveffects/NRFog.java
index 997af386bf69ba2bb03389277bba9099894062f3..5656d91f2f056411ef7cfdde00bc4fa670755c31 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/enveffects/NRFog.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/enveffects/NRFog.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Non-renderable implementation of a fog node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/enveffects/NRTextureBackground.java b/src/java/org/web3d/vrml/renderer/norender/nodes/enveffects/NRTextureBackground.java
index 93b7955612909625528d3f357c42ba11de499f15..0b009068bc60f8d18250fc56f45177c62e03d7f4 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/enveffects/NRTextureBackground.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/enveffects/NRTextureBackground.java
@@ -22,10 +22,12 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * A node that can represents a VRML Background node.
+ * <p>
  *
  * A background node in VRML is quite different to the Java3D background. It
  * is represented by a 6 sided box inside a sphere at a nominal infinite
  * distance. Each side of the box may have a different image on it.
+ * <p>
  *
  * @author Alan Hidson
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/environment/NRProximitySensor.java b/src/java/org/web3d/vrml/renderer/norender/nodes/environment/NRProximitySensor.java
index fae0f24f3f5b87f308f55bcb46840f817652e14d..bab4e2be93b7c6f4fccf1e5f1e67869282bce481 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/environment/NRProximitySensor.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/environment/NRProximitySensor.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * NoRender implementation of a ProximitySensor node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/environment/NRVisibilitySensor.java b/src/java/org/web3d/vrml/renderer/norender/nodes/environment/NRVisibilitySensor.java
index 4bfda28f84f79e72beab96aea949a8e646729d85..c9331bf57af69113174f67e2c56c9b3552eb891a 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/environment/NRVisibilitySensor.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/environment/NRVisibilitySensor.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * NoRender implementation of a VisibilitySensor node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRBooleanFilter.java b/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRBooleanFilter.java
index be6065231aa395bb4a10b5a7ddb3889293b81339..499a2af06415b8ae30b82f0c7dd2f11306ee16dc 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRBooleanFilter.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRBooleanFilter.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * NoRender implementation of the BooleanFilter node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRBooleanSequencer.java b/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRBooleanSequencer.java
index 840c4b508fec9476239adf16c844051cf97cdc33..2058078e6c7ed487af7d6ec52162bc805c082f0e 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRBooleanSequencer.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRBooleanSequencer.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * NoRender implementation of the BooleanSequencer node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRBooleanToggle.java b/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRBooleanToggle.java
index c209541f4e37b20c6d22c08eb72a9edfaf377ac8..4a2e422d75b9fe12c63ff0eb4da33bcf08f28ac6 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRBooleanToggle.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRBooleanToggle.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * NoRender implementation of the BooleanToggle node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRBooleanTrigger.java b/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRBooleanTrigger.java
index e935c9f8fc1002fe84a8e1c0ec66f9b3271eaa91..f42078b35a79a486c3565ec9c459b9a8749d1407 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRBooleanTrigger.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRBooleanTrigger.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * NoRender implementation of the BooleanTrigger node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRIntegerSequencer.java b/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRIntegerSequencer.java
index 60d14ad0304d9c3f1a5e2c965b341fa729e5b030..3c3a79adcb7439da0635f3cabe46b0e826c15fbf 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRIntegerSequencer.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRIntegerSequencer.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * NoRender implementation of the IntegerSequencer node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRIntegerTrigger.java b/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRIntegerTrigger.java
index 93798aa52be612bc659735c052d272ac8ae87d1b..7c73aca41b6783dc503d53f9ec2a8728f107a1cf 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRIntegerTrigger.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRIntegerTrigger.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * NoRender implementation of the IntegerTrigger node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRTimeTrigger.java b/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRTimeTrigger.java
index 55e72ab8828eda7da15d315848d50fff69d9098b..dbd6575c79253b00d550a4788ed707204bccee9b 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRTimeTrigger.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/eventutils/NRTimeTrigger.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * NoRender implementation of the TimeTrigger node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geom2d/NRPolyline2D.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geom2d/NRPolyline2D.java
index 3870e3cb4768cf0ddab3a485e60a8c9f3f29bb26..e00c2e71d0ec700cb41cf922ba100a0cc40243fc 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geom2d/NRPolyline2D.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geom2d/NRPolyline2D.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a Polyline2D.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geom2d/NRPolypoint2D.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geom2d/NRPolypoint2D.java
index 6d8aaf93c1a81e1c5546af612fe5a7434e7ede7a..a5e1254dec9a8efa6fb7868b35f7881b85252934 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geom2d/NRPolypoint2D.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geom2d/NRPolypoint2D.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a Polypoint2D.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geom2d/NRRectangle2D.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geom2d/NRRectangle2D.java
index 42936147f602d3136ee43cb66a519201a55387e4..544729f01c7a1d84aec60141a212f767caf4c547 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geom2d/NRRectangle2D.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geom2d/NRRectangle2D.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a Rectangle2D.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geom2d/NRTriangleSet2D.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geom2d/NRTriangleSet2D.java
index 8edb86cde085351cf2a165d3c2bc8393822a5b2f..72ab3cc22761758703d015f72c5ecbd2dae7958b 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geom2d/NRTriangleSet2D.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geom2d/NRTriangleSet2D.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a TriangleSet2D.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geom3d/NRBox.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geom3d/NRBox.java
index 781e43de4b0fc0a68984a42b1eb39c4e14725713..c9b0844db6cfd764c7ceb6b73228107184d27634 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geom3d/NRBox.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geom3d/NRBox.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a Box node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geom3d/NRCone.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geom3d/NRCone.java
index 07d5c5d8f8ecb347b1efcbb7b464efb1f252d31b..df889d6d186edd565a503a24d70ae37356a87833 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geom3d/NRCone.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geom3d/NRCone.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a Cone node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geom3d/NRCylinder.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geom3d/NRCylinder.java
index 12bcca0c272cbf791148ddcfd886e1146d372b35..ae46cf3d8750b04052793f1ec6dd1cd06ba33287 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geom3d/NRCylinder.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geom3d/NRCylinder.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a Cylinder.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geom3d/NRExtrusion.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geom3d/NRExtrusion.java
index 0cfeced768f832ba344701bb5795cc2c43179f29..acfd42acb6b3a2c4c45d2634b1ccc460a4c62f42 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geom3d/NRExtrusion.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geom3d/NRExtrusion.java
@@ -1,49 +1,50 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.renderer.norender.nodes.geom3d;
-
-// Standard imports
-// None
-
-// Application specific imports
-import org.web3d.vrml.nodes.VRMLNodeType;
-
-import org.web3d.vrml.renderer.common.nodes.geom3d.BaseExtrusion;
-import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
-
-/**
- * Null renderer implementation of an Extrusion.
- *
- * @author Andrzej Kapolka
- * @version $Revision: 1.2 $
- */
-public class NRExtrusion extends BaseExtrusion implements NRVRMLNode {
-
-    /**
-     * Empty constructor
-     */
-    public NRExtrusion() {
-    }
-
-    /**
-     * Construct a new instance of this node based on the details from the
-     * given node. If the node is not the same type, an exception will be
-     * thrown.
-     *
-     * @param node The node to copy
-     * @throws IllegalArgumentException Incorrect Node Type
-     */
-    public NRExtrusion(VRMLNodeType node) {
-        super(node);
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.renderer.norender.nodes.geom3d;
+
+// Standard imports
+// None
+
+// Application specific imports
+import org.web3d.vrml.nodes.VRMLNodeType;
+
+import org.web3d.vrml.renderer.common.nodes.geom3d.BaseExtrusion;
+import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
+
+/**
+ * Null renderer implementation of an Extrusion.
+ * <p>
+ *
+ * @author Andrzej Kapolka
+ * @version $Revision: 1.2 $
+ */
+public class NRExtrusion extends BaseExtrusion implements NRVRMLNode {
+
+    /**
+     * Empty constructor
+     */
+    public NRExtrusion() {
+    }
+
+    /**
+     * Construct a new instance of this node based on the details from the
+     * given node. If the node is not the same type, an exception will be
+     * thrown.
+     *
+     * @param node The node to copy
+     * @throws IllegalArgumentException Incorrect Node Type
+     */
+    public NRExtrusion(VRMLNodeType node) {
+        super(node);
+    }
+}
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoCoordinate.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoCoordinate.java
index 6610704b3d217e5d75326cd1b2c74c740e091a29..bb42290957830e0a19356348c1cf6bf847758330 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoCoordinate.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoCoordinate.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoCoordinate;
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoCoordinate.
+ * NoRender implementation of an GeoCoordinate
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoECParameters.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoECParameters.java
index 0a6c1f7e1e7100c846e73811768f25b2a957d8e3..943f50ebff60767913e072cc1da8afbf4436a347 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoECParameters.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoECParameters.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoECParameters;
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoECParameters.
+ * NoRender implementation of an GeoECParameters
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoElevationGrid.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoElevationGrid.java
index 4bc1ab527cb8ef3672e6642d8ca75173fe0635d8..af13a1bbd4d49267c054cb3b0dea189cb352ebd5 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoElevationGrid.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoElevationGrid.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoElevationGrid;
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoElevationGrid.
+ * NoRender implementation of an GeoElevationGrid
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLCCParameters.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLCCParameters.java
index 7946dfb5e9d7b97b62965fa73d8844b56af86cf3..8039f0a9059ac360052111679067c25b2d9bf2dd 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLCCParameters.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLCCParameters.java
@@ -21,8 +21,9 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoLCCParameters;
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoLCCParameters.
- * 
+ * NoRender implementation of an GeoLCCParameters
+ * <p>
+ *
  * @author Justin Couch
  * @version $Revision: 1.1 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLCE3DParameters.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLCE3DParameters.java
index 24f744244d1564bc38dc75f619bbf60cb6b86278..a31e511f9a42f0ed8bb657cb2ab0090b5aa01f31 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLCE3DParameters.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLCE3DParameters.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoLCE3DParameters;
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoLCE3DParameters.
+ * NoRender implementation of an GeoLCE3DParameters
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLOD.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLOD.java
index b47616fa73d642962a9563a7a6741c34b01110a5..c27ab67ea55446a631ed9335638bfd8872924e90 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLOD.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLOD.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoLOD;
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoLOD.
+ * NoRender implementation of an GeoLOD
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLSR3DParameters.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLSR3DParameters.java
index e01c20044f09dc3075bca3b884cefc52f181ba23..1ca5e02115a3ba767fc535d99f7316caa2da2f36 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLSR3DParameters.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLSR3DParameters.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoLSR3DParameters;
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoLSR3DParameters.
+ * NoRender implementation of an GeoLSR3DParameters
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLTSEParameters.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLTSEParameters.java
index fdcaa4c15862dfe56079488f298a6dd13a8dd3ed..d7d45d9756bac102590672d32e639cffea9a7a06 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLTSEParameters.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLTSEParameters.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoLTSEParameters;
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoLTSEParameters.
+ * NoRender implementation of an GeoLTSEParameters
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLocalTangentParameters.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLocalTangentParameters.java
index 60ea8f5c1d635487a1fd0c516691072f038620c5..e14d2f3da6c57a55d82000227ee0d3ed12700a9c 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLocalTangentParameters.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLocalTangentParameters.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoLocalTangentParame
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoLocalTangentParameters.
+ * NoRender implementation of an GeoLocalTangentParameters
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLocation.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLocation.java
index 6b1bb3dc7094c32bcfd6e4f13518be84effe4aae..8da0dad7a25fc9392eda4e3526dcaa114ace67a2 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLocation.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoLocation.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoLocation;
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoLocation.
+ * NoRender implementation of an GeoLocation
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoMParameters.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoMParameters.java
index e0578abfe7574d06554b6bbeebc49cc51ec3f12b..19bae3fb6f1a5d23a7ef46dfb64cb283f7304df4 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoMParameters.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoMParameters.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoMParameters;
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoMParameters.
+ * NoRender implementation of an GeoMParameters
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoMetadata.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoMetadata.java
index 7caa465f3ee1ff100976d5d7b4474b974acb6e57..3ea0b007190ba4cae4914cbd59e0a22fae6981eb 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoMetadata.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoMetadata.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoMetadata;
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoMetadata.
+ * NoRender implementation of an GeoMetadata
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoObliqueMercatorParameters.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoObliqueMercatorParameters.java
index 223bb734d874b16a3a995b417183d82c80a0f234..ec83f188a44b1a149d467544e033c74427209f83 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoObliqueMercatorParameters.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoObliqueMercatorParameters.java
@@ -21,8 +21,9 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoObliqueMercatorPar
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoObliqueMercatorParameters.
- * 
+ * NoRender implementation of an GeoObliqueMercatorParameters
+ * <p>
+ *
  * @author Justin Couch
  * @version $Revision: 1.1 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoOrigin.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoOrigin.java
index 05f50bfcc40d734b344117d43cb9357e9fd50cb1..f082aada2c67fe968109b36d3a8af790504330b0 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoOrigin.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoOrigin.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoOrigin;
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoOrigin.
+ * NoRender implementation of an GeoOrigin
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoPSParameters.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoPSParameters.java
index 37c600d16dcc0426dbc6a0222f7650b419c70bd4..081c738d6165366aa85e88e3b2826115958b629e 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoPSParameters.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoPSParameters.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoPSParameters;
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoPSParameters.
+ * NoRender implementation of an GeoPSParameters
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoPositionInterpolator.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoPositionInterpolator.java
index d796c06a121382cdb26fc623e1cbcc001b412ad0..648b6c3f40eec330b1070f7c1460e8d929759fa2 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoPositionInterpolator.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoPositionInterpolator.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoPositionInterpolat
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoPositionInterpolator.
+ * NoRender implementation of an GeoPositionInterpolator
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoReferenceSurfaceInfo.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoReferenceSurfaceInfo.java
index 683699914678527444ff6f5579d42da65977b606..7d51c6704ed805777d5faa6d5381ec01a0085c55 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoReferenceSurfaceInfo.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoReferenceSurfaceInfo.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoReferenceSurfaceIn
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoReferenceSurfaceInfo.
+ * NoRender implementation of an GeoReferenceSurfaceInfo
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoSRFInstance.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoSRFInstance.java
index d8b9c594cde7b32b7a1e70761b883d79b6d3603b..0a66ca0004e7c463a5199e9ad0b547bf1740a25f 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoSRFInstance.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoSRFInstance.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoSRFInstance;
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoSRFInstance.
+ * NoRender implementation of an GeoSRFInstance
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoSRFParametersInfo.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoSRFParametersInfo.java
index f8eb7e0070c1848db7c7be339b07a40d1da6e299..411783309ce326674a9e0306aca86fe3377b09f3 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoSRFParametersInfo.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoSRFParametersInfo.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoSRFParametersInfo;
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoSRFParametersInfo.
+ * NoRender implementation of an GeoSRFParametersInfo
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoSRFSet.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoSRFSet.java
index 30fc3e319613723c7269cc92793dc0aaec1f9617..cf453d6d2e08a26f02a847176a7c97e5ca741889 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoSRFSet.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoSRFSet.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoSRFSet;
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoSRFSet.
+ * NoRender implementation of an GeoSRFSet
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoSRFTemplate.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoSRFTemplate.java
index 09c806f9bebedda1351b9fcb15cf19be67a1ee81..7982ce63643cd8214dee87e180d30faccf186343 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoSRFTemplate.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoSRFTemplate.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoSRFTemplate;
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoSRFTemplate.
+ * NoRender implementation of an GeoSRFTemplate
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoTMParameters.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoTMParameters.java
index 9adba0efbaa7fde2f271f781cea9b6324ef6e3bc..27ef99149ca0cee4bd1e47dd5cf56ddee5ccb089 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoTMParameters.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoTMParameters.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoTMParameters;
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoTMParameters.
+ * NoRender implementation of an GeoTMParameters
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoTouchSensor.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoTouchSensor.java
index d521c45766f3d7ba8610cc2126845a4e56d75e63..e628c979762a034a8b655aa19c93e728ccd8eef6 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoTouchSensor.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoTouchSensor.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoTouchSensor;
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoTouchSensor.
+ * NoRender implementation of an GeoTouchSensor
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoTransform.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoTransform.java
index c3788502e216c8b879ccc216d74f794d5d43b213..8718400c33491ca7ab0a1184642b12133b1a4ce6 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoTransform.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoTransform.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoTransform;
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoTransform.
+ * NoRender implementation of an GeoTransform
+ * <p>
  *
  * @author Rex Melton
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoViewpoint.java b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoViewpoint.java
index a16a419c7e35c47de759802977effda29a556072..8bb7b38b9f8833a0754918cc954190f4cace8edb 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoViewpoint.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/geospatial/NRGeoViewpoint.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoViewpoint;
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * NoRender implementation of an GeoViewpoint.
+ * NoRender implementation of an GeoViewpoint
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/group/NRGroup.java b/src/java/org/web3d/vrml/renderer/norender/nodes/group/NRGroup.java
index 083b69d420cdd4eea89f7edbebecf32af172915b..760e1c14b60f921c0e37a412e622a06593dc5be3 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/group/NRGroup.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/group/NRGroup.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.group.BaseGroup;
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * Null-renderer implementation of a group node..
+ * Null-renderer implementation of a group node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/group/NRMatrixTransform.java b/src/java/org/web3d/vrml/renderer/norender/nodes/group/NRMatrixTransform.java
index bb404c51a4749f350fe36e246385ba99ea3b5729..14fc6198a5ff8afd9cd5299a6cae7b7c9b7355a2 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/group/NRMatrixTransform.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/group/NRMatrixTransform.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.common.nodes.group.BaseMatrixTransform;
 
 /**
  * norender implementation of a transform node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/group/NROrderedGroup.java b/src/java/org/web3d/vrml/renderer/norender/nodes/group/NROrderedGroup.java
index f90f5d009f7c148e6f9ecf1d8e9d0cc91d5d86ed..c904538417c03e1550fd21d51f765fd6a3929ee0 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/group/NROrderedGroup.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/group/NROrderedGroup.java
@@ -22,7 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null-renderer implementation of an ordered group node.
- * 
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/group/NRStaticGroup.java b/src/java/org/web3d/vrml/renderer/norender/nodes/group/NRStaticGroup.java
index 47dedd36d4babfff8e50a6083a005b5df1b46a9d..f679fe8bbb96e818f91c922adc7a64d05797a320 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/group/NRStaticGroup.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/group/NRStaticGroup.java
@@ -22,7 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null-renderer implementation of a StaticGroup node.
- * 
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/group/NRSwitch.java b/src/java/org/web3d/vrml/renderer/norender/nodes/group/NRSwitch.java
index d1008de03e23630b9650073a1b0af99908ed7674..116005fdbcdf7f63830545aefad5684dd62ececc 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/group/NRSwitch.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/group/NRSwitch.java
@@ -21,21 +21,19 @@ import org.web3d.vrml.renderer.common.nodes.group.BaseSwitch;
 import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
- * <p>
  * Norender version of a Switch node.
- * </p>
  * <p>
+ *
  * This code assigns a LOD node as the implGroup. As this code is a
  * grouping node, we allow the use of the children being specified as
  * either the <code>childre</code> field or the <code>level</code> field.
  * The former is VRML3.0 and the latter VRML 2.0
- * </p>
  * <p>
+ *
  * The LOD Behavior node is kept as a child of the group node that works
  * here. When the VRML node is removed from the scene, the behavior is too.
  * When the behavior is asked to be disabled, we just call the
  * <code>setEnable</code> method on the behavior, we do not remove it.
- * </p>
  * <p>
  * If someone routes a range change to us, then we see if it is the same
  * length. If it is, we just set the range values in the existing behavior.
@@ -44,7 +42,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
  * is greater than the number of children nodes, we disable the behavior until
  * the number of children increase to the correct amount. In the branchgroup,
  * the behavior is always
- * </p>
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/group/NRTransform.java b/src/java/org/web3d/vrml/renderer/norender/nodes/group/NRTransform.java
index 85223ee8afdbfbcee0d308fa948d8c38bc0cb820..3764b9ba369569260951444f82e4f4d779c1c068 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/group/NRTransform.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/group/NRTransform.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.common.nodes.group.BaseTransform;
 
 /**
  * norender implementation of a transform node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/hanim/NRHAnimDisplacer.java b/src/java/org/web3d/vrml/renderer/norender/nodes/hanim/NRHAnimDisplacer.java
index dbf9e4547c9cb36ac1a470a1255db8923b34c797..f451a7c715261ce4a06eae013239d7e0c4558f9a 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/hanim/NRHAnimDisplacer.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/hanim/NRHAnimDisplacer.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null-renderer implementation of a HAnimDisplacer node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/hanim/NRHAnimHumanoid.java b/src/java/org/web3d/vrml/renderer/norender/nodes/hanim/NRHAnimHumanoid.java
index f6eb27f468e39b29387bc718e1a99f96894cd154..f876d3726ff66f71496ddc681b4ebeff7ef0948c 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/hanim/NRHAnimHumanoid.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/hanim/NRHAnimHumanoid.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null-renderer implementation of a HAnimHumanoid node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/hanim/NRHAnimJoint.java b/src/java/org/web3d/vrml/renderer/norender/nodes/hanim/NRHAnimJoint.java
index 57385d99f5715df61c8d5b5527cc06a4a1548c59..769bb6ac8594851c60e78492c283d518b4a2cbe7 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/hanim/NRHAnimJoint.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/hanim/NRHAnimJoint.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null-renderer implementation of a HAnimJoint node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/hanim/NRHAnimSegment.java b/src/java/org/web3d/vrml/renderer/norender/nodes/hanim/NRHAnimSegment.java
index 22806a91a0616db57edc6a41ff344d7b7222bdbb..5bddd11880e1daf75d01993e310749e3ade1048e 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/hanim/NRHAnimSegment.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/hanim/NRHAnimSegment.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null-renderer implementation of a HAnimSegment node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/hanim/NRHAnimSite.java b/src/java/org/web3d/vrml/renderer/norender/nodes/hanim/NRHAnimSite.java
index 735abc045f903b4bd1d029118d70e91d20797fba..12c5ee9f51ccfdbc805032bd9b34d4ba5470d0b2 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/hanim/NRHAnimSite.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/hanim/NRHAnimSite.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null-renderer implementation of a HAnimSite node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRColorInterpolator.java b/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRColorInterpolator.java
index f3cee81910c3031f6e9109b04d07e3b6af277f20..bc4ff3c2596733017b8c509a7b05e65d7c7a796a 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRColorInterpolator.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRColorInterpolator.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Implementation of a ColorInterpolator.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRCoordinateInterpolator.java b/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRCoordinateInterpolator.java
index 0d839d15a9244fb3cf23d0d2f9919feeaa3aa28b..11c8c1da01a060ee689ecdffaba0aaa3ec41c6b8 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRCoordinateInterpolator.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRCoordinateInterpolator.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Implementation of a CoordinateInterpolator.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRCoordinateInterpolator2D.java b/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRCoordinateInterpolator2D.java
index c3d9d1fbb66c462118857c87b179a30c3ffa63fd..ee69c321f71a68f15cb1f3a207bef4f0fde8ce26 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRCoordinateInterpolator2D.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRCoordinateInterpolator2D.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Implementation of a CoordinateInterpolator2D.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRNormalInterpolator.java b/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRNormalInterpolator.java
index abef99635474ee2e06b4f5fd82de940f6e185ee3..5a9f9839bc7a2b9ddb09917365f3b726ec9f9f74 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRNormalInterpolator.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRNormalInterpolator.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Implementation of a NormalInterpolator.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NROrientationInterpolator.java b/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NROrientationInterpolator.java
index 3638731cac9201b58dc26529b0d4500b4ccacc83..d5be8e0b34ef659c223644727dafa2d538d4aea7 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NROrientationInterpolator.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NROrientationInterpolator.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Implementation of a OrientationInterpolator.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRPositionInterpolator.java b/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRPositionInterpolator.java
index 7fb26e21fe853344c207b30aa0d07e918e8818b6..a936c536db0ad5ce423bcccf9d9ecd54a6d9647b 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRPositionInterpolator.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRPositionInterpolator.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Implementation of the PositionIterpolator.
+ * <p>
  *
  *
  * @author Justin Couch
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRPositionInterpolator2D.java b/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRPositionInterpolator2D.java
index 7d17cd4ee3c72a4ce118fb32620b09bc0f34d99f..15d0275add9aaaabf4a772a6288f139f1e1946df 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRPositionInterpolator2D.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRPositionInterpolator2D.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Implementation of the PositionIterpolator.
+ * <p>
  *
  *
  * @author Justin Couch
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRScalarInterpolator.java b/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRScalarInterpolator.java
index a1c6baac8223d7cd4e5542afa1ae4607fc5b5636..bae0b3d6147ef68ca0e81ea96bc05bf5a24dda33 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRScalarInterpolator.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/interpolator/NRScalarInterpolator.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Implementation of the VRML ScalarInterpolator node.
+ * <p>
  *
  *
  * @author Justin Couch
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/layering/NRCustomViewport.java b/src/java/org/web3d/vrml/renderer/norender/nodes/layering/NRCustomViewport.java
index 8e74fc4d3857875319f55c2154785d5c9af5ae5b..af53a4ae58299ced612b829484eaa59008af65bd 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/layering/NRCustomViewport.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/layering/NRCustomViewport.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null-renderer implementation of the CustomViewport node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/layering/NRFixedViewport.java b/src/java/org/web3d/vrml/renderer/norender/nodes/layering/NRFixedViewport.java
index e49719fa79837b870d41fb66be674ba03cc22ac4..2e91ad0c85da221ba00d49943cc54d4bb0155180 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/layering/NRFixedViewport.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/layering/NRFixedViewport.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null-renderer implementation of the FixedViewport node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/layering/NRLayer.java b/src/java/org/web3d/vrml/renderer/norender/nodes/layering/NRLayer.java
index fdec74919e30c56800c79f7a320591621ce6bdf1..d32aa458be3df6dbd284064a42b13715d183cc57 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/layering/NRLayer.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/layering/NRLayer.java
@@ -22,7 +22,8 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null-renderer implementation of the Layer node.
- * 
+ * <p>
+ *
  * @author Justin Couch
  * @version $Revision: 1.1 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/layering/NRLayerSet.java b/src/java/org/web3d/vrml/renderer/norender/nodes/layering/NRLayerSet.java
index 9249968f7a92714285ef294abcfd80b5477e035b..831a5c46ee38c92b816c9e662574427c9ad51fe3 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/layering/NRLayerSet.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/layering/NRLayerSet.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null-renderer implementation of the Layer node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/layering/NRProportionalViewport.java b/src/java/org/web3d/vrml/renderer/norender/nodes/layering/NRProportionalViewport.java
index fb167eaf14b2d2217ca8c962c84b5272be17a2ef..75cd56f49e26443247098bd066bdfd18c4968074 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/layering/NRProportionalViewport.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/layering/NRProportionalViewport.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null-renderer implementation of the ProportionalViewport node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRBorderLayout.java b/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRBorderLayout.java
index 8628e65bf8f5eb496e20734f6be1a7829867c25c..1c61b4f90b2ea628cf8099da0e80af88952aa5d0 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRBorderLayout.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRBorderLayout.java
@@ -22,6 +22,8 @@ import org.web3d.vrml.renderer.common.nodes.layout.BaseBorderLayout;
 
 /**
  * Null-renderer implementation of a BorderLayout node.
+ * <p>
+ *
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRGridLayout.java b/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRGridLayout.java
index e1dee5370b73d336f51524ec09af29f82d0bfc93..dd941dbccf6bc9d2796fd5ad9a625b0d1b294a58 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRGridLayout.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRGridLayout.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.common.nodes.layout.BaseGridLayout;
 
 /**
  * Null-renderer implementation of a GridLayout node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRGroupLayout.java b/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRGroupLayout.java
index 8f4d69d872f50641f9b8a259db98e7cbfae0d956..8e9d29497027b30a5605a14810b78896bc4249b5 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRGroupLayout.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRGroupLayout.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.common.nodes.layout.BaseGroupLayout;
 
 /**
  * Null-renderer implementation of a GroupLayout node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRImage2D.java b/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRImage2D.java
index 5e981aa07cbb3ccd24ec717453997972dc594241..d8a236b82ef39a800a7b0694a40b0c05d6098e90 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRImage2D.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRImage2D.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.common.nodes.layout.BaseImage2D;
 
 /**
  * Common implementation of a Image2D node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRLayer2D.java b/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRLayer2D.java
index 5454fed3ca28ec3d568d0279acf74bf33e78a4b1..fda2f7f8970b87cdb1add35a92edb039cec83ed6 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRLayer2D.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRLayer2D.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.common.nodes.layout.BaseLayer2D;
 
 /**
  * Null-renderer implementation of an Layer2D node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRText2D.java b/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRText2D.java
index fb86f53689f6ec4eb0040e2056bcc0d67761edcd..319069bb1e2000a006584f0acd530eb347f8455a 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRText2D.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRText2D.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.common.nodes.layout.BaseText2D;
 
 /**
  * Common implementation of a Text2D node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRXYLayout.java b/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRXYLayout.java
index f9a25f9b061616bdaf8b3fb05918325ab115881a..5e483faa4b6f76443f777eb8a12f8d52d4663075 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRXYLayout.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/layout/NRXYLayout.java
@@ -22,7 +22,9 @@ import org.web3d.vrml.renderer.common.nodes.layout.BaseXYLayout;
 
 /**
  * Null-renderer implementation of a XYLayout node.
- * 
+ * <p>
+ *
+ *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/lighting/NRDirectionalLight.java b/src/java/org/web3d/vrml/renderer/norender/nodes/lighting/NRDirectionalLight.java
index a8024df782a2a77bf6efb70712f2fb4245e1aed4..e6c42ba3047f0d7f320b37ef0b0a720fecb73410 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/lighting/NRDirectionalLight.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/lighting/NRDirectionalLight.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * No-render implementation of a directional light.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/lighting/NRPointLight.java b/src/java/org/web3d/vrml/renderer/norender/nodes/lighting/NRPointLight.java
index 272b2084a04345fdda358df7eb7ad4ecc58825c1..69eeb0fddf865b306de57ec15587de2239501590 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/lighting/NRPointLight.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/lighting/NRPointLight.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * NoRender implementation of a pointlight.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/lighting/NRSpotLight.java b/src/java/org/web3d/vrml/renderer/norender/nodes/lighting/NRSpotLight.java
index 0e87dc79b784bc11acca5738dc565d3b4687023c..a923458ff6c49a5a436ab3d7031b1735dfc9be0d 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/lighting/NRSpotLight.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/lighting/NRSpotLight.java
@@ -22,7 +22,8 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * no-render implementation of a spotlight.
- * 
+ * <p>
+ *
  * @author Alan Hudson
  * @version $Revision: 1.4 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/navigation/NRBillboard.java b/src/java/org/web3d/vrml/renderer/norender/nodes/navigation/NRBillboard.java
index f44be562da8a9b24735bff641988f7e3ce785cb7..9d2909c26d8e440cac5d0af05b1a8d98de29748c 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/navigation/NRBillboard.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/navigation/NRBillboard.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null-renderer implementation of a Billboard node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/navigation/NRCollision.java b/src/java/org/web3d/vrml/renderer/norender/nodes/navigation/NRCollision.java
index 294189db8e108e56e77ad8cdebc5202e693d40a5..c0732d39d5cad94edf6c619aa7ab37c8e1698002 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/navigation/NRCollision.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/navigation/NRCollision.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null-renderer implementation of a Collision node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/navigation/NRLOD.java b/src/java/org/web3d/vrml/renderer/norender/nodes/navigation/NRLOD.java
index 78a03e95d45c2519e3b4aff8dda6f36ea79b5e04..fc1f040e78b11a5e65e8e9b1fa99357389715bc8 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/navigation/NRLOD.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/navigation/NRLOD.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null-renderer implementation of a LOD node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/navigation/NRNavigationInfo.java b/src/java/org/web3d/vrml/renderer/norender/nodes/navigation/NRNavigationInfo.java
index 75b180fc4a1d0e14eb346b4d4c8229814dec61c0..25d828dc932a0df8c92f8a3418f8ee535bfa2ea5 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/navigation/NRNavigationInfo.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/navigation/NRNavigationInfo.java
@@ -22,11 +22,13 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a NavigationInfo node.
+ * <p>
  *
  * The NavigationInfo node does not occupy a space in the Java 3D
  * scene graph. This is used as a VRML construct only. When VRML changes the
  * values here, we pass them back courtesy of the listeners to the children
  * nodes.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/networking/NRLoadSensor.java b/src/java/org/web3d/vrml/renderer/norender/nodes/networking/NRLoadSensor.java
index 44ec8838743c30461a39e1a4cab87ca22be1eabc..6fff5ea631c64c81b3b880b4670c189b3944cd73 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/networking/NRLoadSensor.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/networking/NRLoadSensor.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * NoRender implementation of a LoadSensor node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRExplosionEmitter.java b/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRExplosionEmitter.java
index 8852235e293efe9a3e40d081b7f76a6047a29499..53e05619a42479af8f00aa9723bfb6f3150fc4bf 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRExplosionEmitter.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRExplosionEmitter.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a ExplosionEmitter node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 2.0 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRGravityPhysicsModel.java b/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRGravityPhysicsModel.java
index 4288cf5fcbd7aad4091f4a674ef88ce8e596226d..35ee5d2387ceace7cebc558d74f6ee634ca9d5cc 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRGravityPhysicsModel.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRGravityPhysicsModel.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a GravityPhysicsModel node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 2.0 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRParticleSystem.java b/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRParticleSystem.java
index 519556c3dbd3513d06eed1f46633c0a8eb1e37c4..ebaa7933e91aceaeba2ce4e6a1a3352305ca4b8e 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRParticleSystem.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRParticleSystem.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a particle system node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 2.0 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRPointEmitter.java b/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRPointEmitter.java
index 400a49961069d04fbde55e43fff6a4b418d47f85..d331583a4f14bf30e32a6a484bf4e08d8934f795 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRPointEmitter.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRPointEmitter.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a PointEmitter node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 2.0 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRPolylineEmitter.java b/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRPolylineEmitter.java
index 66037617f5b0057696c8ec8dd71cfcce21994142..9cc92403530b55257d47b5fcac54970baf3a7d52 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRPolylineEmitter.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRPolylineEmitter.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a PolylineEmitter node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 2.0 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRWindPhysicsModel.java b/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRWindPhysicsModel.java
index 664e41f29d6affdfe9529c840d8894dde49930a9..be785df6a356ac06f206e3160b80f3a61b970e76 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRWindPhysicsModel.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/particle/NRWindPhysicsModel.java
@@ -22,7 +22,8 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a WindPhysicsModel node.
- * 
+ * <p>
+ *
  * @author Justin Couch
  * @version $Revision: 2.0 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/picking/NRLinePicker.java b/src/java/org/web3d/vrml/renderer/norender/nodes/picking/NRLinePicker.java
index 0ba59277bcd0e9eedddefbc5871a123b1bfebb7f..6ce09f1afe94e35f1ef1f9991a9e9c1d7a539afb 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/picking/NRLinePicker.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/picking/NRLinePicker.java
@@ -21,6 +21,7 @@ import org.web3d.vrml.renderer.common.nodes.picking.BaseLinePicker;
 
 /**
  * Null-renderer implementation of a LinePicker node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/picking/NRPickableGroup.java b/src/java/org/web3d/vrml/renderer/norender/nodes/picking/NRPickableGroup.java
index c49254c3c42802c4d8c88ddaa62016a74f0fd341..791fae6cb724ef1402686ab7c1526979fe34721a 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/picking/NRPickableGroup.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/picking/NRPickableGroup.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.common.nodes.picking.BasePickableGroup;
 
 /**
  * Null-renderer implementation of a PickableGroup node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/picking/NRPointPicker.java b/src/java/org/web3d/vrml/renderer/norender/nodes/picking/NRPointPicker.java
index 3ee1a0730f7ed8ee08a0ba23c2f72f9e60490e92..15374e592dd4d51b9a3082ef89185abff7b38ad2 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/picking/NRPointPicker.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/picking/NRPointPicker.java
@@ -21,6 +21,7 @@ import org.web3d.vrml.renderer.common.nodes.picking.BasePointPicker;
 
 /**
  * Null-renderer implementation of a PointPicker node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/picking/NRPrimitivePicker.java b/src/java/org/web3d/vrml/renderer/norender/nodes/picking/NRPrimitivePicker.java
index 40bbfe9228e7abd28d80f1e3cb975eb38430a05f..bb202086d08c6a29c245d7eb7764533929366a82 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/picking/NRPrimitivePicker.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/picking/NRPrimitivePicker.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.picking.BasePrimitivePicker;
 
 /**
  * Null-renderer implementation of a PrimitivePicker node.
- * 
+ * <p>
+ *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/picking/NRVolumePicker.java b/src/java/org/web3d/vrml/renderer/norender/nodes/picking/NRVolumePicker.java
index 91b52c09feb320bc8d51d25da7675db19456fcfb..e8c0f505350c3044c45ca6e13b07fcbcbe2247b6 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/picking/NRVolumePicker.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/picking/NRVolumePicker.java
@@ -21,6 +21,7 @@ import org.web3d.vrml.renderer.common.nodes.picking.BaseVolumePicker;
 
 /**
  * Null-renderer implementation of a VolumePicker node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRIndexedLineSet.java b/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRIndexedLineSet.java
index e5ec58c1d28c977ba2598644f8c9a83cd9deedd2..1d64a957145d796edacfc1d31f61f6ca743e56b0 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRIndexedLineSet.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRIndexedLineSet.java
@@ -23,6 +23,8 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a VRML IndexedLineSet.
+ * <p>
+ *
  *
  * @author Justin Couch
  * @version $Revision: 1.4 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRIndexedTriangleFanSet.java b/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRIndexedTriangleFanSet.java
index 5c3ff39aac67931445de517d73b6f3bcb404f69e..2e4ce19572fbfc71d5c944b4922b2ffcbfbddab2 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRIndexedTriangleFanSet.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRIndexedTriangleFanSet.java
@@ -23,6 +23,8 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a IndexedTriangleFanSet node.
+ * <p>
+ *
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRIndexedTriangleSet.java b/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRIndexedTriangleSet.java
index c89449d8a115e28c04c769dab7ec9ff131f80a25..2e66a05cc9bbb405b9bb0631f2e1386bfff8602f 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRIndexedTriangleSet.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRIndexedTriangleSet.java
@@ -23,7 +23,9 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a IndexedTriangleSet node.
- * 
+ * <p>
+ *
+ *
  * @author Justin Couch
  * @version $Revision: 1.2 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRIndexedTriangleStripSet.java b/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRIndexedTriangleStripSet.java
index 783c4370b19b52608bdaa536c9dd03774c1bf943..a445a9b6074a764a1c95e1458af909f12c278ed7 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRIndexedTriangleStripSet.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRIndexedTriangleStripSet.java
@@ -23,7 +23,9 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a IndexedTriangleStripSet node.
- * 
+ * <p>
+ *
+ *
  * @author Justin Couch
  * @version $Revision: 1.2 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRLineSet.java b/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRLineSet.java
index cbb881be1a32030b43d9a3b39749e441da669d9f..2b0e728465ecf55ffa50404a8b872d340b059600 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRLineSet.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRLineSet.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of an LineSet.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRPointSet.java b/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRPointSet.java
index 4cd5ec46795a537f511ef9f255a8d3e9bcbc1bcc..81b1cd2a3ecf9b0b244bfb76826c74f1a280324c 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRPointSet.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRPointSet.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of an PointSet.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRTriangleFanSet.java b/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRTriangleFanSet.java
index ee554dfc3272e57ffb21583a289cf8df99dd0482..321f51831d754faf2a09bc9d49636ace690250bc 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRTriangleFanSet.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRTriangleFanSet.java
@@ -23,6 +23,8 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a TriangleFanSet node.
+ * <p>
+ *
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRTriangleSet.java b/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRTriangleSet.java
index 38affd10e535f881252e00917b01fc56d1b30b83..04d353aaa0e046436fe5ce78fb0b84eb33570682 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRTriangleSet.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRTriangleSet.java
@@ -23,6 +23,8 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a TriangleSet node.
+ * <p>
+ *
  *
  * @author Justin Couch
  * @version $Revision: 1.4 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRTriangleStripSet.java b/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRTriangleStripSet.java
index d1bf60c2271bbce24a50d11c8adf8d50c20950f1..afeb3da3a779011e57a7328e98619bf84cd2860a 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRTriangleStripSet.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/render/NRTriangleStripSet.java
@@ -23,7 +23,9 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a TriangleStripSet node.
- * 
+ * <p>
+ *
+ *
  * @author Justin Couch
  * @version $Revision: 1.2 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRBallJoint.java b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRBallJoint.java
index c4edd831223d20a05e51824728cb1a5cf7d32a43..15e28124b16f002842454db52d9ae64b1e0b6a92 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRBallJoint.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRBallJoint.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Implementation of a BallJoint.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRCollidableOffset.java b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRCollidableOffset.java
index e833508d4281f6549cdb04613025acfca29c7d5b..cc50ff46e74c13f56ec42dbc2129cb851b217060 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRCollidableOffset.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRCollidableOffset.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Implementation of a CollidableOffset.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRCollidableShape.java b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRCollidableShape.java
index fae1798413e8ebe30455759ddc69f1f98834f71f..6d9b71e4adc024fe6de63adeeb94174195a299b4 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRCollidableShape.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRCollidableShape.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Implementation of a CollidableShape.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRCollisionCollection.java b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRCollisionCollection.java
index 724ebc312136eed7040a549768c5b2d4496477bd..fde183f9058dc4eee4187b28789235a55884d307 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRCollisionCollection.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRCollisionCollection.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Implementation of a CollisionCollection.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRCollisionSensor.java b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRCollisionSensor.java
index b59cf2b77a792786fa26f00528add4a5340c1f1a..db90642f6fbb4dd36119eaea5a9e3d032adc1288 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRCollisionSensor.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRCollisionSensor.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Implementation of a CollisionSensor.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRCollisionSpace.java b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRCollisionSpace.java
index e198ee7a2a41cd5ccc8f6024423c7e85731b11fe..3c480b633f77dddcb5223ad503ff83abf4c5a0db 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRCollisionSpace.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRCollisionSpace.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Implementation of a CollisionSpace.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRContact.java b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRContact.java
index 946ab549209a5d337a1370757a637511a27970c7..e278fa29c7534089ec2bb09bf8a47e62630f4739 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRContact.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRContact.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Implementation of a Contact.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRDoubleAxisHingeJoint.java b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRDoubleAxisHingeJoint.java
index 34827d288c436eda817aa4b30fbdb1959f447ee8..575c80b74a8abfed6b272f98835684e24285bf62 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRDoubleAxisHingeJoint.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRDoubleAxisHingeJoint.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Implementation of a DoubleAxisHingeJoint.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRMotorJoint.java b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRMotorJoint.java
index 9f1b6ac23345a41c11e0564759515448b596a19d..aa86cde48810c008853374beddd76c8405a00707 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRMotorJoint.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRMotorJoint.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Implementation of a MotorJoint.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRRigidBody.java b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRRigidBody.java
index 979284d0fd6752279194b7247aca0b08216630c1..c1ca2e8c2a43978a6aa9c6f90435b99f1be23391 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRRigidBody.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRRigidBody.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Implementation of a RigidBody.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRRigidBodyCollection.java b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRRigidBodyCollection.java
index 29439b30bdf5fe914208c9fbac9614c9e823373b..6d1a16b673d39cb9afa4af6fcc5b29507a24c189 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRRigidBodyCollection.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRRigidBodyCollection.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Implementation of a RigidBodyCollection.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRSingleAxisHingeJoint.java b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRSingleAxisHingeJoint.java
index b859944904c2d62836c572c53aba3edacae8042e..7541472a0181c801d4a96c7ba4c18bbadeddb156 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRSingleAxisHingeJoint.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRSingleAxisHingeJoint.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Implementation of a SingleAxisHingeJoint.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRSliderJoint.java b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRSliderJoint.java
index 22ed4bf58355966f6966d1d4e0a3f0c1596ba431..bae9ad20dd25b41aaedd2da4533e00cb35123e7b 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRSliderJoint.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRSliderJoint.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Implementation of a SliderJoint.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRUniversalJoint.java b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRUniversalJoint.java
index 80354bf083edfc2a14e74d90c9f23ff1530095d9..edd0b04ea694687302464f1ef9c62fc2ab13caf9 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRUniversalJoint.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/rigidphysics/NRUniversalJoint.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Implementation of a UniversalJoint.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/sensor/NRCylinderSensor.java b/src/java/org/web3d/vrml/renderer/norender/nodes/sensor/NRCylinderSensor.java
index b342211a64ceb0bfcb9dadd729bf380f22ef34c7..1e7ae355ba6dc2c2c0ecc9abdfb533b15607f2bd 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/sensor/NRCylinderSensor.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/sensor/NRCylinderSensor.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.common.nodes.sensor.BaseCylinderSensor;
 
 /**
  * Null-renderer implementation of a CylinderSensor node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/sensor/NRPlaneSensor.java b/src/java/org/web3d/vrml/renderer/norender/nodes/sensor/NRPlaneSensor.java
index b8f9f18cff7865451950511bcbf86e7ba89666f9..cba9bd1d9ffbc5dfe2454aad3dae6559a7956f4b 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/sensor/NRPlaneSensor.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/sensor/NRPlaneSensor.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.common.nodes.sensor.BasePlaneSensor;
 
 /**
  * Null-renderer implementation of a PlaneSensor node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/sensor/NRSphereSensor.java b/src/java/org/web3d/vrml/renderer/norender/nodes/sensor/NRSphereSensor.java
index 06c30d5f614d4edc63ac34e8cf249f4b6d5735e9..6225fd5e6e70a605f3dabc039b74267a7f9145f9 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/sensor/NRSphereSensor.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/sensor/NRSphereSensor.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.common.nodes.sensor.BaseSphereSensor;
 
 /**
  * Null-renderer implementation of a SphereSensor node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/sensor/NRTouchSensor.java b/src/java/org/web3d/vrml/renderer/norender/nodes/sensor/NRTouchSensor.java
index d18fe4d65b153b0fe3ff5daaa28865005ea546a6..3c7affe2d6ba6921ee8bd31ba4715693a48ac714 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/sensor/NRTouchSensor.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/sensor/NRTouchSensor.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.common.nodes.sensor.BaseTouchSensor;
 
 /**
  * Null-renderer implementation of a TouchSensor node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.6 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRAppearance.java b/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRAppearance.java
index c4b6fef5127ee52ceea808b93ca9f1ec609e8bad..201196493ce1cd0960992d4b3ef31fc0f1fba1ce 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRAppearance.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRAppearance.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.common.nodes.shape.BaseAppearance;
 
 /**
  * Null renderer implementation of an Appearance node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRFillProperties.java b/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRFillProperties.java
index 1fc4bc36d56beff7e49b11eee231a3fb42c99362..8728ebfc5c88e746e6d0ee87bb7ebe3de6749456 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRFillProperties.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRFillProperties.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.common.nodes.shape.BaseFillProperties;
 
 /**
  * Null renderer implementation of an FillProperties node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRLineProperties.java b/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRLineProperties.java
index 0cf64b4747b30356b249c5fe1081b19c970e091d..2114afadd9d02689b9a49f45fa60925a53b17c5e 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRLineProperties.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRLineProperties.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.common.nodes.shape.BaseLineProperties;
 
 /**
  * Null renderer implementation of an LineProperties node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRMaterial.java b/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRMaterial.java
index 6c856162ff743c852ba2a513b90c48b492a51043..53925fa64828ee68b491393a02bb8e26b4b8eeaf 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRMaterial.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRMaterial.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a material node.
+ * <p>
  *
  * @author Russell Dodds
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRPointProperties.java b/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRPointProperties.java
index 8c827ceeac0ac9900fb7ac86917b04e4014d6e28..f6d97f8f9b1a9cbecce869ce3f1a647cb664b572 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRPointProperties.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRPointProperties.java
@@ -21,7 +21,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 import org.web3d.vrml.renderer.common.nodes.shape.BasePointProperties;
 
 /**
- * Non-rendering PointProperties node
+ *
  * @author terry
  */
 public class NRPointProperties extends BasePointProperties
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRShape.java b/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRShape.java
index 38dd66736ba76d13a82b877b1c8ccbeb7166e66b..5e1037a6c39d4f8d19073c05d1fd5b3787fba9f1 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRShape.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/shape/NRShape.java
@@ -25,6 +25,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a shape node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.4 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/sound/NRAudioClip.java b/src/java/org/web3d/vrml/renderer/norender/nodes/sound/NRAudioClip.java
index b4226c9e4db6090a1554e1cc0c2acda5a94c75a5..938a9e2de6e32d2236447bdd3ae3bb0ac4652e24 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/sound/NRAudioClip.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/sound/NRAudioClip.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Implementation of an AudioClip.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/sound/NRSound.java b/src/java/org/web3d/vrml/renderer/norender/nodes/sound/NRSound.java
index ca32a90f55399dcc7ad0c8d34a7084e3fbc4f3a8..e68a78678e08c354ce59f8d61aa241ddcc708b0d 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/sound/NRSound.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/sound/NRSound.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 /**
  * Implementation of a sound node for no renderer.
  * This node is used for the creation of PROTOs
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRBorderLayout.java b/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRBorderLayout.java
index b5adcf09d2ced19f6901ac8aa8cb9ce0813af09e..499ec243ce253949aa713784339aac0a8a4a07f6 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRBorderLayout.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRBorderLayout.java
@@ -22,7 +22,9 @@ import org.web3d.vrml.renderer.common.nodes.surface.BaseBorderLayout;
 
 /**
  * Null-renderer implementation of a BorderLayout node.
- * 
+ * <p>
+ *
+ *
  * @author Justin Couch
  * @version $Revision: 1.1 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRGridLayout.java b/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRGridLayout.java
index cd3ecefafde588a46e6e6a50beab935693365fb6..28570dcac79097337834a0dd2f826284688b9723 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRGridLayout.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRGridLayout.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.common.nodes.surface.BaseGridLayout;
 
 /**
  * Null-renderer implementation of a GridLayout node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRGroupLayout.java b/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRGroupLayout.java
index a24d42d817c37f0f732c8fcd5fb4e65598984235..2f304cbd2c0441bbdacbc3361a03633499232698 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRGroupLayout.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRGroupLayout.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.common.nodes.surface.BaseGroupLayout;
 
 /**
  * Null-renderer implementation of a GroupLayout node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRImage2D.java b/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRImage2D.java
index 8bfd90e532a05f338929b40ba78f88817f5affaf..bd402b66f774efadc6bcea2f29a3fadabbdc5764 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRImage2D.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRImage2D.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.common.nodes.surface.BaseImage2D;
 
 /**
  * Common implementation of a Image2D node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NROverlay.java b/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NROverlay.java
index 5580b3c23cdfc9bd8018bd241c31c706178b4c8d..35a21b815caa1f8b624d45f83cda2b3d2eefb63f 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NROverlay.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NROverlay.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.common.nodes.surface.BaseOverlay;
 
 /**
  * Null-renderer implementation of an Overlay node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRText2D.java b/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRText2D.java
index 12edfaa381a5aa4d24ec82bc5d552884eedccead..1da173bcb29f32a83a905556b1958bb0fd03a348 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRText2D.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRText2D.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.common.nodes.surface.BaseText2D;
 
 /**
  * Common implementation of a Text2D node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRXYLayout.java b/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRXYLayout.java
index 0019ec998bc958d7f8ea99f106f35b90293c9f3f..fb8896d4bd6b188cebfb48bd5e04dc8c0afcbd09 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRXYLayout.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/surface/NRXYLayout.java
@@ -22,6 +22,8 @@ import org.web3d.vrml.renderer.common.nodes.surface.BaseXYLayout;
 
 /**
  * Null-renderer implementation of a XYLayout node.
+ * <p>
+ *
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/text/NRFontStyle.java b/src/java/org/web3d/vrml/renderer/norender/nodes/text/NRFontStyle.java
index 03d162566a2cc2017493c966a8118ab6c4bf5058..0b8e23c808b7f98225f1230d6fa349aad483a47a 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/text/NRFontStyle.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/text/NRFontStyle.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Norender implementation of a FontStyle
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/text/NRText.java b/src/java/org/web3d/vrml/renderer/norender/nodes/text/NRText.java
index 60d2d32b8f1008853226273f646c583e399a30f2..bb9d9555c2fc6e6bd483a9ca45b939f0dbfd135c 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/text/NRText.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/text/NRText.java
@@ -27,6 +27,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * NoRender implementation of a Text
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRComposedCubeMapTexture.java b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRComposedCubeMapTexture.java
index cf2fb0d9338fd773b62e118aa10aacbb624de6de..1f85ce39532fa8c2206fa4da0ad364073adc440d 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRComposedCubeMapTexture.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRComposedCubeMapTexture.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.common.nodes.texture.BaseComposedCubeMapTexture;
 
 /**
  * Null-renderer implementation of a ComposedCubeMapTexture node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRComposedTexture3D.java b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRComposedTexture3D.java
index c158bf5b6a8a1e3633b61a735e0efee9e7210135..881bab058764a915e45bb48d6e0cc9881e81d274 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRComposedTexture3D.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRComposedTexture3D.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.common.nodes.texture.BaseComposedTexture3D;
 
 /**
  * Null-renderer implementation of a Composed3DTexture node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRImageCubeMapTexture.java b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRImageCubeMapTexture.java
index ea328ccc49283cc7cfa9b9aae0080d18b6752b03..36cf0997defa0152b819f36c9eef6c5c41920a53 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRImageCubeMapTexture.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRImageCubeMapTexture.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.common.nodes.texture.BaseImageCubeMapTexture;
 
 /**
  * Null-renderer implementation of a ImageCubeMapTexture node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRImageTexture.java b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRImageTexture.java
index 9f07922a1b35d486f4cd0488b93b28d750ecf456..acbaac63eae485d0fd0e9816b43c9e0ccae2939f 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRImageTexture.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRImageTexture.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a ImageTexture node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 2.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRImageTexture3D.java b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRImageTexture3D.java
index 91e90e35f02fe6b3fcf3e004dd6b11f813735631..22f2f89f7459d45a86e21224390115d3b6d3110b 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRImageTexture3D.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRImageTexture3D.java
@@ -23,7 +23,8 @@ import org.web3d.vrml.renderer.common.nodes.texture.BaseImageTexture3D;
 
 /**
  * Null-renderer implementation of a ImageTexture3D node.
- * 
+ * <p>
+ *
  * @author Justin Couch
  * @version $Revision: 1.1 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRMovieTexture.java b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRMovieTexture.java
index 55d9f0cd2d3e1ba838cede24791f54131d0d14c5..d157f8e645316bf68d0c3c7f6ede06451df217ab 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRMovieTexture.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRMovieTexture.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.common.nodes.texture.BaseMovieTexture;
 
 /**
  * Null-renderer implementation of a MovieTexture node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRMultiTexture.java b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRMultiTexture.java
index bfbaacfd1dad2a15b643fc697f3d6a7b03f6bd8d..7ec07aa15c2880d627d49febb0cda2a0c69a8df1 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRMultiTexture.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRMultiTexture.java
@@ -25,6 +25,7 @@ import org.web3d.vrml.renderer.common.nodes.texture.BaseMultiTexture;
 
 /**
  * Null-renderer implementation of a MultiTexture node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRMultiTextureCoordinate.java b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRMultiTextureCoordinate.java
index ba3c850983461691825216eae7ad601bc3503afd..f9f8c3087b157d26288ae4d9518747c1e53c33ec 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRMultiTextureCoordinate.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRMultiTextureCoordinate.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a texture coordinate node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRMultiTextureTransform.java b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRMultiTextureTransform.java
index 477489d3a81fa2ececcefdb81f9303c213126b5e..b2c8dcf7372c4a04d5f5a9521c11cb7337f87bed 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRMultiTextureTransform.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRMultiTextureTransform.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.common.nodes.texture.BaseMultiTextureTransform;
 
 /**
  * Null renderer implementation of a texture transform for multi-texture use.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRPixelCubeMapTexture.java b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRPixelCubeMapTexture.java
index 49f3a19f9b7635a44209821d6cc47c61e1adb48a..7a9532c20adffc1c10923718b97e0e212d9f7fdb 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRPixelCubeMapTexture.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRPixelCubeMapTexture.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.common.nodes.texture.BasePixelCubeMapTexture;
 
 /**
  * Null-renderer implementation of a PixelCubeMapTexture node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRPixelTexture.java b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRPixelTexture.java
index 1328c4921a73f7aa6ef293a66ad8fcd4b5f919fe..59c92bcb720b3450119815a9b35fe5b8e09326b5 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRPixelTexture.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRPixelTexture.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.common.nodes.texture.BasePixelTexture;
 
 /**
  * no-render implementation of a PixelTexture node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 2.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRPixelTexture3D.java b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRPixelTexture3D.java
index 2cbcfa8122ccbe850f9cf4d6ef26e2a9303789ee..3fb85ef12c2b1f499fc0ed75ef1a4a9afc597cb1 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRPixelTexture3D.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRPixelTexture3D.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.common.nodes.texture.BasePixelTexture3D;
 
 /**
  * no-render implementation of a PixelTexture node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRRenderedTexture.java b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRRenderedTexture.java
index f3082962674c5a10ee8b52fab59cca8463ed1f8c..37c5686c9bbe3efd99921709501aca40162973dc 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRRenderedTexture.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRRenderedTexture.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.common.nodes.texture.BaseRenderedTexture;
 
 /**
  * no-render implementation of a RenderedTexture node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureCoordinate.java b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureCoordinate.java
index 45d27a085ccfaf98bfa1abdaf40f58dec52d0e6e..1f9b8fe098f3a8042fa23e7bcc5c9a022eb56665 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureCoordinate.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureCoordinate.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 
 /**
  * Null renderer implementation of a texture coordinate node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureCoordinate3D.java b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureCoordinate3D.java
index 675e8ca235c4b2d241a500ee97b66838e31a7024..8c7e5572abb3d8eefc1d190b1f9b10aea6842dd9 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureCoordinate3D.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureCoordinate3D.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 /**
  * Null renderer implementation of a texture coordinate node for 3D
  * coordinates.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureCoordinate4D.java b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureCoordinate4D.java
index 374c26bb4b2921507975a87901f8248e655c8188..6489c485564d1edd1443b0e2ea693b81be2f8b3d 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureCoordinate4D.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureCoordinate4D.java
@@ -23,7 +23,8 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 /**
  * Null renderer implementation of a texture coordinate node for 4D
  * coordinates.
- * 
+ * <p>
+ *
  * @author Justin Couch
  * @version $Revision: 1.1 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureCoordinateGenerator.java b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureCoordinateGenerator.java
index b31da7da8db1a92a50b88eea8481493585d4b856..4f0758454753c06398068ec0fa08b3dcf66d381c 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureCoordinateGenerator.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureCoordinateGenerator.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.norender.nodes.NRVRMLNode;
 /**
  * Null renderer implementation of a texture coordinate generator node used in
  * multitexture.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureProperties.java b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureProperties.java
index 32b2d10b5fe2f7cd149ee7f8f407871643b528a7..85e691faa3535740478d690af9746d725f0a3f81 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureProperties.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureProperties.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.common.nodes.texture.BaseTextureProperties;
 
 /**
  * Null renderer implementation of a texture properties.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureTransform.java b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureTransform.java
index 93e0fed9aefdacd2613dd7b71c87e610c45b072f..6e707fafaf757db1053dd623785dd71712628435 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureTransform.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureTransform.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.common.nodes.texture.BaseTextureTransform;
 
 /**
  * Null renderer implementation of a texture transform.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureTransform3D.java b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureTransform3D.java
index 76079e8a8c2325c509a8186b6ae683aeb293ad79..948bd7b4348aed22e980791ec570e0d828472ea5 100644
--- a/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureTransform3D.java
+++ b/src/java/org/web3d/vrml/renderer/norender/nodes/texture/NRTextureTransform3D.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.common.nodes.texture.BaseTextureTransform3D;
 
 /**
  * Null renderer implementation of a texture transform.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/OGLExternProtoBuilder.java b/src/java/org/web3d/vrml/renderer/ogl/OGLExternProtoBuilder.java
index e226bb5db69f0d105cae97b41233277891464514..8a324d638591b6cabd74111376ba7d3d34ad6d0a 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/OGLExternProtoBuilder.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/OGLExternProtoBuilder.java
@@ -24,9 +24,11 @@ import org.web3d.vrml.renderer.CRExternProtoBuilder;
 
 /**
  * A SAV interface for dealing with building a single extern proto.
+ * <p>
  *
  * The builder is designed to create a single proto. However, that single proto
  * may well have nested protos as part of it, so we must deal with that too.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.11 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/OGLSceneBuilderFactory.java b/src/java/org/web3d/vrml/renderer/ogl/OGLSceneBuilderFactory.java
index ce68af66d84814056a87590cea5dda67739d3857..ae67d8af573270ed5c458ffd482939b17fb9a313 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/OGLSceneBuilderFactory.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/OGLSceneBuilderFactory.java
@@ -22,6 +22,8 @@ import org.xj3d.core.loading.SceneBuilderFactory;
 /**
  * OpenGL factory used to create new instances of the scene builder
  * on demand.
+ * <p>
+ *
  *
  * @author Justin Couch
  * @version $Revision: 1.4 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/browser/OGLLayerManager.java b/src/java/org/web3d/vrml/renderer/ogl/browser/OGLLayerManager.java
index 28f9ac3c73299c1f67790162fc5795fc51587c9b..3a13579e5524a7a95da5253402dc3f5881f88f11 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/browser/OGLLayerManager.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/browser/OGLLayerManager.java
@@ -1,1681 +1,1681 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2005 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.renderer.ogl.browser;
-
-// External imports
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.vecmath.Matrix4f;
-import javax.vecmath.Vector3f;
-import javax.vecmath.AxisAngle4f;
-import javax.vecmath.Point3f;
-
-import org.j3d.aviatrix3d.*;
-import org.j3d.aviatrix3d.rendering.BoundingVolume;
-import org.j3d.util.MatrixUtils;
-
-// Local imports
-import org.web3d.browser.NavigationStateListener;
-import org.web3d.browser.ProfilingListener;
-import org.web3d.browser.SensorStatusListener;
-import org.web3d.browser.ScreenCaptureListener;
-import org.web3d.browser.ViewpointStatusListener;
-
-import org.j3d.util.DefaultErrorReporter;
-import org.j3d.util.ErrorReporter;
-import org.j3d.util.IntHashMap;
-
-import org.web3d.vrml.lang.TypeConstants;
-import org.web3d.vrml.lang.VRMLNodeFactory;
-
-import org.web3d.vrml.nodes.*;
-
-import org.web3d.vrml.renderer.DefaultNodeFactory;
-import org.web3d.vrml.renderer.ogl.input.DefaultLayerSensorManager;
-import org.web3d.vrml.renderer.ogl.input.OGLUserInputHandler;
-import org.web3d.vrml.renderer.ogl.nodes.OGLUserData;
-import org.web3d.vrml.renderer.ogl.nodes.OGLViewpointNodeType;
-import org.web3d.vrml.renderer.ogl.nodes.OGLTransformNodeType;
-import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
-
-import org.xj3d.core.eventmodel.BindableNodeListener;
-import org.xj3d.core.eventmodel.BindableNodeManager;
-import org.xj3d.core.eventmodel.LayerManager;
-import org.xj3d.core.eventmodel.SensorManager;
-
-/**
- * OpenGL implementation of a layer manager.
- * <p>
- *
- * The layer manager is responsible for keeping track of all the top level
- * renderable structure within a scene.
- * <p>
- *
- * The Aviatrix Scenegraph for each layer is structured as follows:
- * <pre>
- *               SimpleLayer
- *                   |
- *               SimpleScene
- *                   |
- *               worldGroup
- *                  /\
- *                 /  \
- *                /    \
- *               /      \
- *              /        \
- *   sgTransformGroup     commonSg
- *         |                 |
- *        X3D Scene        globalEffects
- * </pre>
- *
- * @author Justin Couch
- * @version $Revision: 1.38 $
- */
-class OGLLayerManager
-    implements LayerManager,
-               NodeUpdateListener,
-               BindableNodeListener,
-               NavigationInfoChangeListener,
-               LayerListener,
-               OGLTransformNodeType {
-
-    /** Message when the node factory doesn't have any configurations set */
-    private static final String NODE_PROFILE_ERR =
-        "LayerManager is unable to initialise the default bindables " +
-        "due to missing node factory configurations.";
-
-    /**
-     * Message for a viewpoint with a weird projection constant. Since this is
-     * Hard-coded into the viewpoint implementation node, we should never see
-     * this error, unless there is a user-implemented type of viewpoint. In
-     * which case, you are now reading the right error message and know that
-     * you need to go fix up the appropriate switch statements down the bottom
-     * of this class.
-     */
-    private static final String UNKNOWN_PROJ_TYPE_MSG =
-        "A viewpoint has been provided with an unknown projection type. The " +
-        "code can only deal with perspective and orthographic projections. " +
-        "We'll default to perspective now.";
-
-    /** Error message when the viewpointAdded() call generates an error */
-    private static final String VP_ADD_ERR =
-        "Error sending viewpoint addition notification.";
-
-    /** Error message when the viewpointRemoved() call generates an error */
-    private static final String VP_REMOVE_ERR =
-        "Error sending viewpoint removed notification.";
-
-    /** Error message when the viewpointBound() call generates an error */
-    private static final String VP_BOUND_ERR =
-        "Error sending viewpoint binding notification.";
-
-    /** Error message when the viewpointLayerActive() call generates an error */
-    private static final String VP_ACTIVATE_ERR =
-        "Error sending viewpoint layer activation notification.";
-
-    /** Error message when the viewpointLayerAdded() call generates an error */
-    private static final String VP_LAYER_ADD_ERR =
-        "Error sending viewpoint layer addtion notification.";
-
-    /** Error message when the viewpointLayerRemoved() call generates an error */
-    private static final String VP_LAYER_REMOVE_ERR =
-        "Error sending viewpoint layer removal notification.";
-
-    /** The time in milliseconds to move between two points */
-    private static final int VP_TRANSITION_TIME = 2_000;
-
-    /** The name of the navigation component */
-    private static final String NAV_COMPONENT = "Navigation";
-
-    /** The name of the environmental effects component */
-    private static final String ENV_COMPONENT = "EnvironmentalEffects";
-
-
-    /** Reporter instance for handing out errors */
-    private ErrorReporter errorReporter;
-
-    /** The View that we use for everything */
-    private ViewEnvironment viewEnvironment;
-
-    /** The current viewpoint node we are playing with */
-    private OGLViewpointNodeType currentViewpoint;
-
-    /** The current navigation info we are running with */
-    private VRMLNavigationInfoNodeType currentNavInfo;
-
-    /** Default viewpoint that exists in every scene */
-    private OGLViewpointNodeType defaultViewpoint;
-
-    /** Default navigationInfo that exists in every scene */
-    private VRMLNavigationInfoNodeType defaultNavInfo;
-
-    /** Default background that exists in every scene */
-    private VRMLBackgroundNodeType defaultBackground;
-
-    /** Default fog that exists in every scene */
-    private VRMLFogNodeType defaultFog;
-
-    /** The node stack for viewpoints */
-    private BindableNodeManager viewpointStack;
-
-    /** The node stack for navigation information */
-    private BindableNodeManager navInfoStack;
-
-    /** The node stack for navigation information */
-    private BindableNodeManager backgroundStack;
-
-    /** The node stack for navigation information */
-    private BindableNodeManager fogStack;
-
-    /** Map of node primary type to the bindable manager for that type */
-    private IntHashMap<BindableNodeManager> bindablesMap;
-
-    /** Clock for setting bindTime information */
-    private VRMLClock clock;
-
-    /** The global effects for this layer */
-    private GlobalEffectsGroup globalEffects;
-
-    /** Manager of the global sensor nodes */
-    private SensorManager sensorManager;
-
-    /** Manager of viewpoint resizes */
-    private ViewpointResizeManager viewpointResizeManager;
-
-    /** The per-layer sensor manager */
-    private DefaultLayerSensorManager layerSensorManager;
-
-    /** Is this layer currently active for navigation purposes? */
-    private boolean navigationEnabled;
-
-    /** Temporary holding the projection type for the update callback */
-    private int projectionType;
-
-    /** Input processing for this layer */
-    private OGLUserInputHandler userInput;
-
-    /** Listeners for the viewpoint status updates from this layer */
-    private List<ViewpointStatusListener> viewpointStatusListeners;
-
-    /** Rendering effects if you want something other than polygons */
-    private OGLRenderingEffects renderEffects;
-
-    // Aviatrix3D variables
-
-    /** The layer above the scene */
-    private SimpleLayer implLayer;
-
-    /** Render manager for handling the backgrounds and fogs */
-    private SimpleScene implScene;
-
-    /** The top level node the universe is using */
-    private Group worldGroup;
-
-    /** The Transform holding the main scene, child 0=vp, 1=loaded scene */
-    private TransformGroup sgTransformGroup;
-
-    /** A group to hold the last vp group for later update */
-    private TransformGroup vpTransformGroup;
-
-    /** The current world root */
-    private Group worldRoot;
-
-    /**
-     * Flag to say that a clear() call has been made and we need to
-     * delete the scene contents, but not kill everything.
-     */
-    private boolean clearAllContent;
-
-    /** Flag to indicate that the default bindables need to be update */
-    private boolean updateBindables;
-
-    /** The geometry from the layer or world root that is pending addition */
-    private Group pendingWorldGeom;
-
-    /** Subgraph that contains the updated default bindables */
-    private Group pendingBindables;
-
-    /** A matrix to hold the last vp matrix for later update */
-    private Matrix4f vpMatrix;
-
-    /** Matrix containing the world scale that is calculated for this layer */
-    private Matrix4f worldScaleMatrix;
-
-    /** A matrix used when calculating the scene graph path */
-    private Matrix4f pathMatrix;
-
-    /** The ID of this layer */
-    private int layerId;
-
-    /** The type of viewport that this layer has */
-    private int viewportType;
-
-    /** The viewport node from the layer. Null if the root layer */
-    private VRMLViewportNodeType viewport;
-
-    /** Temp var used to fetch the scene graph path */
-    private List<Node> pathList;
-
-    /** An array used to fetch the nodes from pathNodes */
-    private Node[] pathNodes;
-
-    /** An aviatrix viewport */
-    private SimpleViewport simpleViewport;
-
-    /**
-     * Create a new instance of the layer manager that looks after the
-     * given effects group.
-     *
-     * @param globals The handler for fog/background et al for this layer
-     */
-    OGLLayerManager() {
-        layerId = -1;
-        clearAllContent = false;
-        updateBindables = false;
-
-        pathList = new ArrayList<>();
-        pathNodes = new Node[20];  // some arbitrary value;
-
-        viewportType = VIEWPORT_FULLWINDOW;
-        projectionType = ViewEnvironment.PERSPECTIVE_PROJECTION;
-
-        implScene = new SimpleScene();
-        viewEnvironment = implScene.getViewEnvironment();
-
-        simpleViewport = new SimpleViewport();
-        simpleViewport.setScene(implScene);
-
-        implLayer = new SimpleLayer();
-        implLayer.setViewport(simpleViewport);
-
-        globalEffects = new GlobalEffectsGroup(implScene);
-        renderEffects = new OGLRenderingEffects(implScene);
-
-        implScene.setRenderEffectsProcessor(renderEffects);
-
-        layerSensorManager = new DefaultLayerSensorManager();
-        layerSensorManager.setViewEnvironment(viewEnvironment);
-        layerSensorManager.setGlobalEffectsHandler(globalEffects);
-
-        userInput = (OGLUserInputHandler)layerSensorManager.getUserInputHandler();
-
-        OGLUserData data = new OGLUserData();
-        data.owner = OGLLayerManager.this;
-
-        Group common_sg = new Group();
-        common_sg.addChild(globalEffects);
-
-        worldGroup = new Group();
-
-        // Group for holding the main scene. Prepopulate two empty children.
-        // The first child belongs to all the default bindable nodes and is
-        // filled in at initialization of this class. The second index is set
-        // to be the geometry of the loaded world.
-        sgTransformGroup = new TransformGroup();
-        sgTransformGroup.setUserData(data);
-        sgTransformGroup.addChild(null);
-        sgTransformGroup.addChild(null);
-
-        worldGroup.addChild(common_sg);
-        worldGroup.addChild(sgTransformGroup);
-
-        implScene.setRenderedGeometry(worldGroup);
-        globalEffects.initialize();
-
-        bindablesMap = new IntHashMap<>();
-        errorReporter = DefaultErrorReporter.getDefaultReporter();
-
-        worldScaleMatrix = new Matrix4f();
-        worldScaleMatrix.setIdentity();
-
-        pathMatrix = new Matrix4f();
-
-        viewpointStatusListeners = new ArrayList<>(1);
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by LayerManager
-    //----------------------------------------------------------
-
-    /**
-     * Register an error reporter with the engine so that any errors generated
-     * by the loading of script code can be reported in a nice, pretty fashion.
-     * Setting a value of null will clear the currently set reporter. If one
-     * is already set, the new value replaces the old.
-     *
-     * @param reporter The instance to use or null
-     */
-    @Override
-    public void setErrorReporter(ErrorReporter reporter) {
-        errorReporter = reporter;
-
-        // Reset the default only if we are not shutting down the system.
-        if(reporter == null)
-            errorReporter = DefaultErrorReporter.getDefaultReporter();
-
-        int[] keys = bindablesMap.keySet();
-
-        for(int i = 0; i < keys.length; i++) {
-            BindableNodeManager mgr = bindablesMap.get(keys[i]);
-            mgr.setErrorReporter(errorReporter);
-        }
-    }
-
-    /**
-     * Complete the initialization of the layer manager now. This should be
-     * called after setting the clock and the current error reporter instance.
-     *
-     * @param sensors The sensor manager to start with from the global list
-     */
-    @Override
-    public void initialise(SensorManager smgr) {
-        sensorManager = smgr;
-
-        clock = sensorManager.getVRMLClock();
-
-        BindableNodeManager vp_mgr = new BindableNodeManager();
-        vp_mgr.setVRMLClock(clock);
-        vp_mgr.setErrorReporter(errorReporter);
-        vp_mgr.setNodeChangeListener(this);
-        bindablesMap.put(TypeConstants.ViewpointNodeType, vp_mgr);
-        viewpointStack = vp_mgr;
-
-        BindableNodeManager ni_mgr = new BindableNodeManager();
-        ni_mgr.setVRMLClock(clock);
-        ni_mgr.setErrorReporter(errorReporter);
-        ni_mgr.setNodeChangeListener(this);
-        bindablesMap.put(TypeConstants.NavigationInfoNodeType, ni_mgr);
-        navInfoStack = ni_mgr;
-
-        BindableNodeManager bg_mgr = new BindableNodeManager();
-        bg_mgr.setVRMLClock(clock);
-        bg_mgr.setErrorReporter(errorReporter);
-        bindablesMap.put(TypeConstants.BackgroundNodeType, bg_mgr);
-        backgroundStack = bg_mgr;
-
-        BindableNodeManager fog_mgr = new BindableNodeManager();
-        fog_mgr.setVRMLClock(clock);
-        fog_mgr.setErrorReporter(errorReporter);
-        bindablesMap.put(TypeConstants.FogNodeType, fog_mgr);
-        fogStack = fog_mgr;
-
-        layerSensorManager.setNavigationStacks(vp_mgr,
-                                               ni_mgr,
-                                               bg_mgr,
-                                               fog_mgr);
-        layerSensorManager.setVRMLClock(clock);
-
-        sensorManager.addLayerSensorManager(layerSensorManager);
-
-        createDefaultBindables(3, 2);
-    }
-
-    /**
-     * Set or reset the layer ID to the new ID value.
-     *
-     * @param id A non-negative ID for the layer
-     */
-    @Override
-    public void setLayerId(int id) {
-        layerId = id;
-        layerSensorManager.setLayerId(id);
-        globalEffects.setLayerId(id);
-    }
-
-    /**
-     * Set the specification version that should be handled by this manager.
-     * This is needed so that the correct version of the default bindables are
-     * instantiated before the rest of the world loads. For example, the default
-     * nav type for VRML is different to X3D, so this makes sure all the right
-     * spec stuff is catered for.
-     *
-     * @param major The spec major version number
-     * @param minor The spec minor version number
-     */
-    @Override
-    public void setSpecVersion(int major, int minor) {
-        createDefaultBindables(major, minor);
-    }
-
-    /**
-     * Change the rendering style that the browser should currently be using
-     * for all layers. Various options are available based on the constants
-     * defined in this
-     *
-     * @param style One of the RENDER_* constants from LayerRenderingManager
-     * @throws IllegalArgumentException A style constant that is not recognized
-     *   by the implementation was provided
-     */
-    @Override
-    public void setRenderingStyle(int style)
-        throws IllegalArgumentException {
-
-        renderEffects.setRenderingStyle(style);
-    }
-
-    /**
-     * Get the currently set rendering style. The default style is
-     * RENDER_SHADED.
-     *
-     * @return one of the RENDER_ constants from LayerRenderingManager
-     */
-    @Override
-    public int getRenderingStyle() {
-        return renderEffects.getRenderingStyle();
-    }
-
-    /**
-     * Capture the screen on the next render.
-     *
-     * @param listener Listener for capture results
-     * @param width The screen width
-     * @param height The screen height
-     */
-    public void captureScreenOnce(ScreenCaptureListener listener,
-                                  int width,
-                                  int height) {
-        renderEffects.captureScreenOnce(listener, width, height);
-    }
-
-    /**
-     * Capture the screen on each render.
-     *
-     * @param listener Listener for capture results
-     * @param width The screen width
-     * @param height The screen height
-     */
-    public void captureScreenStart(ScreenCaptureListener listener,
-                                   int width,
-                                   int height) {
-        renderEffects.captureScreenStart(listener, width, height);
-    }
-
-    /**
-     * Stop capturing the screen on each render.
-     */
-    public void captureScreenEnd() {
-        renderEffects.captureScreenEnd();
-    }
-
-    /**
-     * Perform the initial bind for a new scene. This is typically called some
-     * time just after the clear() method with a new scene. This will
-     * automatically reset the current navigation state for this layer to be
-     * inactive, even if it was previously active.
-     */
-    @Override
-    public void initialBind() {
-
-        // create default nodes to suit.
-        double time = clock.getTime();
-
-        // Put the defaults back into the stacks after it has been
-        // cleared
-        viewpointStack.addNode(defaultViewpoint, true);
-        navInfoStack.addNode(defaultNavInfo, true);
-        backgroundStack.addNode(defaultBackground, true);
-        fogStack.addNode((VRMLBindableNodeType)defaultFog, true);
-
-        viewpointStack.addDefaultBindable(defaultViewpoint);
-        navInfoStack.addDefaultBindable(defaultNavInfo);
-        backgroundStack.addDefaultBindable(defaultBackground );
-        fogStack.addDefaultBindable((VRMLBindableNodeType)defaultFog);
-
-// LAYERS:
-// This should also go looking for the default for this viewpoint based on
-// the #ref part of a URL and see if it is part of this layer.
-        VRMLViewpointNodeType vp =
-            (VRMLViewpointNodeType)viewpointStack.getFirstNode();
-
-        VRMLNavigationInfoNodeType nav =
-            (VRMLNavigationInfoNodeType)navInfoStack.getFirstNode();
-
-        VRMLBackgroundNodeType bg =
-            (VRMLBackgroundNodeType)backgroundStack.getFirstNode();
-
-        VRMLFogNodeType fog = (VRMLFogNodeType)fogStack.getFirstNode();
-
-        vp.setBind(true, true, time);
-        nav.setBind(true, true, time);
-        bg.setBind(true, true, time);
-        ((VRMLBindableNodeType)fog).setBind(true, true, time);
-
-        currentNavInfo = nav;
-        currentNavInfo.addNavigationChangedListener(this);
-        globalEffects.useHeadlight(currentNavInfo.getHeadlight());
-
-        SceneGraphPath path = generatePath(vpTransformGroup);
-
-        userInput.setViewInfo(currentViewpoint,
-                              vpTransformGroup,
-                              path);
-
-        if(sgTransformGroup.isLive())
-            sgTransformGroup.boundsChanged(this);
-        else
-            updateNodeBoundsChanges(sgTransformGroup);
-    }
-
-    /**
-     * Get the bindable node manager for the given node type. If the node type
-     * does not have a bindable manager for it, one will be created.
-     *
-     * @param type The type constant of the node type for the manager
-     * @return The bindable manager for it
-     * @see org.web3d.vrml.lang.TypeConstants
-     */
-    @Override
-    public BindableNodeManager getBindableManager(int type) {
-        BindableNodeManager ret_val = bindablesMap.get(type);
-
-        if(ret_val == null) {
-            ret_val = new BindableNodeManager();
-            ret_val.setErrorReporter(errorReporter);
-            ret_val.setVRMLClock(sensorManager.getVRMLClock());
-            bindablesMap.put(type, ret_val);
-        }
-
-        return ret_val;
-    }
-
-    /**
-     * Enable or disable this layer to be currently navigable layer. The
-     * navigable layer takes the input from the input devices and interacts
-     * with the currently bound viewpoint etc.
-     *
-     * @param state True to enable this layer as navigable
-     */
-    @Override
-    public void setActiveNavigationLayer(boolean state) {
-        navigationEnabled = state;
-        layerSensorManager.setNavigationEnabled(state);
-        userInput.sendCurrentNavState();
-
-        if(state) {
-            int size = viewpointStatusListeners.size();
-
-            for(int i = 0; i < size; i++) {
-                try {
-                    ViewpointStatusListener l = viewpointStatusListeners.get(i);
-
-                    l.viewpointLayerActive(layerId);
-                } catch(Exception e) {
-                    errorReporter.warningReport(VP_ACTIVATE_ERR, e);
-                }
-            }
-
-            if(simpleViewport.isLive())
-                simpleViewport.dataChanged(this);
-            else
-                updateNodeDataChanges(simpleViewport);
-
-        }
-    }
-
-    /**
-     * Check to see if this is the active navigation layer.
-     *
-     * @return true if this is the currently active layer for navigation
-     */
-    @Override
-    public boolean isActiveNavigationLayer() {
-        return navigationEnabled;
-    }
-
-    /**
-     * Set the desired navigation mode. The mode string is one of the
-     * spec-defined strings for the NavigationInfo node in the VRML/X3D
-     * specification.
-     *
-     * @param mode The requested mode.
-     * @return Whether the mode is valid.
-     */
-    @Override
-    public boolean setNavigationMode(String mode) {
-        return userInput.setNavigationMode(mode);
-    }
-
-    /**
-     * Get the user's location and orientation.  This will use the viewpoint
-     * bound in the active layer.
-     *
-     * @param pos The current user position
-     * @param ori The current user orientation
-     */
-    @Override
-    public void getUserPosition(Vector3f pos, AxisAngle4f ori) {
-        userInput.getPosition(pos);
-        userInput.getOrientation(ori);
-    }
-
-    /**
-     * Move the user's location to see the entire world in this layer. Change
-     * the users orientation to look at the center of the world.
-     *
-     * @param animated Should the transition be animated.  Defaults to FALSE.
-     */
-    @Override
-    public void fitToWorld(boolean animated) {
-
-        vpMatrix.setIdentity();
-
-        BoundingVolume bounds = worldRoot.getBounds();
-
-        if (bounds instanceof BoundingVoid) {return;}
-
-        float[] boundsMin = new float[3];
-        float[] boundsMax = new float[3];
-
-        bounds.getExtents(boundsMin, boundsMax);
-
-        float[] size = new float[3];
-        ((BoundingBox)bounds).getSize(size);
-
-/*
-        float zrange = Math.abs(boundsMax[2] - boundsMin[2]);
-
-        float mult = 1;
-
-        if (zrange > 1000)
-            mult = 1.25f;
-        else
-            mult = 2;
-
-        float zloc = center[2] + zrange * mult;
-*/
-        float x_center = ( boundsMin[0] + boundsMax[0] ) / 2;
-        float y_center = ( boundsMin[1] + boundsMax[1] ) / 2;
-        float z_center = ( boundsMin[2] + boundsMax[2] ) / 2;
-
-        float[] center = new float[]{ x_center, y_center, z_center };
-
-        // the extents, by half
-        float x = size[0];
-        float y = size[1];
-        float z = size[2];
-
-        // radius of the bounding sphere
-        float radius = (float)Math.sqrt((x * x) + (y * y) + (z * z));
-
-        // given a field-of-view of 45 degrees - the distance from
-        // the center of the bounding sphere at which the sphere
-        // surface should be within the f-o-v (0.392699 radians == 22.5 degrees)
-        // note, the sin gives the distance to the sphere's visible edge,
-        // a tan would give the distance to the center. the edge distance
-        // is greater and moves the position a bit farther away - providing
-        // some margin between the actual f-o-v and the bounding sphere
-        float distance = radius / (float)(Math.sin(0.392699));
-
-        // equidistant components of the distance to combine with
-        // the object center.
-        float offset = ( distance / (float)Math.sqrt(3.0) );
-
-        // if the distance away is less than the clipping plane
-        // then move the viewpoint a little
-        if (offset < 0.125f) {
-            offset = 0.126f;
-
-            // would prefer to change clip plane, not sure how yet
-        }
-
-        float[] position = new float[]{
-                x_center + offset, y_center + offset, z_center + offset};
-
-
-        vpMatrix.setTranslation(new Vector3f(position[0], position[1], position[2]));
-
-        Point3f from = new Point3f(position);
-        Point3f to = new Point3f(center);
-        Vector3f Yup = new Vector3f(0, 1, 0);
-
-        MatrixUtils mu = new MatrixUtils();
-        Matrix4f rot = new Matrix4f();
-        mu.lookAt(from, to, Yup, rot);
-        mu.inverse(rot, rot);
-
-        AxisAngle4f a = new AxisAngle4f();
-        a.set(rot);
-
-        vpMatrix.setRotation(a);
-
-        if (vpTransformGroup.isLive())
-            vpTransformGroup.boundsChanged(this);
-        else
-            updateNodeBoundsChanges(vpTransformGroup);
-    }
-
-    /**
-     * Set the contents that this layer manages to be the ungrouped nodes
-     * of the scene. The code should take all the children nodes from this node
-     * that are not part of a layer and render them as this layer.
-     *
-     * @param root The root of the world to handle
-     */
-    @Override
-    public void setManagedNodes(VRMLWorldRootNodeType root) {
-        // The base layer always occupies the full window space.
-        viewportType = VIEWPORT_FULLWINDOW;
-        viewport = null;
-
-        int size = viewpointStatusListeners.size();
-
-        for(int i = 0; i < size; i++) {
-            try {
-                ViewpointStatusListener l = viewpointStatusListeners.get(i);
-
-                l.viewpointLayerAdded(layerId);
-            } catch(Exception e) {
-                errorReporter.warningReport(VP_LAYER_ADD_ERR, e);
-            }
-        }
-
-        OGLVRMLNode ogl_root = (OGLVRMLNode)root;
-
-        pendingWorldGeom = (Group)ogl_root.getSceneGraphObject();
-        layerSensorManager.setWorldRoot(pendingWorldGeom);
-    }
-
-    /**
-     * Set the contents that this layer manages the specific layer instance
-     * provided.
-     *
-     * @param layer The root of the layer to handle
-     */
-    @Override
-    public void setManagedLayer(VRMLLayerNodeType layer) {
-        viewportType = layer.getViewportType();
-
-        VRMLNodeType vp = layer.getViewport();
-        VRMLNodeType node;
-
-        if(vp instanceof VRMLProtoInstance) {
-            node = ((VRMLProtoInstance)vp).getImplementationNode();
-
-            while((node != null) && (node instanceof VRMLProtoInstance))
-                node = ((VRMLProtoInstance)node).getImplementationNode();
-
-            if((node != null) && !(node instanceof VRMLViewportNodeType)) {
-                // if it is invalid, replace the window with a fullscreen one.
-                // Ideally we would never hit this as the field should never
-                // have been allowed to be set in the first place.
-                viewportType = VIEWPORT_FULLWINDOW;
-                viewport = null;
-                node = null;
-            }
-        } else if(vp != null &&
-                  (!(vp instanceof VRMLViewportNodeType))) {
-
-            // if it is invalid, replace the window with a fullscreen one.
-            // Ideally we would never hit this as the field should never have
-            // been allowed to be set in the first place.
-            viewportType = VIEWPORT_FULLWINDOW;
-            viewport = null;
-            node = null;
-        } else {
-            node = vp;
-        }
-
-        viewport = (VRMLViewportNodeType)node;
-
-        int size = viewpointStatusListeners.size();
-
-        for(int i = 0; i < size; i++) {
-            try {
-                ViewpointStatusListener l = viewpointStatusListeners.get(i);
-
-                l.viewpointLayerAdded(layerId);
-            } catch(Exception e) {
-                errorReporter.warningReport(VP_LAYER_ADD_ERR, e);
-            }
-        }
-
-        OGLVRMLNode ogl_root = (OGLVRMLNode)layer;
-
-        pendingWorldGeom = (Group)ogl_root.getSceneGraphObject();
-        layerSensorManager.setWorldRoot(pendingWorldGeom);
-        layerSensorManager.setIsPickable(layer.isPickable());
-
-        layer.addLayerListener(this);
-    }
-
-    /**
-     * Override the file field of view values with a value that suits
-     * the given output device. A value of 0 = no, otherwise use this
-     * instead of content
-     *
-     * @param fov The fov in degrees.
-     */
-    @Override
-    public void setHardwareFOV(float fov) {
-        viewpointResizeManager.setHardwareFOV(fov);
-    }
-
-    /**
-     * Set whether stereo is enabled for all layers.
-     */
-    @Override
-    public void setStereoEnabled(boolean enabled) {
-        viewEnvironment.setStereoEnabled(enabled);
-    }
-
-    /**
-     * Shutdown the node manager now. If this is using any external resources
-     * it should remove those now as the entire application is about to die
-     */
-    @Override
-    public void shutdown() {
-
-        simpleViewport = null;
-        sensorManager.removeLayerSensorManager(layerSensorManager);
-
-        if (worldGroup.isLive()) {
-            worldGroup.boundsChanged(this);
-        } else {
-            updateNodeBoundsChanges(worldGroup);
-        }
-        globalEffects.shutdown();
-    }
-
-    /**
-     * Update the viewing matrix.  Call this when you want the SensorManager to update
-     * the viewing matrix.  Typically after all user input and events have resolved.
-     */
-    @Override
-    public void updateViewMatrix() {
-        layerSensorManager.updateViewMatrix();
-    }
-
-    /**
-     * Force clearing all currently managed nodes from this manager now. This
-     * is used to indicate that a new world is about to be loaded and
-     * everything should be cleaned out now.
-     */
-    @Override
-    public void clear() {
-        viewport = null;
-        int size = viewpointStatusListeners.size();
-
-        // if we were the currently active nav layer, then reset the
-        // active layer to layer 0, as that's the only one we can
-        // guarantee always exists.
-        //
-        // Note, could be dodgy if we are layer 0. Need to check on this.
-        if(navigationEnabled) {
-            for(int i = 0; i < size; i++) {
-                try {
-                    ViewpointStatusListener l = viewpointStatusListeners.get(i);
-
-                    if(layerId == 0)
-                        l.viewpointLayerActive(-1);
-                    else
-                        l.viewpointLayerActive(0);
-
-                } catch(Exception e) {
-                    errorReporter.warningReport(VP_ACTIVATE_ERR, e);
-                }
-            }
-        }
-
-        for(int i = 0; i < size; i++) {
-            try {
-                ViewpointStatusListener l = viewpointStatusListeners.get(i);
-
-                l.viewpointLayerRemoved(layerId);
-            } catch(Exception e) {
-                errorReporter.warningReport(VP_LAYER_REMOVE_ERR, e);
-            }
-        }
-
-        if(currentNavInfo != null)
-            currentNavInfo.removeNavigationChangedListener(this);
-
-        layerSensorManager.clear();
-        layerSensorManager.setNavigationEnabled(false);
-
-        vpTransformGroup = null;
-        pendingWorldGeom = null;
-        worldRoot = null;
-        currentViewpoint = null;
-        currentNavInfo = null;
-        clearAllContent = true;
-
-        userInput.clear();
-
-        pathList.clear();
-        for (int i = 0; i < pathNodes.length; i++){
-            pathNodes[i] = null;
-        }
-        if (viewpointResizeManager != null ) {
-            viewpointResizeManager.clear();
-        }
-
-        if(sgTransformGroup.isLive())
-            sgTransformGroup.boundsChanged(this);
-        else
-            updateNodeBoundsChanges(sgTransformGroup);
-    }
-
-    /**
-     * Check to see if this is an unmanaged size layer. A layer that has no
-     * specific viewport set, or a percentage size.
-     *
-     * @return One of the VIEWPORT_* constants
-     */
-    @Override
-    public int getViewportType() {
-        return viewportType;
-    }
-
-    /**
-     * Get the Viewport node that this layer uses. If the layer does not have
-     * a viewport set, then it returns null. The value is the real
-     * X3DViewportNode instance stripped from any surrounding proto shells etc.
-     *
-     * @return The current viewport node instance used by the layer
-     */
-    @Override
-    public VRMLViewportNodeType getViewport() {
-        return viewport;
-    }
-
-    /**
-     * Add a listener for navigation state changes.  A listener can only be added once.
-     * Duplicate requests are ignored.
-     *
-     * @param l The listener to add
-     */
-    @Override
-    public void addNavigationStateListener(NavigationStateListener l) {
-        userInput.addNavigationStateListener(l);
-    }
-
-    /**
-     * Remove a navigation state listener. If the reference is null or not known,
-     * the request is silently ignored.
-     *
-     * @param l The listener to remove
-     */
-    @Override
-    public void removeNavigationStateListener(NavigationStateListener l) {
-        userInput.removeNavigationStateListener(l);
-    }
-
-    /**
-     * Request notification of profiling information.
-     *
-     * @param l The listener
-     */
-    public void addProfilingListener(ProfilingListener l) {
-        if(l == null)
-            return;
-
-        renderEffects.addProfilingListener(l);
-    }
-
-    /**
-     * Remove notification of profiling information.
-     *
-     * @param l The listener
-     */
-    public void removeProfilingListener(ProfilingListener l) {
-        if(l == null)
-            return;
-
-        renderEffects.removeProfilingListener(l);
-    }
-
-    /**
-     * Add a listener for sensor state changes.  A listener can only be added once.
-     * Duplicate requests are ignored.
-     *
-     * @param l The listener to add
-     */
-    @Override
-    public void addSensorStatusListener(SensorStatusListener l) {
-        userInput.addSensorStatusListener(l);
-    }
-
-    /**
-     * Remove a sensor state listener. If the reference is null or not known,
-     * the request is silently ignored.
-     *
-     * @param l The listener to remove
-     */
-    @Override
-    public void removeSensorStatusListener(SensorStatusListener l) {
-        userInput.removeSensorStatusListener(l);
-    }
-
-    /**
-     * Add a listener for viewpoint status changes.  A listener can only be added once.
-     * Duplicate requests are ignored.
-     *
-     * @param l The listener to add
-     */
-    @Override
-    public void addViewpointStatusListener(ViewpointStatusListener l) {
-        if((l != null) && !viewpointStatusListeners.contains(l)) {
-            viewpointStatusListeners.add(l);
-
-            // Inform the listener of our status
-            l.viewpointLayerAdded(layerId);
-
-            if(navigationEnabled)
-                l.viewpointLayerActive(layerId);
-
-            // Go through the list of our currently available viewpoints
-        }
-    }
-
-    /**
-     * Remove a viewpoint state listener. If the reference is null or not known,
-     * the request is silently ignored.
-     *
-     * @param l The listener to remove
-     */
-    @Override
-    public void removeViewpointStatusListener(ViewpointStatusListener l) {
-        if(l == null)
-            return;
-
-        viewpointStatusListeners.remove(l);
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by VRMLBindableNodeListener
-    //----------------------------------------------------------
-
-    /**
-     * Notification that a binding stack has requested that this node be now
-     * bound as the active node.
-     *
-     * @param node The source node that is to be bound
-     */
-    @Override
-    public void newNodeBound(VRMLBindableNodeType node) {
-        if(node instanceof OGLViewpointNodeType) {
-            OGLViewpointNodeType vp = (OGLViewpointNodeType)node;
-
-            changeViewpoints(vp);
-
-            int size = viewpointStatusListeners.size();
-
-            for(int i = 0; i < size; i++) {
-                try {
-                    ViewpointStatusListener l = viewpointStatusListeners.get(i);
-
-                    l.viewpointBound(vp, layerId);
-                } catch(Exception e) {
-                    errorReporter.warningReport(VP_BOUND_ERR, e);
-                }
-            }
-        } else {
-            VRMLNavigationInfoNodeType nav =
-                (VRMLNavigationInfoNodeType)node;
-
-            if(currentNavInfo != null)
-                currentNavInfo.removeNavigationChangedListener(this);
-
-            currentNavInfo = nav;
-            currentNavInfo.addNavigationChangedListener(this);
-            globalEffects.useHeadlight(currentNavInfo.getHeadlight());
-        }
-    }
-
-    /**
-     * Notification that a new bindable has been added.
-     *
-     * @param node The new node
-     * @param isDefault True if this is a default node instance
-     */
-    @Override
-    public void bindableAdded(VRMLBindableNodeType node, boolean isDefault) {
-        if(!(node instanceof OGLViewpointNodeType))
-            return;
-
-        int size = viewpointStatusListeners.size();
-
-        for(int i = 0; i < size; i++) {
-            try {
-                ViewpointStatusListener l = viewpointStatusListeners.get(i);
-
-                l.viewpointAdded((VRMLViewpointNodeType)node,
-                                 layerId,
-                                 isDefault);
-            } catch(Exception e) {
-                errorReporter.warningReport(VP_ADD_ERR, e);
-            }
-        }
-    }
-
-    /**
-     * Notification that a bindable has been removed.
-     *
-     * @param node The node
-     */
-    @Override
-    public void bindableRemoved(VRMLBindableNodeType node) {
-        if(!(node instanceof OGLViewpointNodeType))
-            return;
-
-        int size = viewpointStatusListeners.size();
-
-        for(int i = 0; i < size; i++) {
-            try {
-                ViewpointStatusListener l = viewpointStatusListeners.get(i);
-
-                l.viewpointRemoved((VRMLViewpointNodeType)node, layerId);
-            } catch(Exception e) {
-                errorReporter.warningReport(VP_REMOVE_ERR, e);
-            }
-        }
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by NavigationInfoChangeListener
-    //----------------------------------------------------------
-
-    /**
-     * Notification that the navigation modes allowed has changed
-     * on the current NavigationInfo node.
-     *
-     * @param newModes The new allowed navigation modes
-     * @param numModes number of valid modes in array
-     */
-    @Override
-    public void notifyNavigationModesChanged(String[] newModes, int numModes) {
-        // Ignored by this class.
-    }
-
-    /**
-     * Notification that the avatar size has changed
-     * on the current NavigationInfo node.
-     *
-     * @param size The size parameters for the avatar
-     * @param dimensions The number of valid avatar dimensions
-     */
-    @Override
-    public void notifyAvatarSizeChanged(float[] size, int dimensions) {
-        // Ignored by this class.
-    }
-
-    /**
-     * Notification that the navigation speed has changed on the
-     * current NavigationInfo node.
-     *
-     * @param newSpeed The new navigation speed.
-     */
-    @Override
-    public void notifyNavigationSpeedChanged(float newSpeed) {
-        // Ignored by this class.
-    }
-
-    /**
-     * Notification that the visibility limit has been changed.
-     *
-     * @param distance The new distance value to use
-     */
-    @Override
-    public void notifyVisibilityLimitChanged(float distance) {
-        // Ignored by this class.
-    }
-
-    /**
-     * Notification that headlight state has changed.
-     *
-     * @param enable true if the headlight should now be on
-     */
-    @Override
-    public void notifyHeadlightChanged(boolean enable) {
-        globalEffects.useHeadlight(enable);
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by OGLTransformNodeType
-    //----------------------------------------------------------
-
-    /**
-     * Get the transform matrix for this node.  A reference is ok as
-     * the users of this method will not modify the matrix.
-     *
-     * @return The matrix.
-     */
-    @Override
-    public Matrix4f getTransform() {
-        return worldScaleMatrix;
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by NodeUpdateListener
-    //----------------------------------------------------------
-
-    /**
-     * Notification that its safe to update the node now with any operations
-     * that could potentially effect the node's bounds.
-     *
-     * @param src The node or Node Component that is to be updated.
-     */
-    @Override
-    public void updateNodeBoundsChanges(Object src) {
-
-        if(src == sgTransformGroup) {
-            sgTransformGroup.setTransform(worldScaleMatrix);
-
-            if(pendingWorldGeom != null) {
-                sgTransformGroup.setChild(pendingWorldGeom, 1);
-                worldRoot = pendingWorldGeom;
-                pendingWorldGeom = null;
-                clearAllContent = false;
-            } else if(clearAllContent) {
-                sgTransformGroup.setChild(null, 0);
-                sgTransformGroup.setChild(null, 1);
-                clearAllContent = false;
-            }
-
-            if(updateBindables) {
-                sgTransformGroup.setChild(pendingBindables, 0);
-                pendingBindables = null;
-                updateBindables = false;
-            }
-
-            userInput.setPickableScene(sgTransformGroup);
-            layerSensorManager.setWorldRoot(sgTransformGroup);
-
-// TODO: I expect this had some interaction with animated viewpoints but its causing timing issues
-/*
-            SceneGraphPath path = generatePath(vpTransformGroup);
-
-            userInput.setViewInfo(currentViewpoint,
-                                  vpTransformGroup,
-                                  path);
-*/
-        } else if (worldGroup == src) {
-			// rem:
-			// this would be a shutdown, clear out all geometry
-			// so the resources are eligible for deletion in the
-			// scene graph
-			worldGroup.removeAllChildren();
-
-		} else if(vpTransformGroup == src) {
-            vpTransformGroup.setTransform(vpMatrix);
-
-// TODO: I expect this had some interaction with animated viewpoints but its causing timing issues
-/*
-            SceneGraphPath path = generatePath(vpTransformGroup);
-
-            userInput.setViewInfo(currentViewpoint,
-                                  vpTransformGroup,
-                                  path);
-*/
-        } else {
-            ((Group)src).removeAllChildren();
-        }
-    }
-
-    /**
-     * Notification that its safe to update the node now with any operations
-     * that only change the node's properties, but do not change the bounds.
-     *
-     * @param src The node or Node Component that is to be updated.
-     */
-    @Override
-    public void updateNodeDataChanges(Object src) {
-        if (src == simpleViewport) {
-           simpleViewport.makeActiveSoundLayer();
-        }
-    }
-
-    //----------------------------------------------------------
-    // LayerListener methods
-    //----------------------------------------------------------
-
-    /**
-     * The pickable status of the layer has changed.
-     *
-     * @param pickable Is this layer pickable
-     */
-    @Override
-    public void pickableStateChanged(boolean pickable) {
-        layerSensorManager.setIsPickable(pickable);
-    }
-
-    //----------------------------------------------------------
-    // Local Methods
-    //----------------------------------------------------------
-
-    void setViewpointResizeManager(ViewpointResizeManager vrm) {
-        viewpointResizeManager = vrm;
-    }
-
-    /**
-     * Get the viewport layer that this layer manager works with.
-     *
-     * @return The AV3D layer representation used
-     */
-    SimpleLayer getLayer() {
-        return implLayer;
-    }
-
-    /**
-     * Convenience method to do the transition between the current viewpoint
-     * and the newly given one. Will jump or smooth transition depending on
-     * the new viewpoint requirements.
-     *
-     * @param inSetup true if this is the setup (initialBind) process
-     */
-    private void changeViewpoints(OGLViewpointNodeType vp) {
-        if(vp.getJump()) {
-            if (viewpointResizeManager != null)
-                viewpointResizeManager.removeViewpoint(currentViewpoint);
-
-            currentViewpoint = vp;
-
-            if (viewpointResizeManager != null)
-                viewpointResizeManager.addViewpoint(currentViewpoint, viewEnvironment);
-
-            // Always reset the viewpoint to the default position as we might
-            // be re-binding the same viewpoint, which is supposed to place it
-            // back in it's original spot.
-            vpTransformGroup = currentViewpoint.getPlatformGroup();
-            vpMatrix = currentViewpoint.getViewTransform();
-
-            SceneGraphPath path = generatePath(vpTransformGroup);
-
-            userInput.setViewInfo(currentViewpoint,
-                                  vpTransformGroup,
-                                  path);
-
-            if(vpTransformGroup.isLive())
-                vpTransformGroup.boundsChanged(this);
-            else
-                vpTransformGroup.setTransform(vpMatrix);
-
-            switch(currentViewpoint.getProjectionType()) {
-                case VRMLViewpointNodeType.PROJECTION_PERSPECTIVE:
-                    projectionType = ViewEnvironment.PERSPECTIVE_PROJECTION;
-
-                    break;
-
-                case VRMLViewpointNodeType.PROJECTION_ORTHO:
-                    projectionType = ViewEnvironment.ORTHOGRAPHIC_PROJECTION;
-                    break;
-
-                default:
-                    errorReporter.warningReport(UNKNOWN_PROJ_TYPE_MSG, null);
-                    projectionType = ViewEnvironment.PERSPECTIVE_PROJECTION;
-            }
-
-            viewEnvironment.setProjectionType(projectionType);
-
-        } else {
-
-System.out.println("non-jump transistions not handled yet");
-            // Copied code from jump section
-            if (viewpointResizeManager != null)
-                viewpointResizeManager.removeViewpoint(currentViewpoint);
-
-            currentViewpoint = vp;
-
-            if (viewpointResizeManager != null)
-                viewpointResizeManager.addViewpoint(currentViewpoint, viewEnvironment);
-
-            // Always reset the viewpoint to the default position as we might
-            // be re-binding the same viewpoint, which is supposed to place it
-            // back in it's original spot.
-            vpTransformGroup = currentViewpoint.getPlatformGroup();
-            vpMatrix = currentViewpoint.getViewTransform();
-
-            SceneGraphPath path = generatePath(vpTransformGroup);
-
-            userInput.setViewInfo(currentViewpoint,
-                                  vpTransformGroup,
-                                  path);
-
-            if(vpTransformGroup.isLive())
-                vpTransformGroup.boundsChanged(this);
-            else
-                vpTransformGroup.setTransform(vpMatrix);
-
-            switch(currentViewpoint.getProjectionType()) {
-                case VRMLViewpointNodeType.PROJECTION_PERSPECTIVE:
-                    projectionType = ViewEnvironment.PERSPECTIVE_PROJECTION;
-                    break;
-
-                case VRMLViewpointNodeType.PROJECTION_ORTHO:
-                    projectionType = ViewEnvironment.ORTHOGRAPHIC_PROJECTION;
-                    break;
-
-                default:
-                    errorReporter.warningReport(UNKNOWN_PROJ_TYPE_MSG, null);
-                    projectionType = ViewEnvironment.PERSPECTIVE_PROJECTION;
-            }
-
-            viewEnvironment.setProjectionType(projectionType);
-
-            // End copied code
-/*
-            // We have to do a smooth transition between the points
-            TransformGroup old_tg = currentViewpoint.getPlatformGroup();
-            TransformGroup new_tg = vp.getPlatformGroup();
-
-            oldTx.setIdentity();
-            destTx.setIdentity();
-            Matrix4f final_tx = vp.getViewTransform();
-
-            getLocalToVworld(old_tg, oldTx);
-            getLocalToVworld(new_tg, destTx);
-
-            // To work out the transition, the transform group of the dest
-            // viewpoint must be set to exactly the virtual world position of
-            // the old viewpoint and then allowed to transition across to the
-            // final destination. However, we must allow for the differences
-            // in their parent transforms first and make sure we have a proper
-            // scale value.
-
-            Vector3f old_trans = new Vector3f();
-            Vector3f dest_trans = new Vector3f();
-            Vector3f new_trans = new Vector3f();
-            Quat4f old_orient = new Quat4f();
-            Quat4f dest_orient = new Quat4f();
-            Quat4f new_orient = new Quat4f();
-
-            dest_orient.set(destTx);
-            old_orient.set(oldTx);
-
-
-            destTx.get(dest_orient);
-            destTx.get(dest_trans);
-            oldTx.get(old_orient);
-            oldTx.get(old_trans);
-
-            new_trans.sub(dest_trans, old_trans);
-            new_orient.sub(dest_orient, old_orient);
-
-            Matrix4f new_tx = new Matrix4f();
-            new_tx.set(new_orient, new_trans, 1);
-            new_tx.set(new_trans);
-
-            vpTransformGroup = new_tg;
-
-            vpMatrix = new_tx;
-            new_tg.boundsChanged(this);
-
-            currentViewpoint = vp;
-
-            if(hardwareFOV != 0f)
-                viewEnvironment.setFieldOfView(hardwareFOV);
-            else
-                viewEnvironment.setFieldOfView(currentViewpoint.getFieldOfView()  *
-                                               DEG_TO_RAD);
-*/
-        }
-
-        if(currentNavInfo != null)
-            globalEffects.useHeadlight(currentNavInfo.getHeadlight());
-    }
-
-    /**
-     * From the given node, create a scene graph path to the root. Used
-     * to make the path for the view handling. If a shared group is
-     * encountered, just take the first parent all the time
-     *
-     * @param leaf The terminal node of the path
-     * @return A path from here to the root
-     */
-    private SceneGraphPath generatePath(Node leaf) {
-
-        Node parent = leaf.getParent();
-        pathList.clear();
-
-        if(parent == null)
-            return null;
-
-        while(parent != null) {
-            if(parent instanceof SharedGroup) {
-                SharedGroup sg = (SharedGroup)parent;
-
-                if(sg.numParents() == 0)
-                    break;
-
-                sg.getParents(pathNodes);
-                parent = pathNodes[0];
-                pathList.add(parent);
-            } else {
-                pathList.add(parent);
-                parent = parent.getParent();
-            }
-        }
-
-        // Invert the array while copying it into the path.
-        pathMatrix.setIdentity();
-        int size =  pathList.size();
-
-        if(pathNodes.length < size)
-            pathNodes = new Node[size];
-
-        for(int i = 0; i < size; i++)
-            pathNodes[i] = pathList.get(size - i - 1);
-
-        return new SceneGraphPath(pathNodes, size, pathMatrix, pathMatrix);
-    }
-
-    /**
-     * Convenience method to walk to the root of the scene and calculate the
-     * root to virtual world coordinate location of the given node. If a
-     * sharedGroup is found, then take the first parent listed always.
-     *
-     * @param terminal The end node to calculate from
-     * @param mat The matrix to put the final result into
-     */
-    private void getLocalToVworld(Node terminal, Matrix4f mat) {
-
-        Node parent = terminal.getParent();
-        pathList.clear();
-
-        if(parent instanceof TransformGroup)
-            pathList.add(parent);
-
-        while(parent != null) {
-            if(parent instanceof SharedGroup) {
-                SharedGroup sg = (SharedGroup)parent;
-
-                int num_parents = sg.numParents();
-
-                if(num_parents == 0)
-                    break;
-                else if(num_parents > pathNodes.length)
-                    pathNodes = new Node[num_parents];
-
-                sg.getParents(pathNodes);
-                parent = pathNodes[0];
-            } else {
-                if(parent instanceof TransformGroup)
-                    pathList.add(parent);
-
-                parent = parent.getParent();
-            }
-        }
-
-        int num_nodes = pathList.size();
-        mat.setIdentity();
-        pathMatrix.setIdentity();
-
-        // use vwTransform for fetching the tx. It is only a temp var anyway
-        for(int i = num_nodes - 1; i >= 0; i--) {
-            TransformGroup tg = (TransformGroup)pathList.get(i);
-            tg.getTransform(pathMatrix);
-
-            mat.mul(pathMatrix);
-        }
-    }
-
-    /**
-     * Create the default bindables and add them to the scene of the given
-     * spec version.
-     *
-     * @param major The spec major version number
-     * @param minor The spec minor version number
-     */
-    private void createDefaultBindables(int major, int minor) {
-        VRMLNodeFactory fac =
-            DefaultNodeFactory.createFactory(
-                DefaultNodeFactory.OPENGL_RENDERER
-            );
-
-        fac.setSpecVersion(major, minor);
-
-        defaultViewpoint =
-            (OGLViewpointNodeType)fac.createVRMLNode(NAV_COMPONENT,
-                                                     "Viewpoint",
-                                                     false);
-
-        defaultViewpoint.setDescription("Default viewpoint");
-        defaultViewpoint.setupFinished();
-
-        defaultNavInfo =
-            (VRMLNavigationInfoNodeType)fac.createVRMLNode(NAV_COMPONENT,
-                                                           "NavigationInfo",
-                                                            false);
-        defaultNavInfo.setupFinished();
-
-        defaultBackground =
-            (VRMLBackgroundNodeType)fac.createVRMLNode(ENV_COMPONENT,
-                                                       "Background",
-                                                       false);
-        defaultBackground.setupFinished();
-
-        defaultFog =
-            (VRMLFogNodeType)fac.createVRMLNode(ENV_COMPONENT, "Fog", false);
-        defaultFog.setFogType(VRMLFogNodeType.FOG_TYPE_DISABLE);
-        defaultFog.setupFinished();
-
-        // Fill in the geometry of the default viewpoints.
-        Node vp_node = (Node)defaultViewpoint.getSceneGraphObject();
-        Node bg_node = (Node)((OGLVRMLNode)defaultBackground).getSceneGraphObject();
-        Node fog_node = (Node)((OGLVRMLNode)defaultFog).getSceneGraphObject();
-
-        Group grp = new Group();
-        grp.addChild(vp_node);
-        grp.addChild(bg_node);
-        grp.addChild(fog_node);
-
-        pendingBindables = grp;
-        updateBindables = true;
-
-        if(sgTransformGroup.isLive())
-            sgTransformGroup.boundsChanged(this);
-        else
-            updateNodeBoundsChanges(sgTransformGroup);
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2005 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.renderer.ogl.browser;
+
+// External imports
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.vecmath.Matrix4f;
+import javax.vecmath.Vector3f;
+import javax.vecmath.AxisAngle4f;
+import javax.vecmath.Point3f;
+
+import org.j3d.aviatrix3d.*;
+import org.j3d.aviatrix3d.rendering.BoundingVolume;
+import org.j3d.util.MatrixUtils;
+
+// Local imports
+import org.web3d.browser.NavigationStateListener;
+import org.web3d.browser.ProfilingListener;
+import org.web3d.browser.SensorStatusListener;
+import org.web3d.browser.ScreenCaptureListener;
+import org.web3d.browser.ViewpointStatusListener;
+
+import org.j3d.util.DefaultErrorReporter;
+import org.j3d.util.ErrorReporter;
+import org.j3d.util.IntHashMap;
+
+import org.web3d.vrml.lang.TypeConstants;
+import org.web3d.vrml.lang.VRMLNodeFactory;
+
+import org.web3d.vrml.nodes.*;
+
+import org.web3d.vrml.renderer.DefaultNodeFactory;
+import org.web3d.vrml.renderer.ogl.input.DefaultLayerSensorManager;
+import org.web3d.vrml.renderer.ogl.input.OGLUserInputHandler;
+import org.web3d.vrml.renderer.ogl.nodes.OGLUserData;
+import org.web3d.vrml.renderer.ogl.nodes.OGLViewpointNodeType;
+import org.web3d.vrml.renderer.ogl.nodes.OGLTransformNodeType;
+import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
+
+import org.xj3d.core.eventmodel.BindableNodeListener;
+import org.xj3d.core.eventmodel.BindableNodeManager;
+import org.xj3d.core.eventmodel.LayerManager;
+import org.xj3d.core.eventmodel.SensorManager;
+
+/**
+ * OpenGL implementation of a layer manager.
+ * <p>
+ *
+ * The layer manager is responsible for keeping track of all the top level
+ * renderable structure within a scene.
+ * <p>
+ *
+ * The Aviatrix Scenegraph for each layer is structured as follows:
+ * <pre>
+ *               SimpleLayer
+ *                   |
+ *               SimpleScene
+ *                   |
+ *               worldGroup
+ *                  /\
+ *                 /  \
+ *                /    \
+ *               /      \
+ *              /        \
+ *   sgTransformGroup     commonSg
+ *         |                 |
+ *        X3D Scene        globalEffects
+ * </pre>
+ *
+ * @author Justin Couch
+ * @version $Revision: 1.38 $
+ */
+class OGLLayerManager
+    implements LayerManager,
+               NodeUpdateListener,
+               BindableNodeListener,
+               NavigationInfoChangeListener,
+               LayerListener,
+               OGLTransformNodeType {
+
+    /** Message when the node factory doesn't have any configurations set */
+    private static final String NODE_PROFILE_ERR =
+        "LayerManager is unable to initialise the default bindables " +
+        "due to missing node factory configurations.";
+
+    /**
+     * Message for a viewpoint with a weird projection constant. Since this is
+     * Hard-coded into the viewpoint implementation node, we should never see
+     * this error, unless there is a user-implemented type of viewpoint. In
+     * which case, you are now reading the right error message and know that
+     * you need to go fix up the appropriate switch statements down the bottom
+     * of this class.
+     */
+    private static final String UNKNOWN_PROJ_TYPE_MSG =
+        "A viewpoint has been provided with an unknown projection type. The " +
+        "code can only deal with perspective and orthographic projections. " +
+        "We'll default to perspective now.";
+
+    /** Error message when the viewpointAdded() call generates an error */
+    private static final String VP_ADD_ERR =
+        "Error sending viewpoint addition notification.";
+
+    /** Error message when the viewpointRemoved() call generates an error */
+    private static final String VP_REMOVE_ERR =
+        "Error sending viewpoint removed notification.";
+
+    /** Error message when the viewpointBound() call generates an error */
+    private static final String VP_BOUND_ERR =
+        "Error sending viewpoint binding notification.";
+
+    /** Error message when the viewpointLayerActive() call generates an error */
+    private static final String VP_ACTIVATE_ERR =
+        "Error sending viewpoint layer activation notification.";
+
+    /** Error message when the viewpointLayerAdded() call generates an error */
+    private static final String VP_LAYER_ADD_ERR =
+        "Error sending viewpoint layer addtion notification.";
+
+    /** Error message when the viewpointLayerRemoved() call generates an error */
+    private static final String VP_LAYER_REMOVE_ERR =
+        "Error sending viewpoint layer removal notification.";
+
+    /** The time in milliseconds to move between two points */
+    private static final int VP_TRANSITION_TIME = 2_000;
+
+    /** The name of the navigation component */
+    private static final String NAV_COMPONENT = "Navigation";
+
+    /** The name of the environmental effects component */
+    private static final String ENV_COMPONENT = "EnvironmentalEffects";
+
+
+    /** Reporter instance for handing out errors */
+    private ErrorReporter errorReporter;
+
+    /** The View that we use for everything */
+    private ViewEnvironment viewEnvironment;
+
+    /** The current viewpoint node we are playing with */
+    private OGLViewpointNodeType currentViewpoint;
+
+    /** The current navigation info we are running with */
+    private VRMLNavigationInfoNodeType currentNavInfo;
+
+    /** Default viewpoint that exists in every scene */
+    private OGLViewpointNodeType defaultViewpoint;
+
+    /** Default navigationInfo that exists in every scene */
+    private VRMLNavigationInfoNodeType defaultNavInfo;
+
+    /** Default background that exists in every scene */
+    private VRMLBackgroundNodeType defaultBackground;
+
+    /** Default fog that exists in every scene */
+    private VRMLFogNodeType defaultFog;
+
+    /** The node stack for viewpoints */
+    private BindableNodeManager viewpointStack;
+
+    /** The node stack for navigation information */
+    private BindableNodeManager navInfoStack;
+
+    /** The node stack for navigation information */
+    private BindableNodeManager backgroundStack;
+
+    /** The node stack for navigation information */
+    private BindableNodeManager fogStack;
+
+    /** Map of node primary type to the bindable manager for that type */
+    private IntHashMap<BindableNodeManager> bindablesMap;
+
+    /** Clock for setting bindTime information */
+    private VRMLClock clock;
+
+    /** The global effects for this layer */
+    private GlobalEffectsGroup globalEffects;
+
+    /** Manager of the global sensor nodes */
+    private SensorManager sensorManager;
+
+    /** Manager of viewpoint resizes */
+    private ViewpointResizeManager viewpointResizeManager;
+
+    /** The per-layer sensor manager */
+    private DefaultLayerSensorManager layerSensorManager;
+
+    /** Is this layer currently active for navigation purposes? */
+    private boolean navigationEnabled;
+
+    /** Temporary holding the projection type for the update callback */
+    private int projectionType;
+
+    /** Input processing for this layer */
+    private OGLUserInputHandler userInput;
+
+    /** Listeners for the viewpoint status updates from this layer */
+    private List<ViewpointStatusListener> viewpointStatusListeners;
+
+    /** Rendering effects if you want something other than polygons */
+    private OGLRenderingEffects renderEffects;
+
+    // Aviatrix3D variables
+
+    /** The layer above the scene */
+    private SimpleLayer implLayer;
+
+    /** Render manager for handling the backgrounds and fogs */
+    private SimpleScene implScene;
+
+    /** The top level node the universe is using */
+    private Group worldGroup;
+
+    /** The Transform holding the main scene, child 0=vp, 1=loaded scene */
+    private TransformGroup sgTransformGroup;
+
+    /** A group to hold the last vp group for later update */
+    private TransformGroup vpTransformGroup;
+
+    /** The current world root */
+    private Group worldRoot;
+
+    /**
+     * Flag to say that a clear() call has been made and we need to
+     * delete the scene contents, but not kill everything.
+     */
+    private boolean clearAllContent;
+
+    /** Flag to indicate that the default bindables need to be update */
+    private boolean updateBindables;
+
+    /** The geometry from the layer or world root that is pending addition */
+    private Group pendingWorldGeom;
+
+    /** Subgraph that contains the updated default bindables */
+    private Group pendingBindables;
+
+    /** A matrix to hold the last vp matrix for later update */
+    private Matrix4f vpMatrix;
+
+    /** Matrix containing the world scale that is calculated for this layer */
+    private Matrix4f worldScaleMatrix;
+
+    /** A matrix used when calculating the scene graph path */
+    private Matrix4f pathMatrix;
+
+    /** The ID of this layer */
+    private int layerId;
+
+    /** The type of viewport that this layer has */
+    private int viewportType;
+
+    /** The viewport node from the layer. Null if the root layer */
+    private VRMLViewportNodeType viewport;
+
+    /** Temp var used to fetch the scene graph path */
+    private List<Node> pathList;
+
+    /** An array used to fetch the nodes from pathNodes */
+    private Node[] pathNodes;
+
+    /** An aviatrix viewport */
+    private SimpleViewport simpleViewport;
+
+    /**
+     * Create a new instance of the layer manager that looks after the
+     * given effects group.
+     *
+     * @param globals The handler for fog/background et al for this layer
+     */
+    OGLLayerManager() {
+        layerId = -1;
+        clearAllContent = false;
+        updateBindables = false;
+
+        pathList = new ArrayList<>();
+        pathNodes = new Node[20];  // some arbitrary value;
+
+        viewportType = VIEWPORT_FULLWINDOW;
+        projectionType = ViewEnvironment.PERSPECTIVE_PROJECTION;
+
+        implScene = new SimpleScene();
+        viewEnvironment = implScene.getViewEnvironment();
+
+        simpleViewport = new SimpleViewport();
+        simpleViewport.setScene(implScene);
+
+        implLayer = new SimpleLayer();
+        implLayer.setViewport(simpleViewport);
+
+        globalEffects = new GlobalEffectsGroup(implScene);
+        renderEffects = new OGLRenderingEffects(implScene);
+
+        implScene.setRenderEffectsProcessor(renderEffects);
+
+        layerSensorManager = new DefaultLayerSensorManager();
+        layerSensorManager.setViewEnvironment(viewEnvironment);
+        layerSensorManager.setGlobalEffectsHandler(globalEffects);
+
+        userInput = (OGLUserInputHandler)layerSensorManager.getUserInputHandler();
+
+        OGLUserData data = new OGLUserData();
+        data.owner = OGLLayerManager.this;
+
+        Group common_sg = new Group();
+        common_sg.addChild(globalEffects);
+
+        worldGroup = new Group();
+
+        // Group for holding the main scene. Prepopulate two empty children.
+        // The first child belongs to all the default bindable nodes and is
+        // filled in at initialization of this class. The second index is set
+        // to be the geometry of the loaded world.
+        sgTransformGroup = new TransformGroup();
+        sgTransformGroup.setUserData(data);
+        sgTransformGroup.addChild(null);
+        sgTransformGroup.addChild(null);
+
+        worldGroup.addChild(common_sg);
+        worldGroup.addChild(sgTransformGroup);
+
+        implScene.setRenderedGeometry(worldGroup);
+        globalEffects.initialize();
+
+        bindablesMap = new IntHashMap<>();
+        errorReporter = DefaultErrorReporter.getDefaultReporter();
+
+        worldScaleMatrix = new Matrix4f();
+        worldScaleMatrix.setIdentity();
+
+        pathMatrix = new Matrix4f();
+
+        viewpointStatusListeners = new ArrayList<>(1);
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by LayerManager
+    //----------------------------------------------------------
+
+    /**
+     * Register an error reporter with the engine so that any errors generated
+     * by the loading of script code can be reported in a nice, pretty fashion.
+     * Setting a value of null will clear the currently set reporter. If one
+     * is already set, the new value replaces the old.
+     *
+     * @param reporter The instance to use or null
+     */
+    @Override
+    public void setErrorReporter(ErrorReporter reporter) {
+        errorReporter = reporter;
+
+        // Reset the default only if we are not shutting down the system.
+        if(reporter == null)
+            errorReporter = DefaultErrorReporter.getDefaultReporter();
+
+        int[] keys = bindablesMap.keySet();
+
+        for(int i = 0; i < keys.length; i++) {
+            BindableNodeManager mgr = bindablesMap.get(keys[i]);
+            mgr.setErrorReporter(errorReporter);
+        }
+    }
+
+    /**
+     * Complete the initialization of the layer manager now. This should be
+     * called after setting the clock and the current error reporter instance.
+     *
+     * @param sensors The sensor manager to start with from the global list
+     */
+    @Override
+    public void initialise(SensorManager smgr) {
+        sensorManager = smgr;
+
+        clock = sensorManager.getVRMLClock();
+
+        BindableNodeManager vp_mgr = new BindableNodeManager();
+        vp_mgr.setVRMLClock(clock);
+        vp_mgr.setErrorReporter(errorReporter);
+        vp_mgr.setNodeChangeListener(this);
+        bindablesMap.put(TypeConstants.ViewpointNodeType, vp_mgr);
+        viewpointStack = vp_mgr;
+
+        BindableNodeManager ni_mgr = new BindableNodeManager();
+        ni_mgr.setVRMLClock(clock);
+        ni_mgr.setErrorReporter(errorReporter);
+        ni_mgr.setNodeChangeListener(this);
+        bindablesMap.put(TypeConstants.NavigationInfoNodeType, ni_mgr);
+        navInfoStack = ni_mgr;
+
+        BindableNodeManager bg_mgr = new BindableNodeManager();
+        bg_mgr.setVRMLClock(clock);
+        bg_mgr.setErrorReporter(errorReporter);
+        bindablesMap.put(TypeConstants.BackgroundNodeType, bg_mgr);
+        backgroundStack = bg_mgr;
+
+        BindableNodeManager fog_mgr = new BindableNodeManager();
+        fog_mgr.setVRMLClock(clock);
+        fog_mgr.setErrorReporter(errorReporter);
+        bindablesMap.put(TypeConstants.FogNodeType, fog_mgr);
+        fogStack = fog_mgr;
+
+        layerSensorManager.setNavigationStacks(vp_mgr,
+                                               ni_mgr,
+                                               bg_mgr,
+                                               fog_mgr);
+        layerSensorManager.setVRMLClock(clock);
+
+        sensorManager.addLayerSensorManager(layerSensorManager);
+
+        createDefaultBindables(3, 2);
+    }
+
+    /**
+     * Set or reset the layer ID to the new ID value.
+     *
+     * @param id A non-negative ID for the layer
+     */
+    @Override
+    public void setLayerId(int id) {
+        layerId = id;
+        layerSensorManager.setLayerId(id);
+        globalEffects.setLayerId(id);
+    }
+
+    /**
+     * Set the specification version that should be handled by this manager.
+     * This is needed so that the correct version of the default bindables are
+     * instantiated before the rest of the world loads. For example, the default
+     * nav type for VRML is different to X3D, so this makes sure all the right
+     * spec stuff is catered for.
+     *
+     * @param major The spec major version number
+     * @param minor The spec minor version number
+     */
+    @Override
+    public void setSpecVersion(int major, int minor) {
+        createDefaultBindables(major, minor);
+    }
+
+    /**
+     * Change the rendering style that the browser should currently be using
+     * for all layers. Various options are available based on the constants
+     * defined in this
+     *
+     * @param style One of the RENDER_* constants from LayerRenderingManager
+     * @throws IllegalArgumentException A style constant that is not recognized
+     *   by the implementation was provided
+     */
+    @Override
+    public void setRenderingStyle(int style)
+        throws IllegalArgumentException {
+
+        renderEffects.setRenderingStyle(style);
+    }
+
+    /**
+     * Get the currently set rendering style. The default style is
+     * RENDER_SHADED.
+     *
+     * @return one of the RENDER_ constants from LayerRenderingManager
+     */
+    @Override
+    public int getRenderingStyle() {
+        return renderEffects.getRenderingStyle();
+    }
+
+    /**
+     * Capture the screen on the next render.
+     *
+     * @param listener Listener for capture results
+     * @param width The screen width
+     * @param height The screen height
+     */
+    public void captureScreenOnce(ScreenCaptureListener listener,
+                                  int width,
+                                  int height) {
+        renderEffects.captureScreenOnce(listener, width, height);
+    }
+
+    /**
+     * Capture the screen on each render.
+     *
+     * @param listener Listener for capture results
+     * @param width The screen width
+     * @param height The screen height
+     */
+    public void captureScreenStart(ScreenCaptureListener listener,
+                                   int width,
+                                   int height) {
+        renderEffects.captureScreenStart(listener, width, height);
+    }
+
+    /**
+     * Stop capturing the screen on each render.
+     */
+    public void captureScreenEnd() {
+        renderEffects.captureScreenEnd();
+    }
+
+    /**
+     * Perform the initial bind for a new scene. This is typically called some
+     * time just after the clear() method with a new scene. This will
+     * automatically reset the current navigation state for this layer to be
+     * inactive, even if it was previously active.
+     */
+    @Override
+    public void initialBind() {
+
+        // create default nodes to suit.
+        double time = clock.getTime();
+
+        // Put the defaults back into the stacks after it has been
+        // cleared
+        viewpointStack.addNode(defaultViewpoint, true);
+        navInfoStack.addNode(defaultNavInfo, true);
+        backgroundStack.addNode(defaultBackground, true);
+        fogStack.addNode((VRMLBindableNodeType)defaultFog, true);
+
+        viewpointStack.addDefaultBindable(defaultViewpoint);
+        navInfoStack.addDefaultBindable(defaultNavInfo);
+        backgroundStack.addDefaultBindable(defaultBackground );
+        fogStack.addDefaultBindable((VRMLBindableNodeType)defaultFog);
+
+// LAYERS:
+// This should also go looking for the default for this viewpoint based on
+// the #ref part of a URL and see if it is part of this layer.
+        VRMLViewpointNodeType vp =
+            (VRMLViewpointNodeType)viewpointStack.getFirstNode();
+
+        VRMLNavigationInfoNodeType nav =
+            (VRMLNavigationInfoNodeType)navInfoStack.getFirstNode();
+
+        VRMLBackgroundNodeType bg =
+            (VRMLBackgroundNodeType)backgroundStack.getFirstNode();
+
+        VRMLFogNodeType fog = (VRMLFogNodeType)fogStack.getFirstNode();
+
+        vp.setBind(true, true, time);
+        nav.setBind(true, true, time);
+        bg.setBind(true, true, time);
+        ((VRMLBindableNodeType)fog).setBind(true, true, time);
+
+        currentNavInfo = nav;
+        currentNavInfo.addNavigationChangedListener(this);
+        globalEffects.useHeadlight(currentNavInfo.getHeadlight());
+
+        SceneGraphPath path = generatePath(vpTransformGroup);
+
+        userInput.setViewInfo(currentViewpoint,
+                              vpTransformGroup,
+                              path);
+
+        if(sgTransformGroup.isLive())
+            sgTransformGroup.boundsChanged(this);
+        else
+            updateNodeBoundsChanges(sgTransformGroup);
+    }
+
+    /**
+     * Get the bindable node manager for the given node type. If the node type
+     * does not have a bindable manager for it, one will be created.
+     *
+     * @param type The type constant of the node type for the manager
+     * @return The bindable manager for it
+     * @see org.web3d.vrml.lang.TypeConstants
+     */
+    @Override
+    public BindableNodeManager getBindableManager(int type) {
+        BindableNodeManager ret_val = bindablesMap.get(type);
+
+        if(ret_val == null) {
+            ret_val = new BindableNodeManager();
+            ret_val.setErrorReporter(errorReporter);
+            ret_val.setVRMLClock(sensorManager.getVRMLClock());
+            bindablesMap.put(type, ret_val);
+        }
+
+        return ret_val;
+    }
+
+    /**
+     * Enable or disable this layer to be currently navigable layer. The
+     * navigable layer takes the input from the input devices and interacts
+     * with the currently bound viewpoint etc.
+     *
+     * @param state True to enable this layer as navigable
+     */
+    @Override
+    public void setActiveNavigationLayer(boolean state) {
+        navigationEnabled = state;
+        layerSensorManager.setNavigationEnabled(state);
+        userInput.sendCurrentNavState();
+
+        if(state) {
+            int size = viewpointStatusListeners.size();
+
+            for(int i = 0; i < size; i++) {
+                try {
+                    ViewpointStatusListener l = viewpointStatusListeners.get(i);
+
+                    l.viewpointLayerActive(layerId);
+                } catch(Exception e) {
+                    errorReporter.warningReport(VP_ACTIVATE_ERR, e);
+                }
+            }
+
+            if(simpleViewport.isLive())
+                simpleViewport.dataChanged(this);
+            else
+                updateNodeDataChanges(simpleViewport);
+
+        }
+    }
+
+    /**
+     * Check to see if this is the active navigation layer.
+     *
+     * @return true if this is the currently active layer for navigation
+     */
+    @Override
+    public boolean isActiveNavigationLayer() {
+        return navigationEnabled;
+    }
+
+    /**
+     * Set the desired navigation mode. The mode string is one of the
+     * spec-defined strings for the NavigationInfo node in the VRML/X3D
+     * specification.
+     *
+     * @param mode The requested mode.
+     * @return Whether the mode is valid.
+     */
+    @Override
+    public boolean setNavigationMode(String mode) {
+        return userInput.setNavigationMode(mode);
+    }
+
+    /**
+     * Get the user's location and orientation.  This will use the viewpoint
+     * bound in the active layer.
+     *
+     * @param pos The current user position
+     * @param ori The current user orientation
+     */
+    @Override
+    public void getUserPosition(Vector3f pos, AxisAngle4f ori) {
+        userInput.getPosition(pos);
+        userInput.getOrientation(ori);
+    }
+
+    /**
+     * Move the user's location to see the entire world in this layer. Change
+     * the users orientation to look at the center of the world.
+     *
+     * @param animated Should the transition be animated.  Defaults to FALSE.
+     */
+    @Override
+    public void fitToWorld(boolean animated) {
+
+        vpMatrix.setIdentity();
+
+        BoundingVolume bounds = worldRoot.getBounds();
+
+        if (bounds instanceof BoundingVoid) {return;}
+
+        float[] boundsMin = new float[3];
+        float[] boundsMax = new float[3];
+
+        bounds.getExtents(boundsMin, boundsMax);
+
+        float[] size = new float[3];
+        ((BoundingBox)bounds).getSize(size);
+
+/*
+        float zrange = Math.abs(boundsMax[2] - boundsMin[2]);
+
+        float mult = 1;
+
+        if (zrange > 1000)
+            mult = 1.25f;
+        else
+            mult = 2;
+
+        float zloc = center[2] + zrange * mult;
+*/
+        float x_center = ( boundsMin[0] + boundsMax[0] ) / 2;
+        float y_center = ( boundsMin[1] + boundsMax[1] ) / 2;
+        float z_center = ( boundsMin[2] + boundsMax[2] ) / 2;
+
+        float[] center = new float[]{ x_center, y_center, z_center };
+
+        // the extents, by half
+        float x = size[0];
+        float y = size[1];
+        float z = size[2];
+
+        // radius of the bounding sphere
+        float radius = (float)Math.sqrt((x * x) + (y * y) + (z * z));
+
+        // given a field-of-view of 45 degrees - the distance from
+        // the center of the bounding sphere at which the sphere
+        // surface should be within the f-o-v (0.392699 radians == 22.5 degrees)
+        // note, the sin gives the distance to the sphere's visible edge,
+        // a tan would give the distance to the center. the edge distance
+        // is greater and moves the position a bit farther away - providing
+        // some margin between the actual f-o-v and the bounding sphere
+        float distance = radius / (float)(Math.sin(0.392699));
+
+        // equidistant components of the distance to combine with
+        // the object center.
+        float offset = ( distance / (float)Math.sqrt(3.0) );
+
+        // if the distance away is less than the clipping plane
+        // then move the viewpoint a little
+        if (offset < 0.125f) {
+            offset = 0.126f;
+
+            // would prefer to change clip plane, not sure how yet
+        }
+
+        float[] position = new float[]{
+                x_center + offset, y_center + offset, z_center + offset};
+
+
+        vpMatrix.setTranslation(new Vector3f(position[0], position[1], position[2]));
+
+        Point3f from = new Point3f(position);
+        Point3f to = new Point3f(center);
+        Vector3f Yup = new Vector3f(0, 1, 0);
+
+        MatrixUtils mu = new MatrixUtils();
+        Matrix4f rot = new Matrix4f();
+        mu.lookAt(from, to, Yup, rot);
+        mu.inverse(rot, rot);
+
+        AxisAngle4f a = new AxisAngle4f();
+        a.set(rot);
+
+        vpMatrix.setRotation(a);
+
+        if (vpTransformGroup.isLive())
+            vpTransformGroup.boundsChanged(this);
+        else
+            updateNodeBoundsChanges(vpTransformGroup);
+    }
+
+    /**
+     * Set the contents that this layer manages to be the ungrouped nodes
+     * of the scene. The code should take all the children nodes from this node
+     * that are not part of a layer and render them as this layer.
+     *
+     * @param root The root of the world to handle
+     */
+    @Override
+    public void setManagedNodes(VRMLWorldRootNodeType root) {
+        // The base layer always occupies the full window space.
+        viewportType = VIEWPORT_FULLWINDOW;
+        viewport = null;
+
+        int size = viewpointStatusListeners.size();
+
+        for(int i = 0; i < size; i++) {
+            try {
+                ViewpointStatusListener l = viewpointStatusListeners.get(i);
+
+                l.viewpointLayerAdded(layerId);
+            } catch(Exception e) {
+                errorReporter.warningReport(VP_LAYER_ADD_ERR, e);
+            }
+        }
+
+        OGLVRMLNode ogl_root = (OGLVRMLNode)root;
+
+        pendingWorldGeom = (Group)ogl_root.getSceneGraphObject();
+        layerSensorManager.setWorldRoot(pendingWorldGeom);
+    }
+
+    /**
+     * Set the contents that this layer manages the specific layer instance
+     * provided.
+     *
+     * @param layer The root of the layer to handle
+     */
+    @Override
+    public void setManagedLayer(VRMLLayerNodeType layer) {
+        viewportType = layer.getViewportType();
+
+        VRMLNodeType vp = layer.getViewport();
+        VRMLNodeType node;
+
+        if(vp instanceof VRMLProtoInstance) {
+            node = ((VRMLProtoInstance)vp).getImplementationNode();
+
+            while((node != null) && (node instanceof VRMLProtoInstance))
+                node = ((VRMLProtoInstance)node).getImplementationNode();
+
+            if((node != null) && !(node instanceof VRMLViewportNodeType)) {
+                // if it is invalid, replace the window with a fullscreen one.
+                // Ideally we would never hit this as the field should never
+                // have been allowed to be set in the first place.
+                viewportType = VIEWPORT_FULLWINDOW;
+                viewport = null;
+                node = null;
+            }
+        } else if(vp != null &&
+                  (!(vp instanceof VRMLViewportNodeType))) {
+
+            // if it is invalid, replace the window with a fullscreen one.
+            // Ideally we would never hit this as the field should never have
+            // been allowed to be set in the first place.
+            viewportType = VIEWPORT_FULLWINDOW;
+            viewport = null;
+            node = null;
+        } else {
+            node = vp;
+        }
+
+        viewport = (VRMLViewportNodeType)node;
+
+        int size = viewpointStatusListeners.size();
+
+        for(int i = 0; i < size; i++) {
+            try {
+                ViewpointStatusListener l = viewpointStatusListeners.get(i);
+
+                l.viewpointLayerAdded(layerId);
+            } catch(Exception e) {
+                errorReporter.warningReport(VP_LAYER_ADD_ERR, e);
+            }
+        }
+
+        OGLVRMLNode ogl_root = (OGLVRMLNode)layer;
+
+        pendingWorldGeom = (Group)ogl_root.getSceneGraphObject();
+        layerSensorManager.setWorldRoot(pendingWorldGeom);
+        layerSensorManager.setIsPickable(layer.isPickable());
+
+        layer.addLayerListener(this);
+    }
+
+    /**
+     * Override the file field of view values with a value that suits
+     * the given output device. A value of 0 = no, otherwise use this
+     * instead of content
+     *
+     * @param fov The fov in degrees.
+     */
+    @Override
+    public void setHardwareFOV(float fov) {
+        viewpointResizeManager.setHardwareFOV(fov);
+    }
+
+    /**
+     * Set whether stereo is enabled for all layers.
+     */
+    @Override
+    public void setStereoEnabled(boolean enabled) {
+        viewEnvironment.setStereoEnabled(enabled);
+    }
+
+    /**
+     * Shutdown the node manager now. If this is using any external resources
+     * it should remove those now as the entire application is about to die
+     */
+    @Override
+    public void shutdown() {
+
+        simpleViewport = null;
+        sensorManager.removeLayerSensorManager(layerSensorManager);
+
+        if (worldGroup.isLive()) {
+            worldGroup.boundsChanged(this);
+        } else {
+            updateNodeBoundsChanges(worldGroup);
+        }
+        globalEffects.shutdown();
+    }
+
+    /**
+     * Update the viewing matrix.  Call this when you want the SensorManager to update
+     * the viewing matrix.  Typically after all user input and events have resolved.
+     */
+    @Override
+    public void updateViewMatrix() {
+        layerSensorManager.updateViewMatrix();
+    }
+
+    /**
+     * Force clearing all currently managed nodes from this manager now. This
+     * is used to indicate that a new world is about to be loaded and
+     * everything should be cleaned out now.
+     */
+    @Override
+    public void clear() {
+        viewport = null;
+        int size = viewpointStatusListeners.size();
+
+        // if we were the currently active nav layer, then reset the
+        // active layer to layer 0, as that's the only one we can
+        // guarantee always exists.
+        //
+        // Note, could be dodgy if we are layer 0. Need to check on this.
+        if(navigationEnabled) {
+            for(int i = 0; i < size; i++) {
+                try {
+                    ViewpointStatusListener l = viewpointStatusListeners.get(i);
+
+                    if(layerId == 0)
+                        l.viewpointLayerActive(-1);
+                    else
+                        l.viewpointLayerActive(0);
+
+                } catch(Exception e) {
+                    errorReporter.warningReport(VP_ACTIVATE_ERR, e);
+                }
+            }
+        }
+
+        for(int i = 0; i < size; i++) {
+            try {
+                ViewpointStatusListener l = viewpointStatusListeners.get(i);
+
+                l.viewpointLayerRemoved(layerId);
+            } catch(Exception e) {
+                errorReporter.warningReport(VP_LAYER_REMOVE_ERR, e);
+            }
+        }
+
+        if(currentNavInfo != null)
+            currentNavInfo.removeNavigationChangedListener(this);
+
+        layerSensorManager.clear();
+        layerSensorManager.setNavigationEnabled(false);
+
+        vpTransformGroup = null;
+        pendingWorldGeom = null;
+        worldRoot = null;
+        currentViewpoint = null;
+        currentNavInfo = null;
+        clearAllContent = true;
+
+        userInput.clear();
+
+        pathList.clear();
+        for (int i = 0; i < pathNodes.length; i++){
+            pathNodes[i] = null;
+        }
+        if (viewpointResizeManager != null ) {
+            viewpointResizeManager.clear();
+        }
+
+        if(sgTransformGroup.isLive())
+            sgTransformGroup.boundsChanged(this);
+        else
+            updateNodeBoundsChanges(sgTransformGroup);
+    }
+
+    /**
+     * Check to see if this is an unmanaged size layer. A layer that has no
+     * specific viewport set, or a percentage size.
+     *
+     * @return One of the VIEWPORT_* constants
+     */
+    @Override
+    public int getViewportType() {
+        return viewportType;
+    }
+
+    /**
+     * Get the Viewport node that this layer uses. If the layer does not have
+     * a viewport set, then it returns null. The value is the real
+     * X3DViewportNode instance stripped from any surrounding proto shells etc.
+     *
+     * @return The current viewport node instance used by the layer
+     */
+    @Override
+    public VRMLViewportNodeType getViewport() {
+        return viewport;
+    }
+
+    /**
+     * Add a listener for navigation state changes.  A listener can only be added once.
+     * Duplicate requests are ignored.
+     *
+     * @param l The listener to add
+     */
+    @Override
+    public void addNavigationStateListener(NavigationStateListener l) {
+        userInput.addNavigationStateListener(l);
+    }
+
+    /**
+     * Remove a navigation state listener. If the reference is null or not known,
+     * the request is silently ignored.
+     *
+     * @param l The listener to remove
+     */
+    @Override
+    public void removeNavigationStateListener(NavigationStateListener l) {
+        userInput.removeNavigationStateListener(l);
+    }
+
+    /**
+     * Request notification of profiling information.
+     *
+     * @param l The listener
+     */
+    public void addProfilingListener(ProfilingListener l) {
+        if(l == null)
+            return;
+
+        renderEffects.addProfilingListener(l);
+    }
+
+    /**
+     * Remove notification of profiling information.
+     *
+     * @param l The listener
+     */
+    public void removeProfilingListener(ProfilingListener l) {
+        if(l == null)
+            return;
+
+        renderEffects.removeProfilingListener(l);
+    }
+
+    /**
+     * Add a listener for sensor state changes.  A listener can only be added once.
+     * Duplicate requests are ignored.
+     *
+     * @param l The listener to add
+     */
+    @Override
+    public void addSensorStatusListener(SensorStatusListener l) {
+        userInput.addSensorStatusListener(l);
+    }
+
+    /**
+     * Remove a sensor state listener. If the reference is null or not known,
+     * the request is silently ignored.
+     *
+     * @param l The listener to remove
+     */
+    @Override
+    public void removeSensorStatusListener(SensorStatusListener l) {
+        userInput.removeSensorStatusListener(l);
+    }
+
+    /**
+     * Add a listener for viewpoint status changes.  A listener can only be added once.
+     * Duplicate requests are ignored.
+     *
+     * @param l The listener to add
+     */
+    @Override
+    public void addViewpointStatusListener(ViewpointStatusListener l) {
+        if((l != null) && !viewpointStatusListeners.contains(l)) {
+            viewpointStatusListeners.add(l);
+
+            // Inform the listener of our status
+            l.viewpointLayerAdded(layerId);
+
+            if(navigationEnabled)
+                l.viewpointLayerActive(layerId);
+
+            // Go through the list of our currently available viewpoints
+        }
+    }
+
+    /**
+     * Remove a viewpoint state listener. If the reference is null or not known,
+     * the request is silently ignored.
+     *
+     * @param l The listener to remove
+     */
+    @Override
+    public void removeViewpointStatusListener(ViewpointStatusListener l) {
+        if(l == null)
+            return;
+
+        viewpointStatusListeners.remove(l);
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by VRMLBindableNodeListener
+    //----------------------------------------------------------
+
+    /**
+     * Notification that a binding stack has requested that this node be now
+     * bound as the active node.
+     *
+     * @param node The source node that is to be bound
+     */
+    @Override
+    public void newNodeBound(VRMLBindableNodeType node) {
+        if(node instanceof OGLViewpointNodeType) {
+            OGLViewpointNodeType vp = (OGLViewpointNodeType)node;
+
+            changeViewpoints(vp);
+
+            int size = viewpointStatusListeners.size();
+
+            for(int i = 0; i < size; i++) {
+                try {
+                    ViewpointStatusListener l = viewpointStatusListeners.get(i);
+
+                    l.viewpointBound(vp, layerId);
+                } catch(Exception e) {
+                    errorReporter.warningReport(VP_BOUND_ERR, e);
+                }
+            }
+        } else {
+            VRMLNavigationInfoNodeType nav =
+                (VRMLNavigationInfoNodeType)node;
+
+            if(currentNavInfo != null)
+                currentNavInfo.removeNavigationChangedListener(this);
+
+            currentNavInfo = nav;
+            currentNavInfo.addNavigationChangedListener(this);
+            globalEffects.useHeadlight(currentNavInfo.getHeadlight());
+        }
+    }
+
+    /**
+     * Notification that a new bindable has been added.
+     *
+     * @param node The new node
+     * @param isDefault True if this is a default node instance
+     */
+    @Override
+    public void bindableAdded(VRMLBindableNodeType node, boolean isDefault) {
+        if(!(node instanceof OGLViewpointNodeType))
+            return;
+
+        int size = viewpointStatusListeners.size();
+
+        for(int i = 0; i < size; i++) {
+            try {
+                ViewpointStatusListener l = viewpointStatusListeners.get(i);
+
+                l.viewpointAdded((VRMLViewpointNodeType)node,
+                                 layerId,
+                                 isDefault);
+            } catch(Exception e) {
+                errorReporter.warningReport(VP_ADD_ERR, e);
+            }
+        }
+    }
+
+    /**
+     * Notification that a bindable has been removed.
+     *
+     * @param node The node
+     */
+    @Override
+    public void bindableRemoved(VRMLBindableNodeType node) {
+        if(!(node instanceof OGLViewpointNodeType))
+            return;
+
+        int size = viewpointStatusListeners.size();
+
+        for(int i = 0; i < size; i++) {
+            try {
+                ViewpointStatusListener l = viewpointStatusListeners.get(i);
+
+                l.viewpointRemoved((VRMLViewpointNodeType)node, layerId);
+            } catch(Exception e) {
+                errorReporter.warningReport(VP_REMOVE_ERR, e);
+            }
+        }
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by NavigationInfoChangeListener
+    //----------------------------------------------------------
+
+    /**
+     * Notification that the navigation modes allowed has changed
+     * on the current NavigationInfo node.
+     *
+     * @param newModes The new allowed navigation modes
+     * @param numModes number of valid modes in array
+     */
+    @Override
+    public void notifyNavigationModesChanged(String[] newModes, int numModes) {
+        // Ignored by this class.
+    }
+
+    /**
+     * Notification that the avatar size has changed
+     * on the current NavigationInfo node.
+     *
+     * @param size The size parameters for the avatar
+     * @param dimensions The number of valid avatar dimensions
+     */
+    @Override
+    public void notifyAvatarSizeChanged(float[] size, int dimensions) {
+        // Ignored by this class.
+    }
+
+    /**
+     * Notification that the navigation speed has changed on the
+     * current NavigationInfo node.
+     *
+     * @param newSpeed The new navigation speed.
+     */
+    @Override
+    public void notifyNavigationSpeedChanged(float newSpeed) {
+        // Ignored by this class.
+    }
+
+    /**
+     * Notification that the visibility limit has been changed.
+     *
+     * @param distance The new distance value to use
+     */
+    @Override
+    public void notifyVisibilityLimitChanged(float distance) {
+        // Ignored by this class.
+    }
+
+    /**
+     * Notification that headlight state has changed.
+     *
+     * @param enable true if the headlight should now be on
+     */
+    @Override
+    public void notifyHeadlightChanged(boolean enable) {
+        globalEffects.useHeadlight(enable);
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by OGLTransformNodeType
+    //----------------------------------------------------------
+
+    /**
+     * Get the transform matrix for this node.  A reference is ok as
+     * the users of this method will not modify the matrix.
+     *
+     * @return The matrix.
+     */
+    @Override
+    public Matrix4f getTransform() {
+        return worldScaleMatrix;
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by NodeUpdateListener
+    //----------------------------------------------------------
+
+    /**
+     * Notification that its safe to update the node now with any operations
+     * that could potentially effect the node's bounds.
+     *
+     * @param src The node or Node Component that is to be updated.
+     */
+    @Override
+    public void updateNodeBoundsChanges(Object src) {
+
+        if(src == sgTransformGroup) {
+            sgTransformGroup.setTransform(worldScaleMatrix);
+
+            if(pendingWorldGeom != null) {
+                sgTransformGroup.setChild(pendingWorldGeom, 1);
+                worldRoot = pendingWorldGeom;
+                pendingWorldGeom = null;
+                clearAllContent = false;
+            } else if(clearAllContent) {
+                sgTransformGroup.setChild(null, 0);
+                sgTransformGroup.setChild(null, 1);
+                clearAllContent = false;
+            }
+
+            if(updateBindables) {
+                sgTransformGroup.setChild(pendingBindables, 0);
+                pendingBindables = null;
+                updateBindables = false;
+            }
+
+            userInput.setPickableScene(sgTransformGroup);
+            layerSensorManager.setWorldRoot(sgTransformGroup);
+
+// TODO: I expect this had some interaction with animated viewpoints but its causing timing issues
+/*
+            SceneGraphPath path = generatePath(vpTransformGroup);
+
+            userInput.setViewInfo(currentViewpoint,
+                                  vpTransformGroup,
+                                  path);
+*/
+        } else if (worldGroup == src) {
+			// rem:
+			// this would be a shutdown, clear out all geometry
+			// so the resources are eligible for deletion in the
+			// scene graph
+			worldGroup.removeAllChildren();
+
+		} else if(vpTransformGroup == src) {
+            vpTransformGroup.setTransform(vpMatrix);
+
+// TODO: I expect this had some interaction with animated viewpoints but its causing timing issues
+/*
+            SceneGraphPath path = generatePath(vpTransformGroup);
+
+            userInput.setViewInfo(currentViewpoint,
+                                  vpTransformGroup,
+                                  path);
+*/
+        } else {
+            ((Group)src).removeAllChildren();
+        }
+    }
+
+    /**
+     * Notification that its safe to update the node now with any operations
+     * that only change the node's properties, but do not change the bounds.
+     *
+     * @param src The node or Node Component that is to be updated.
+     */
+    @Override
+    public void updateNodeDataChanges(Object src) {
+        if (src == simpleViewport) {
+           simpleViewport.makeActiveSoundLayer();
+        }
+    }
+
+    //----------------------------------------------------------
+    // LayerListener methods
+    //----------------------------------------------------------
+
+    /**
+     * The pickable status of the layer has changed.
+     *
+     * @param pickable Is this layer pickable
+     */
+    @Override
+    public void pickableStateChanged(boolean pickable) {
+        layerSensorManager.setIsPickable(pickable);
+    }
+
+    //----------------------------------------------------------
+    // Local Methods
+    //----------------------------------------------------------
+
+    void setViewpointResizeManager(ViewpointResizeManager vrm) {
+        viewpointResizeManager = vrm;
+    }
+
+    /**
+     * Get the viewport layer that this layer manager works with.
+     *
+     * @return The AV3D layer representation used
+     */
+    SimpleLayer getLayer() {
+        return implLayer;
+    }
+
+    /**
+     * Convenience method to do the transition between the current viewpoint
+     * and the newly given one. Will jump or smooth transition depending on
+     * the new viewpoint requirements.
+     *
+     * @param inSetup true if this is the setup (initialBind) process
+     */
+    private void changeViewpoints(OGLViewpointNodeType vp) {
+        if(vp.getJump()) {
+            if (viewpointResizeManager != null)
+                viewpointResizeManager.removeViewpoint(currentViewpoint);
+
+            currentViewpoint = vp;
+
+            if (viewpointResizeManager != null)
+                viewpointResizeManager.addViewpoint(currentViewpoint, viewEnvironment);
+
+            // Always reset the viewpoint to the default position as we might
+            // be re-binding the same viewpoint, which is supposed to place it
+            // back in it's original spot.
+            vpTransformGroup = currentViewpoint.getPlatformGroup();
+            vpMatrix = currentViewpoint.getViewTransform();
+
+            SceneGraphPath path = generatePath(vpTransformGroup);
+
+            userInput.setViewInfo(currentViewpoint,
+                                  vpTransformGroup,
+                                  path);
+
+            if(vpTransformGroup.isLive())
+                vpTransformGroup.boundsChanged(this);
+            else
+                vpTransformGroup.setTransform(vpMatrix);
+
+            switch(currentViewpoint.getProjectionType()) {
+                case VRMLViewpointNodeType.PROJECTION_PERSPECTIVE:
+                    projectionType = ViewEnvironment.PERSPECTIVE_PROJECTION;
+
+                    break;
+
+                case VRMLViewpointNodeType.PROJECTION_ORTHO:
+                    projectionType = ViewEnvironment.ORTHOGRAPHIC_PROJECTION;
+                    break;
+
+                default:
+                    errorReporter.warningReport(UNKNOWN_PROJ_TYPE_MSG, null);
+                    projectionType = ViewEnvironment.PERSPECTIVE_PROJECTION;
+            }
+
+            viewEnvironment.setProjectionType(projectionType);
+
+        } else {
+
+System.out.println("non-jump transistions not handled yet");
+            // Copied code from jump section
+            if (viewpointResizeManager != null)
+                viewpointResizeManager.removeViewpoint(currentViewpoint);
+
+            currentViewpoint = vp;
+
+            if (viewpointResizeManager != null)
+                viewpointResizeManager.addViewpoint(currentViewpoint, viewEnvironment);
+
+            // Always reset the viewpoint to the default position as we might
+            // be re-binding the same viewpoint, which is supposed to place it
+            // back in it's original spot.
+            vpTransformGroup = currentViewpoint.getPlatformGroup();
+            vpMatrix = currentViewpoint.getViewTransform();
+
+            SceneGraphPath path = generatePath(vpTransformGroup);
+
+            userInput.setViewInfo(currentViewpoint,
+                                  vpTransformGroup,
+                                  path);
+
+            if(vpTransformGroup.isLive())
+                vpTransformGroup.boundsChanged(this);
+            else
+                vpTransformGroup.setTransform(vpMatrix);
+
+            switch(currentViewpoint.getProjectionType()) {
+                case VRMLViewpointNodeType.PROJECTION_PERSPECTIVE:
+                    projectionType = ViewEnvironment.PERSPECTIVE_PROJECTION;
+                    break;
+
+                case VRMLViewpointNodeType.PROJECTION_ORTHO:
+                    projectionType = ViewEnvironment.ORTHOGRAPHIC_PROJECTION;
+                    break;
+
+                default:
+                    errorReporter.warningReport(UNKNOWN_PROJ_TYPE_MSG, null);
+                    projectionType = ViewEnvironment.PERSPECTIVE_PROJECTION;
+            }
+
+            viewEnvironment.setProjectionType(projectionType);
+
+            // End copied code
+/*
+            // We have to do a smooth transition between the points
+            TransformGroup old_tg = currentViewpoint.getPlatformGroup();
+            TransformGroup new_tg = vp.getPlatformGroup();
+
+            oldTx.setIdentity();
+            destTx.setIdentity();
+            Matrix4f final_tx = vp.getViewTransform();
+
+            getLocalToVworld(old_tg, oldTx);
+            getLocalToVworld(new_tg, destTx);
+
+            // To work out the transition, the transform group of the dest
+            // viewpoint must be set to exactly the virtual world position of
+            // the old viewpoint and then allowed to transition across to the
+            // final destination. However, we must allow for the differences
+            // in their parent transforms first and make sure we have a proper
+            // scale value.
+
+            Vector3f old_trans = new Vector3f();
+            Vector3f dest_trans = new Vector3f();
+            Vector3f new_trans = new Vector3f();
+            Quat4f old_orient = new Quat4f();
+            Quat4f dest_orient = new Quat4f();
+            Quat4f new_orient = new Quat4f();
+
+            dest_orient.set(destTx);
+            old_orient.set(oldTx);
+
+
+            destTx.get(dest_orient);
+            destTx.get(dest_trans);
+            oldTx.get(old_orient);
+            oldTx.get(old_trans);
+
+            new_trans.sub(dest_trans, old_trans);
+            new_orient.sub(dest_orient, old_orient);
+
+            Matrix4f new_tx = new Matrix4f();
+            new_tx.set(new_orient, new_trans, 1);
+            new_tx.set(new_trans);
+
+            vpTransformGroup = new_tg;
+
+            vpMatrix = new_tx;
+            new_tg.boundsChanged(this);
+
+            currentViewpoint = vp;
+
+            if(hardwareFOV != 0f)
+                viewEnvironment.setFieldOfView(hardwareFOV);
+            else
+                viewEnvironment.setFieldOfView(currentViewpoint.getFieldOfView()  *
+                                               DEG_TO_RAD);
+*/
+        }
+
+        if(currentNavInfo != null)
+            globalEffects.useHeadlight(currentNavInfo.getHeadlight());
+    }
+
+    /**
+     * From the given node, create a scene graph path to the root. Used
+     * to make the path for the view handling. If a shared group is
+     * encountered, just take the first parent all the time
+     *
+     * @param leaf The terminal node of the path
+     * @return A path from here to the root
+     */
+    private SceneGraphPath generatePath(Node leaf) {
+
+        Node parent = leaf.getParent();
+        pathList.clear();
+
+        if(parent == null)
+            return null;
+
+        while(parent != null) {
+            if(parent instanceof SharedGroup) {
+                SharedGroup sg = (SharedGroup)parent;
+
+                if(sg.numParents() == 0)
+                    break;
+
+                sg.getParents(pathNodes);
+                parent = pathNodes[0];
+                pathList.add(parent);
+            } else {
+                pathList.add(parent);
+                parent = parent.getParent();
+            }
+        }
+
+        // Invert the array while copying it into the path.
+        pathMatrix.setIdentity();
+        int size =  pathList.size();
+
+        if(pathNodes.length < size)
+            pathNodes = new Node[size];
+
+        for(int i = 0; i < size; i++)
+            pathNodes[i] = pathList.get(size - i - 1);
+
+        return new SceneGraphPath(pathNodes, size, pathMatrix, pathMatrix);
+    }
+
+    /**
+     * Convenience method to walk to the root of the scene and calculate the
+     * root to virtual world coordinate location of the given node. If a
+     * sharedGroup is found, then take the first parent listed always.
+     *
+     * @param terminal The end node to calculate from
+     * @param mat The matrix to put the final result into
+     */
+    private void getLocalToVworld(Node terminal, Matrix4f mat) {
+
+        Node parent = terminal.getParent();
+        pathList.clear();
+
+        if(parent instanceof TransformGroup)
+            pathList.add(parent);
+
+        while(parent != null) {
+            if(parent instanceof SharedGroup) {
+                SharedGroup sg = (SharedGroup)parent;
+
+                int num_parents = sg.numParents();
+
+                if(num_parents == 0)
+                    break;
+                else if(num_parents > pathNodes.length)
+                    pathNodes = new Node[num_parents];
+
+                sg.getParents(pathNodes);
+                parent = pathNodes[0];
+            } else {
+                if(parent instanceof TransformGroup)
+                    pathList.add(parent);
+
+                parent = parent.getParent();
+            }
+        }
+
+        int num_nodes = pathList.size();
+        mat.setIdentity();
+        pathMatrix.setIdentity();
+
+        // use vwTransform for fetching the tx. It is only a temp var anyway
+        for(int i = num_nodes - 1; i >= 0; i--) {
+            TransformGroup tg = (TransformGroup)pathList.get(i);
+            tg.getTransform(pathMatrix);
+
+            mat.mul(pathMatrix);
+        }
+    }
+
+    /**
+     * Create the default bindables and add them to the scene of the given
+     * spec version.
+     *
+     * @param major The spec major version number
+     * @param minor The spec minor version number
+     */
+    private void createDefaultBindables(int major, int minor) {
+        VRMLNodeFactory fac =
+            DefaultNodeFactory.createFactory(
+                DefaultNodeFactory.OPENGL_RENDERER
+            );
+
+        fac.setSpecVersion(major, minor);
+
+        defaultViewpoint =
+            (OGLViewpointNodeType)fac.createVRMLNode(NAV_COMPONENT,
+                                                     "Viewpoint",
+                                                     false);
+
+        defaultViewpoint.setDescription("Default viewpoint");
+        defaultViewpoint.setupFinished();
+
+        defaultNavInfo =
+            (VRMLNavigationInfoNodeType)fac.createVRMLNode(NAV_COMPONENT,
+                                                           "NavigationInfo",
+                                                            false);
+        defaultNavInfo.setupFinished();
+
+        defaultBackground =
+            (VRMLBackgroundNodeType)fac.createVRMLNode(ENV_COMPONENT,
+                                                       "Background",
+                                                       false);
+        defaultBackground.setupFinished();
+
+        defaultFog =
+            (VRMLFogNodeType)fac.createVRMLNode(ENV_COMPONENT, "Fog", false);
+        defaultFog.setFogType(VRMLFogNodeType.FOG_TYPE_DISABLE);
+        defaultFog.setupFinished();
+
+        // Fill in the geometry of the default viewpoints.
+        Node vp_node = (Node)defaultViewpoint.getSceneGraphObject();
+        Node bg_node = (Node)((OGLVRMLNode)defaultBackground).getSceneGraphObject();
+        Node fog_node = (Node)((OGLVRMLNode)defaultFog).getSceneGraphObject();
+
+        Group grp = new Group();
+        grp.addChild(vp_node);
+        grp.addChild(bg_node);
+        grp.addChild(fog_node);
+
+        pendingBindables = grp;
+        updateBindables = true;
+
+        if(sgTransformGroup.isLive())
+            sgTransformGroup.boundsChanged(this);
+        else
+            updateNodeBoundsChanges(sgTransformGroup);
+    }
+}
diff --git a/src/java/org/web3d/vrml/renderer/ogl/browser/OGLRenderingEffects.java b/src/java/org/web3d/vrml/renderer/ogl/browser/OGLRenderingEffects.java
index 6ffa323d277f46d9300929610849dd24ae0e036d..315ccc6b1796e07a48091e57fcec5832bfd1d780 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/browser/OGLRenderingEffects.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/browser/OGLRenderingEffects.java
@@ -32,6 +32,7 @@ import org.xj3d.sai.Xj3DBrowser;
 
 /**
  * Pre and post frame rendering effects processing for any OpenGL renderer.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.8 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/browser/OGLStandardBrowserCore.java b/src/java/org/web3d/vrml/renderer/ogl/browser/OGLStandardBrowserCore.java
index 602359d6218da2cf71c20fed4472584e6d61f88c..2c8d776408692f100a1b1135b8ad0adb97c6a855 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/browser/OGLStandardBrowserCore.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/browser/OGLStandardBrowserCore.java
@@ -15,29 +15,34 @@ package org.web3d.vrml.renderer.ogl.browser;
 // External imports
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+
 import java.util.*;
-import javax.vecmath.AxisAngle4f;
+
 import javax.vecmath.Vector3f;
+import javax.vecmath.AxisAngle4f;
+
 import org.j3d.aviatrix3d.*;
-import org.j3d.aviatrix3d.management.DisplayCollection;
 import org.j3d.aviatrix3d.management.RenderManager;
+import org.j3d.aviatrix3d.management.DisplayCollection;
 import org.j3d.aviatrix3d.pipeline.graphics.GraphicsResizeListener;
 import org.j3d.util.DefaultErrorReporter;
 import org.j3d.util.ErrorReporter;
+
+// Local imports
 import org.web3d.browser.*;
+
 import org.web3d.vrml.lang.*;
 import org.web3d.vrml.nodes.*;
 import org.web3d.vrml.util.URLChecker;
+
 import org.xj3d.core.eventmodel.EventModelEvaluator;
 import org.xj3d.core.eventmodel.EventModelInitListener;
 import org.xj3d.core.eventmodel.LayerManager;
 import org.xj3d.core.eventmodel.LayerRenderingManager;
 
 /**
- * <p>
  * Representation of a core of a browser implemented using the OpenGL
  * rendering APIs.
- * </p>
  * <p>
  * The universe is responsible for handling the management of the viewpoints
  * within a scene. VRML defines a single viewpoint model for multiple canvases.
@@ -47,11 +52,10 @@ import org.xj3d.core.eventmodel.LayerRenderingManager;
  * editor environment, this universe is not suitable as it uses a single
  * View object and attaches all canvases to that view and hence the underlying
  * currently bound viewpoint.
- * </p>
  * <p>
  * The universe is not responsible for loading VRML/X3D content. To handle
  * anchors, it delegates to the supplied listener.
- * </p>
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.36 $
@@ -310,16 +314,14 @@ public class OGLStandardBrowserCore
         }
 
         currentScene = nextScene;
-        if (currentScene != null)
-        {
-            defMap = currentScene.getDEFNodes(); // <- something like this was missing
-                                                // causing the parsetest/eai stuff
-                                                 // from working. Found solution from
-                                                 // org.xj3d.loaders.ogl.StaticBrowserCore 
-                                                 // 26 FEB 2020 (TDN)
+        defMap = currentScene.getDEFNodes(); // <- something like this was missing
+                                             // causing the parsetest/eai stuff
+                                             // from working. Found solution from
+                                             // org.xj3d.loaders.ogl.StaticBrowserCore 
+                                             // 26 FEB 2020 (TDN)
 
+        if (currentScene != null)
             currentSpace = (VRMLExecutionSpace)currentScene.getRootNode();
-        }
         nextScene = null;
     }
 
diff --git a/src/java/org/web3d/vrml/renderer/ogl/input/CollisionListener.java b/src/java/org/web3d/vrml/renderer/ogl/input/CollisionListener.java
index 83822a6e231e6b489c3ac26b67b259c075c7f555..54a4b2782887cdd04c90c3ca8a1b440b3c5ac24a 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/input/CollisionListener.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/input/CollisionListener.java
@@ -21,6 +21,7 @@ import org.j3d.aviatrix3d.SceneGraphPath;
 /**
  * A listener interface used to notify of a collision between the user position
  * and geometry in the scene.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/input/Xj3DNavigationState.java b/src/java/org/web3d/vrml/renderer/ogl/input/Xj3DNavigationState.java
index 6050c59b397a47c5cb3e59b27d239b19870d1643..9de75f674f908c110054531ce0c122b96ae54563 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/input/Xj3DNavigationState.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/input/Xj3DNavigationState.java
@@ -20,6 +20,7 @@ package org.web3d.vrml.renderer.ogl.input;
 
 /**
  * A collection of navigation state information constants.
+ * <p>
  *
  * @author Rex Melton
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLBackgroundNodeType.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLBackgroundNodeType.java
index fdfc243d0aeab6db4a14c02fdafa76f80c6bbef1..f91d7d436417ff51ab65f6f65a3bd1c7771483d8 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLBackgroundNodeType.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLBackgroundNodeType.java
@@ -22,6 +22,8 @@ import org.web3d.vrml.nodes.VRMLBackgroundNodeType;
 /**
  * An abstract representation of any background node for use in the OpenGL
  * renderer.
+ * <p>
+ *
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLLightNodeType.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLLightNodeType.java
index b7e1821473bbdaa5ea893526ffd1a952a174a912..cb5657fe1f5a70aaa0772aa8c9fbf8f7f990e834 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLLightNodeType.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLLightNodeType.java
@@ -21,6 +21,7 @@ import org.web3d.vrml.nodes.VRMLLightNodeType;
 /**
  * An abstract representation of any form of light node in the OpenGL
  * scene graph.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLNavigationInfoNodeType.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLNavigationInfoNodeType.java
index f18edaca7e2b4d9662f4688f5e441368fd1d7b81..b9547686cae9b1dfcf4751f669a293666b1f8696 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLNavigationInfoNodeType.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLNavigationInfoNodeType.java
@@ -20,6 +20,8 @@ import org.web3d.vrml.nodes.VRMLNavigationInfoNodeType;
 
 /**
  * Java3D specific representation of a navigation info node.
+ * <p>
+ *
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLPickingSensorNodeType.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLPickingSensorNodeType.java
index acaabe61cef4e4d6ac93723e8a4b51da8f1c1ec0..77e41830384a8a123c537ab2ef54ccf4e5b0594a 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLPickingSensorNodeType.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLPickingSensorNodeType.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.nodes.VRMLPickingSensorNodeType;
 
 /**
  * OpenGL abstract representation of a picking sensor node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLTextureConstConverter.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLTextureConstConverter.java
index b893863154dfa9586093a39c7470170e7f545e6b..4a4ccbac4907c4376364a01bce4d701fdf9d4739 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLTextureConstConverter.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLTextureConstConverter.java
@@ -1,188 +1,189 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2003
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.renderer.ogl.nodes;
-
-// Standard imports
-import org.j3d.aviatrix3d.Texture;
-import org.j3d.aviatrix3d.TextureAttributes;
-
-// Application specific imports
-import org.web3d.vrml.lang.TextureConstants;
-
-/**
- * OpenGL mapping from TextureConstants to renderer specific constants.
- *
- * @author Alan Hudson
- * @version $Revision: 1.3 $
- */
-public class OGLTextureConstConverter {
-    /**
-     * Convert mode constants.
-     *
-     * @param tc The TextureConst to convert
-     * @return The J3D specific value.
-     */
-    public static int convertMode(int tc) {
-        int m=0;
-        switch(tc) {
-            case TextureConstants.MODE_REPLACE:
-                m = TextureAttributes.MODE_REPLACE;
-                break;
-            case TextureConstants.MODE_MODULATE:
-                m = TextureAttributes.MODE_MODULATE;
-                break;
-            default:
-                System.err.println("Unknown TextureConstants.Mode: " + tc);
-        }
-
-        return m;
-    }
-
-    /**
-     * Convert source constants.
-     *
-     * @param tc The TextureConst to convert
-     * @return The J3D specific value.
-     */
-    public static int convertSource(int tc) {
-        return 0;
-    }
-
-    /**
-     * Convert Boundary Mode constants.
-     *
-     * @param tc The TextureConst to convert
-     * @return The J3D specific value.
-     */
-    public static int convertBoundary(int tc) {
-        int bm=0;
-
-        switch(tc) {
-            case TextureConstants.BM_WRAP:
-                bm = Texture.BM_WRAP;
-                break;
-            case TextureConstants.BM_CLAMP:
-                bm = Texture.BM_CLAMP;
-                break;
-            case TextureConstants.BM_CLAMP_EDGE:
-                bm = Texture.BM_CLAMP_TO_EDGE;
-                break;
-            case TextureConstants.BM_CLAMP_BOUNDARY:
-                bm = Texture.BM_CLAMP_TO_BOUNDARY;
-                break;
-            case TextureConstants.BM_MIRRORED_REPEAT:
-                bm = Texture.BM_MIRRORED_REPEAT;
-                break;
-            default:
-                System.err.println("Unknown TextureConstants.boundaryMode: " + tc);
-        }
-
-        return bm;
-    }
-
-    /**
-     * Convert MagFilter constants.
-     *
-     * @param tc The TextureConst to convert
-     * @return The J3D specific value.
-     */
-    public static int convertMagFilter(int tc) {
-        int mfm=0;
-
-        switch(tc) {
-            case TextureConstants.MAGFILTER_FASTEST:
-                mfm = Texture.MAGFILTER_FASTEST;
-                break;
-            case TextureConstants.MAGFILTER_NICEST:
-                mfm = Texture.MAGFILTER_NICEST;
-                break;
-            case TextureConstants.MAGFILTER_BASE_LEVEL_POINT:
-                mfm = Texture.MAGFILTER_BASE_LEVEL_POINT;
-                break;
-            case TextureConstants.MAGFILTER_BASE_LEVEL_LINEAR:
-                mfm = Texture.MAGFILTER_BASE_LEVEL_LINEAR;
-                break;
-/*
-            case TextureConstants.MAGFILTER_LINEAR_DETAIL:
-                mfm = Texture2D.LINEAR_DETAIL;
-                break;
-            case TextureConstants.MAGFILTER_LINEAR_DETAIL_RGB:
-                mfm = Texture2D.LINEAR_DETAIL_RGB;
-                break;
-            case TextureConstants.MAGFILTER_LINEAR_DETAIL_ALPHA:
-                mfm = Texture2D.LINEAR_DETAIL_ALPHA;
-                break;
-*/
-            default:
-               System.err.println("Unknown TextureConstants.MagFilter" + tc);
-        }
-
-        return mfm;
-    }
-
-    /**
-     * Convert MinFilter constants.
-     *
-     * @param tc The TextureConst to convert
-     * @return The J3D specific value.
-     */
-    public static int convertMinFilter(int tc) {
-        int mfm=0;
-
-        switch(tc) {
-            case TextureConstants.MINFILTER_FASTEST:
-                mfm = Texture.MINFILTER_FASTEST;
-                break;
-            case TextureConstants.MINFILTER_NICEST:
-                mfm = Texture.MINFILTER_NICEST;
-                break;
-            case TextureConstants.MINFILTER_BASE_LEVEL_POINT:
-                mfm = Texture.MINFILTER_BASE_LEVEL_POINT;
-                break;
-            case TextureConstants.MINFILTER_BASE_LEVEL_LINEAR:
-                mfm = Texture.MINFILTER_BASE_LEVEL_LINEAR;
-                break;
-            case TextureConstants.MINFILTER_MULTI_LEVEL_POINT:
-                mfm = Texture.MINFILTER_MULTI_LEVEL_POINT;
-                break;
-            case TextureConstants.MINFILTER_MULTI_LEVEL_LINEAR:
-                mfm = Texture.MINFILTER_MULTI_LEVEL_LINEAR;
-                break;
-            default:
-               System.err.println("Unknown TextureConstants.MinFilter" + tc);
-        }
-
-        return mfm;
-    }
-
-    /**
-     * Convert Anisotropic Mode constants.
-     *
-     * @param tc The TextureConst to convert
-     * @return The J3D specific value.
-     */
-    public static int convertAnisotropicMode(int tc) {
-        int am=0;
-        switch(tc) {
-            case TextureConstants.ANISOTROPIC_MODE_SINGLE:
-                am = Texture.ANISOTROPIC_MODE_SINGLE;
-                break;
-            case TextureConstants.ANISOTROPIC_MODE_NONE:
-                am = Texture.ANISOTROPIC_MODE_NONE;
-                break;
-            default:
-               System.err.println("Unknown TextureConstants.Anisotropic Mode: " + tc);
-        }
-        return am;
-    }
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2003
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.renderer.ogl.nodes;
+
+// Standard imports
+import org.j3d.aviatrix3d.Texture;
+import org.j3d.aviatrix3d.TextureAttributes;
+
+// Application specific imports
+import org.web3d.vrml.lang.TextureConstants;
+
+/**
+ * OpenGL mapping from TextureConstants to renderer specific constants.
+ * <p>
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.3 $
+ */
+public class OGLTextureConstConverter {
+    /**
+     * Convert mode constants.
+     *
+     * @param tc The TextureConst to convert
+     * @return The J3D specific value.
+     */
+    public static int convertMode(int tc) {
+        int m=0;
+        switch(tc) {
+            case TextureConstants.MODE_REPLACE:
+                m = TextureAttributes.MODE_REPLACE;
+                break;
+            case TextureConstants.MODE_MODULATE:
+                m = TextureAttributes.MODE_MODULATE;
+                break;
+            default:
+                System.err.println("Unknown TextureConstants.Mode: " + tc);
+        }
+
+        return m;
+    }
+
+    /**
+     * Convert source constants.
+     *
+     * @param tc The TextureConst to convert
+     * @return The J3D specific value.
+     */
+    public static int convertSource(int tc) {
+        return 0;
+    }
+
+    /**
+     * Convert Boundary Mode constants.
+     *
+     * @param tc The TextureConst to convert
+     * @return The J3D specific value.
+     */
+    public static int convertBoundary(int tc) {
+        int bm=0;
+
+        switch(tc) {
+            case TextureConstants.BM_WRAP:
+                bm = Texture.BM_WRAP;
+                break;
+            case TextureConstants.BM_CLAMP:
+                bm = Texture.BM_CLAMP;
+                break;
+            case TextureConstants.BM_CLAMP_EDGE:
+                bm = Texture.BM_CLAMP_TO_EDGE;
+                break;
+            case TextureConstants.BM_CLAMP_BOUNDARY:
+                bm = Texture.BM_CLAMP_TO_BOUNDARY;
+                break;
+            case TextureConstants.BM_MIRRORED_REPEAT:
+                bm = Texture.BM_MIRRORED_REPEAT;
+                break;
+            default:
+                System.err.println("Unknown TextureConstants.boundaryMode: " + tc);
+        }
+
+        return bm;
+    }
+
+    /**
+     * Convert MagFilter constants.
+     *
+     * @param tc The TextureConst to convert
+     * @return The J3D specific value.
+     */
+    public static int convertMagFilter(int tc) {
+        int mfm=0;
+
+        switch(tc) {
+            case TextureConstants.MAGFILTER_FASTEST:
+                mfm = Texture.MAGFILTER_FASTEST;
+                break;
+            case TextureConstants.MAGFILTER_NICEST:
+                mfm = Texture.MAGFILTER_NICEST;
+                break;
+            case TextureConstants.MAGFILTER_BASE_LEVEL_POINT:
+                mfm = Texture.MAGFILTER_BASE_LEVEL_POINT;
+                break;
+            case TextureConstants.MAGFILTER_BASE_LEVEL_LINEAR:
+                mfm = Texture.MAGFILTER_BASE_LEVEL_LINEAR;
+                break;
+/*
+            case TextureConstants.MAGFILTER_LINEAR_DETAIL:
+                mfm = Texture2D.LINEAR_DETAIL;
+                break;
+            case TextureConstants.MAGFILTER_LINEAR_DETAIL_RGB:
+                mfm = Texture2D.LINEAR_DETAIL_RGB;
+                break;
+            case TextureConstants.MAGFILTER_LINEAR_DETAIL_ALPHA:
+                mfm = Texture2D.LINEAR_DETAIL_ALPHA;
+                break;
+*/
+            default:
+               System.err.println("Unknown TextureConstants.MagFilter" + tc);
+        }
+
+        return mfm;
+    }
+
+    /**
+     * Convert MinFilter constants.
+     *
+     * @param tc The TextureConst to convert
+     * @return The J3D specific value.
+     */
+    public static int convertMinFilter(int tc) {
+        int mfm=0;
+
+        switch(tc) {
+            case TextureConstants.MINFILTER_FASTEST:
+                mfm = Texture.MINFILTER_FASTEST;
+                break;
+            case TextureConstants.MINFILTER_NICEST:
+                mfm = Texture.MINFILTER_NICEST;
+                break;
+            case TextureConstants.MINFILTER_BASE_LEVEL_POINT:
+                mfm = Texture.MINFILTER_BASE_LEVEL_POINT;
+                break;
+            case TextureConstants.MINFILTER_BASE_LEVEL_LINEAR:
+                mfm = Texture.MINFILTER_BASE_LEVEL_LINEAR;
+                break;
+            case TextureConstants.MINFILTER_MULTI_LEVEL_POINT:
+                mfm = Texture.MINFILTER_MULTI_LEVEL_POINT;
+                break;
+            case TextureConstants.MINFILTER_MULTI_LEVEL_LINEAR:
+                mfm = Texture.MINFILTER_MULTI_LEVEL_LINEAR;
+                break;
+            default:
+               System.err.println("Unknown TextureConstants.MinFilter" + tc);
+        }
+
+        return mfm;
+    }
+
+    /**
+     * Convert Anisotropic Mode constants.
+     *
+     * @param tc The TextureConst to convert
+     * @return The J3D specific value.
+     */
+    public static int convertAnisotropicMode(int tc) {
+        int am=0;
+        switch(tc) {
+            case TextureConstants.ANISOTROPIC_MODE_SINGLE:
+                am = Texture.ANISOTROPIC_MODE_SINGLE;
+                break;
+            case TextureConstants.ANISOTROPIC_MODE_NONE:
+                am = Texture.ANISOTROPIC_MODE_NONE;
+                break;
+            default:
+               System.err.println("Unknown TextureConstants.Anisotropic Mode: " + tc);
+        }
+        return am;
+    }
 }
\ No newline at end of file
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLTransformNodeType.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLTransformNodeType.java
index 9707fd68dd4d21a5e27c0dc20cfaa3a451d7f3ff..d22fe0f4aebcc94cd8b9240dbb2a66f816a26233 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLTransformNodeType.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLTransformNodeType.java
@@ -20,6 +20,7 @@ import javax.vecmath.Matrix4f;
 /**
  * This node contains an aviatrix TransformGroup.  All OGL nodes which
  * have their impls under a TransformGroup must implement this interface.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLVRMLNode.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLVRMLNode.java
index 0ab99989e73eaee559075a06232a391060683e7c..96d99b63ee6dfee35e404809a81dd8d7f6fcd2e7 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLVRMLNode.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLVRMLNode.java
@@ -21,6 +21,7 @@ import org.web3d.vrml.nodes.VRMLNodeType;
 /**
  * Representation of the basic VRMLNodeType specific to the OpenGL render
  * rendering system.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLViewpointNodeType.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLViewpointNodeType.java
index 596f3e9ccb37f493cc51a2d6682626ee88d2c857..a690e2b3ab0870a6bfabb84d6dcf9d24734b22be 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLViewpointNodeType.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/OGLViewpointNodeType.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.nodes.VRMLViewpointNodeType;
 
 /**
  * Shell representation of a viewpoint node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.8 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/TextureCache.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/TextureCache.java
index 337be2af64c1944b87a249f4ab06d4cdf2dc2a2e..6be84944a494f94ef5e58963a1b8d67c5a7316e2 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/TextureCache.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/TextureCache.java
@@ -30,6 +30,7 @@ import org.j3d.aviatrix3d.Texture3D;
 /**
  * A cache for Texture instance management where the objects stay according
  * to Java's WeakReference system.
+ * <p>
  *
  * @author Rex Melton
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/cadgeometry/OGLCADAssembly.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/cadgeometry/OGLCADAssembly.java
index fd8c147652e9705524ca81d2e180ce688311eaaa..c50bc75436f5ca7a1e28d88d9aed4ab9f263e62d 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/cadgeometry/OGLCADAssembly.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/cadgeometry/OGLCADAssembly.java
@@ -38,7 +38,8 @@ import org.web3d.vrml.renderer.common.nodes.cadgeometry.BaseCADAssembly;
 
 /**
  * OpenGL implementation of a group node.
- * 
+ * <p>
+ *
  * @author Alan Hudson
  * @version $Revision: 1.4 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/cadgeometry/OGLCADFace.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/cadgeometry/OGLCADFace.java
index 0dd99475824d1d5e9a0d700227aa92719ed1cf5a..c277f548c2f555062a3df8e38314262d4866703b 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/cadgeometry/OGLCADFace.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/cadgeometry/OGLCADFace.java
@@ -33,6 +33,7 @@ import org.web3d.vrml.renderer.common.nodes.cadgeometry.BaseCADFace;
 
 /**
  * OpenGL implementation of a group node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/cadgeometry/OGLCADLayer.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/cadgeometry/OGLCADLayer.java
index f83a12e9e63ecefc9fc42f230f54bfcfe9fd7bf8..21aad8f13f1302789ed6d40f883c99d0682a8575 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/cadgeometry/OGLCADLayer.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/cadgeometry/OGLCADLayer.java
@@ -40,6 +40,7 @@ import org.web3d.vrml.renderer.common.nodes.cadgeometry.BaseCADLayer;
 
 /**
  * OpenGL implementation of a CADLayer.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.7 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/cadgeometry/OGLCADPart.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/cadgeometry/OGLCADPart.java
index b34058bb05409e89df247658fbb5105c47930808..7b73c4103d183fc5957686ae79baad0645679cfc 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/cadgeometry/OGLCADPart.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/cadgeometry/OGLCADPart.java
@@ -37,6 +37,7 @@ import org.web3d.vrml.renderer.common.nodes.cadgeometry.BaseCADPart;
 
 /**
  * OpenGL implementation of a CADPart node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.6 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/core/OGLMetadataDouble.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/core/OGLMetadataDouble.java
index 0c546ea4bd2c8ff7a95105bd445457b9795b858b..98972104700168836a63777a2a3a8ac1e97920e9 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/core/OGLMetadataDouble.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/core/OGLMetadataDouble.java
@@ -23,7 +23,9 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of the VRML MetadataDouble node.
- * 
+ * <p>
+ *
+ *
  * @author Justin Couch
  * @version $Revision: 1.2 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/core/OGLMetadataFloat.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/core/OGLMetadataFloat.java
index e4234bfac44d7ef58a40eadd9bab75f423dc16ae..c4e292b924700b5bdd76952b44ed301d24b26ef6 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/core/OGLMetadataFloat.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/core/OGLMetadataFloat.java
@@ -23,7 +23,9 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of the VRML MetadataFloat node.
- * 
+ * <p>
+ *
+ *
  * @author Justin Couch
  * @version $Revision: 1.2 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/core/OGLMetadataInteger.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/core/OGLMetadataInteger.java
index 0edc4881a3d10f2f6eb3055af85ce668b6822cd6..60f33da7f6b5d39c910ee049f5f3c5c736e8b9a3 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/core/OGLMetadataInteger.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/core/OGLMetadataInteger.java
@@ -23,6 +23,8 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of the VRML MetadataInteger node.
+ * <p>
+ *
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/core/OGLMetadataSet.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/core/OGLMetadataSet.java
index 9f474056941cbfeedfc34adfdfc9a54d73801074..2f0bbb3b0e544d6403373cd6b615b785791fb023 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/core/OGLMetadataSet.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/core/OGLMetadataSet.java
@@ -23,7 +23,9 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of the VRML MetadataSet node.
- * 
+ * <p>
+ *
+ *
  * @author Justin Couch
  * @version $Revision: 1.2 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/core/OGLMetadataString.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/core/OGLMetadataString.java
index e5b4e9a448e931f450a1c85f447af488a2ad20f2..4ec9b4e9fbda9554b3430620baeec2af9eb9e0fd 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/core/OGLMetadataString.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/core/OGLMetadataString.java
@@ -23,6 +23,8 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of the VRML MetadataString node.
+ * <p>
+ *
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/dis/OGLEspduTransform.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/dis/OGLEspduTransform.java
index 1e1f22fd8189304529372ddbf0c32d7cc4732ba7..af1315a41e9ff7957241c7d967dcaf6200b48c6c 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/dis/OGLEspduTransform.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/dis/OGLEspduTransform.java
@@ -37,7 +37,8 @@ import org.web3d.vrml.renderer.common.nodes.dis.BaseEspduTransform;
 
 /**
  * OpenGL implementation of a EspduTransform node.
- * 
+ * <p>
+ *
  * @author Alan Hudson
  * @version $Revision: 1.8 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/environment/OGLProximitySensor.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/environment/OGLProximitySensor.java
index 71a6021edd35dbf6f5e1fc6fff9362d0b247cb31..1bf16b5921a4e7cdfe3897eab4653f02b8fbaae8 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/environment/OGLProximitySensor.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/environment/OGLProximitySensor.java
@@ -41,6 +41,7 @@ import org.web3d.vrml.renderer.common.nodes.environment.BaseProximitySensor;
 
 /**
  * OpenGL implementation of a ProximitySensor node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.7 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/environment/OGLVisibilitySensor.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/environment/OGLVisibilitySensor.java
index 21f8ebe094e6512ef4e70b4a12c087c19c170be5..7bcd80a48dc48ad2f406cf1d68faf2a59f27d246 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/environment/OGLVisibilitySensor.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/environment/OGLVisibilitySensor.java
@@ -35,6 +35,7 @@ import org.web3d.vrml.renderer.common.nodes.environment.BaseVisibilitySensor;
 
 /**
  * OpenGL implementation of a VisibilitySensor node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.6 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLBooleanFilter.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLBooleanFilter.java
index d9045183cad11ba99e766d42f42f8f60f3fa4017..df7e1f92426287ee1240f342c6781f7e33e66249 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLBooleanFilter.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLBooleanFilter.java
@@ -23,6 +23,8 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of the BooleanFilter.
+ * <p>
+ *
  *
  * @author Alan Hudson
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLBooleanSequencer.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLBooleanSequencer.java
index 3ef4fffb7bc860a3ec809bf1b7bbad22ab1fa4b2..dbc9c9aa587e4239950df7410c2922bcbee6e0ea 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLBooleanSequencer.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLBooleanSequencer.java
@@ -23,6 +23,8 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of the BooleanSequencer.
+ * <p>
+ *
  *
  * @author Alan Hudson
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLBooleanToggle.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLBooleanToggle.java
index e9f634f05e419be6096d045f7c15741144a849fc..a289f8e2f0cbe6ce28cb8dd6e4d75ed75f642c1f 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLBooleanToggle.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLBooleanToggle.java
@@ -23,7 +23,9 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of the BooleanToggle.
- * 
+ * <p>
+ *
+ *
  * @author Alan Hudson
  * @version $Revision: 1.2 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLBooleanTrigger.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLBooleanTrigger.java
index e89d1238ac00981049a5322330d09328667f1e38..e692ec017ac3ae19d57148be6a50ce599049fa24 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLBooleanTrigger.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLBooleanTrigger.java
@@ -23,7 +23,9 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of the BooleanTrigger.
- * 
+ * <p>
+ *
+ *
  * @author Alan Hudson
  * @version $Revision: 1.2 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLIntegerSequencer.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLIntegerSequencer.java
index 696b43240ab7cfb900a34bcbabce0b071cbb3471..450a1fddb2fcad8911f4c611d81a49ed6368cb20 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLIntegerSequencer.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLIntegerSequencer.java
@@ -23,6 +23,8 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of the IntegerSequencer.
+ * <p>
+ *
  *
  * @author Alan Hudson
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLIntegerTrigger.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLIntegerTrigger.java
index 9f265c15a33450a4e28bd438b90b66be1d0abb9a..79b464b054ae8ffb03766ac7a88acf11148d4210 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLIntegerTrigger.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLIntegerTrigger.java
@@ -23,6 +23,8 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of the IntegerTrigger.
+ * <p>
+ *
  *
  * @author Alan Hudson
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLTimeTrigger.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLTimeTrigger.java
index fba98888f3bfd15fa805c890730c9a783306b8e4..4957390ce74ced43bb80d254f4eb35f451eea826 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLTimeTrigger.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/eventutils/OGLTimeTrigger.java
@@ -23,7 +23,9 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of the TimeTrigger.
- * 
+ * <p>
+ *
+ *
  * @author Alan Hudson
  * @version $Revision: 1.2 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geom2d/OGLDisk2D.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geom2d/OGLDisk2D.java
index c39e8b5677dc6768c136bc584563c4fa895950f5..b1b363d8d7be8bf846e8e81b900ec621eaf3b78d 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geom2d/OGLDisk2D.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geom2d/OGLDisk2D.java
@@ -25,9 +25,11 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLGeometryNodeType;
 import org.web3d.vrml.renderer.common.nodes.geom2d.BaseDisk2D;
 
 /**
- * OpenGL implementation of an Disc2D.
+ * OpenGL implementation of an Disc2D
+ * <p>
  *
  * The point set directly maps to Aviatrix3D's PointArray class.
+ * <p>
  *
  * @author Vincent Marchetti
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geom2d/OGLPolyline2D.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geom2d/OGLPolyline2D.java
index f0a066f1339725113d30be223d637a6b1cf7d462..92d27cf1c139b3d56cbbb77b8c2b0b3785144a32 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geom2d/OGLPolyline2D.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geom2d/OGLPolyline2D.java
@@ -23,11 +23,13 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLGeometryNodeType;
 import org.web3d.vrml.renderer.common.nodes.geom2d.BasePolyline2D;
 
 /**
- * OpenGL implementation of an Polyline2D.
+ * OpenGL implementation of an Polyline2D
+ * <p>
  *
  * The point set directly maps to Aviatrix3D's LineArray class. When the
  * coordinates change to a different length than the current set, it will
- * notify the geometry listener to fetch the new information
+ * notify the geometry listener to fetch the new information.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geom2d/OGLPolypoint2D.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geom2d/OGLPolypoint2D.java
index 13b8cac55baf53b10fd5da298845bcd31d4bc033..a25c3b45021a20e3eb7e66725548807f38a3a14c 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geom2d/OGLPolypoint2D.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geom2d/OGLPolypoint2D.java
@@ -23,9 +23,11 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLGeometryNodeType;
 import org.web3d.vrml.renderer.common.nodes.geom2d.BasePolypoint2D;
 
 /**
- * OpenGL implementation of an Polypoint2D.
+ * OpenGL implementation of an Polypoint2D
+ * <p>
  *
  * The point set directly maps to Aviatrix3D's PointArray class.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geom2d/OGLRectangle2D.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geom2d/OGLRectangle2D.java
index 6f555e06a0477d9008a2353a7431ecc32ef0e0ce..2b208445ab4542145ed24c06cbb14fefd1eacbbb 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geom2d/OGLRectangle2D.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geom2d/OGLRectangle2D.java
@@ -27,9 +27,11 @@ import org.web3d.vrml.renderer.common.nodes.GeometryHolder;
 import org.web3d.vrml.renderer.common.nodes.GeometryUtils;
 
 /**
- * OpenGL implementation of an Rectangle2D.
+ * OpenGL implementation of an Rectangle2D
+ * <p>
  *
  * The point set directly maps to Aviatrix3D's PointArray class.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geom2d/OGLTriangleSet2D.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geom2d/OGLTriangleSet2D.java
index d12382d1352b412dfef5e98502196e93d471bc5f..7f86c5477615e9cff7062809049075bb96d4bd35 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geom2d/OGLTriangleSet2D.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geom2d/OGLTriangleSet2D.java
@@ -27,9 +27,11 @@ import org.web3d.vrml.renderer.common.nodes.GeometryHolder;
 import org.web3d.vrml.renderer.common.nodes.GeometryUtils;
 
 /**
- * OpenGL implementation of an TriangleSet2D.
+ * OpenGL implementation of an TriangleSet2D
+ * <p>
  *
  * The point set directly maps to Aviatrix3D's PointArray class.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geom3d/OGLExtrusion.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geom3d/OGLExtrusion.java
index f75bea042f6f8b48c16c87da5239db152c9f22bf..ea20874b6f6db934c9f0f533981de634c0c2e1a3 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geom3d/OGLExtrusion.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geom3d/OGLExtrusion.java
@@ -1,1116 +1,1116 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.renderer.ogl.nodes.geom3d;
-
-// External imports
-import javax.vecmath.*;
-
-import org.j3d.aviatrix3d.*;
-
-import org.j3d.geom.GeometryData;
-
-// Local import
-import org.web3d.vrml.lang.*;
-
-import org.web3d.vrml.nodes.VRMLNodeType;
-import org.web3d.vrml.renderer.common.nodes.geom3d.BaseExtrusion;
-import org.web3d.vrml.renderer.common.nodes.GeometryUtils;
-import org.web3d.vrml.renderer.common.nodes.GeometryHolder;
-import org.web3d.vrml.renderer.ogl.nodes.OGLGeometryNodeType;
-
-/**
- * OpenGL implGeomementation of an Extrusion
- * <p> The 1.16 version of OGLExtrusion generates
- * end caps correctly for both convex and concave
- * crossSections.  More thorough testing is needed
- * to see if textures are handled properly, however.
- *
- * @author Justin Couch, Andrzej Kapolka, Rick Goldberg
- * @version $Revision: 1.20 $
- */
-public class OGLExtrusion extends BaseExtrusion
-    implements OGLGeometryNodeType, NodeUpdateListener{
-
-    /** Message when we detect a solid of revolution */
-    private static final String SOR_ERR =
-        "Invalid Extrusion data; looks like a solid of revolution";
-
-    /** When the normalisation of the Y axis fails because it is zero length */
-    private static final String Y_NORM_MSG =
-        "Error normalizing Y in Extrusion";
-
-    /** The OpenGL geometry implGeommentation
-     * Previous implementation of OGLExtrusion used an IndexedTriangleStripArray;
-     * more recently implGeom is a TriangleArray.        */
-    private Geometry implGeom;
-
-    /** The number of texture coordinate sets to be set by Shape Class */
-    private int numTexCoordSets;
-    
-    /** The coord array defines the 3D vertices referenced by the coordIndex field. */
-    private float[] coords;
-
-    /** The coordIndex array specifies polygonal faces by indexing into coordinates
-     * in the 'coords' array.  An index of -1 indicates that the current face has
-     * ended and the next one begins.     */
-    private int[] coordIndex;
-
-    /** The Point3f[] version of vfSpine.
-     * One point for every spine.      */
-    private Point3f[] spines;
-
-    /** The Vector3f[] version of vfScale. */
-    private Vector3f[] scales;
-
-    /** The AxisAngle4f[] version of vfOrientation. */
-    private AxisAngle4f[] orientations;
-
-    /** rotations will contain the per spine transform composed with
-     * orientation after the call to calculateSCP(); */
-    private Matrix3f[] rotations;
-    private Matrix4f[] transforms;
-
-    private boolean collinear;
-
-    /** Flag to say normals have changed when updating the geometry */
-    private boolean normalsChanged;
-
-    /** Flag to say texture coords have changed when updating the geometry */
-    private boolean texCoordsChanged;
-
-    /** Flag to say colors have changed when updating the geometry */
-    private boolean colorsChanged;
-
-    /** Did the vbo state change */
-    private boolean vboChanged;
-
-    /** Flag indicating if the spine is closed as a surface of revolution */
-    private boolean spineClosed;
-
-    /** Flag to say if the crossSection is closed or not.
-     * Fundamental enough that it may belong in the base class */
-    boolean crossSectionClosed;
-
-    /** Userdata kept in the triangle geometry */
-    protected GeometryData geomData;
-
-    /** Set to "numCrossSection-1" if(crossSectionClosed)
-     * else equal to numCrossSection.  */
-    int uniqueCrossSectionPoints;
-
-    /**
-     * Construct a default sphere instance
-     */
-    public OGLExtrusion() {
-    }
-
-    /**
-     * Construct a new instance of this node based on the details from the
-     * given node. If the node is not a Box node, an exception will be
-     * thrown.
-     *
-     * @param node The node to copy
-     * @throws IllegalArgumentException The node is not a Group node
-     */
-    public OGLExtrusion(VRMLNodeType node) {
-        super(node);
-    }
-
-    //----------------------------------------------------------
-    // Methods required by the UpdateListener interface.
-    //----------------------------------------------------------
-
-    /**
-     * Notification that its safe to update the node now with any operations
-     * that could potentially effect the node's bounds.
-     *
-     * @param src The node or Node Component that is to be updated.
-     */
-    @Override
-    public void updateNodeBoundsChanges(Object src) {
-        ((VertexGeometry)implGeom).setVertices(  TriangleArray.COORDINATE_3,
-                                                geomData.coordinates,
-                                                geomData.vertexCount);
-    }
-
-    /**
-     * Notification that its safe to update the node now with any operations
-     * that only change the node's properties, but do not change the bounds.
-     *
-     * @param src The node or Node Component that is to be updated.
-     */
-    @Override
-    public void updateNodeDataChanges(Object src) {
-
-/*        if(colorsChanged) {
-            int num_comp =
-                (vfColor == null) ? 0 : vfColor.getNumColorComponents();
-            boolean has_alpha = num_comp == 4;
-
-            implGeom.setColors(has_alpha, geomData.colors);
-            colorsChanged = false;
-
-            if (vfColor == null) {
-                localColors = false;
-            }
-        }
-
-        if(normalsChanged) {*/
-            ((VertexGeometry)implGeom).setNormals(geomData.normals);
-            /*normalsChanged = false;
-        }
-
-        if(texCoordsChanged) {
-            implGeom.setTextureCoordinates(texTypes,
-                                           texCoords,
-                                           numUniqueTexSets);
-            implGeom.setTextureSetMap(texSetMap, numTexSets);
-
-            texCoordsChanged = false;
-        }
-
-        if (vboChanged) {
-            // Only ever change to false after activity
-            implGeom.setVBOEnabled(false);
-
-            vboChanged = false;
-        }*/
-    }
-
-    //-------------------------------------------------------------
-    // Methods used to set implGeom as TriangleArray
-    //-------------------------------------------------------------
-
-    /**
-     * Build the implGeom, set the normals, etc.:
-     * Basically let GeometryUtils do all the work.
-     *
-     * @author Eric Fickenscher
-     */
-    private void buildImplTriangleArray(){
-
-        // convert vrml data to intermediate form
-        initSetup();
-        // calculate per spine SCP transforms
-        // results in transforms[] being filled withs SCP info
-        // complete with scale, translation and orientation from
-        // fields
-        if(!calculateSCP()) return;
-
-        // transform the crossSections to coordinates
-        createExtrusionCoordinates();
-
-        // set coordIndex to create an IndexedFaceSet representing this extrusion
-        createIndicesTriangleArray();
-        //printIndices();
-
-        GeometryUtils gutils = new GeometryUtils();
-        GeometryHolder gholder = new GeometryHolder();
-
-        gutils.generateTriangleArrays(  coords,
-                                        null,   // float[] color
-                                        null,   // float[] normal
-                                        null,   // float[] texture
-                                        1,
-                                        true,   // genTexCoords,
-                                        true,   // genNormals,
-                                        coordIndex,
-                                        coordIndex.length,
-                                        null,   // int[] vfColorIndex,
-                                        null,   // int[] vfNormalIndex,
-                                        null,   // int[] vfTexCoordIndex,
-                                                // TODO : are we obeying the ccw right-hand-
-                                        true,   // rule or not?  this is far different
-                                                // than the meaning of vfCCW!
-                                        vfConvex,
-                                        false,  // colorPerVertex,
-                                        true,   // normalPerVertex,
-                                        0,
-                                        vfCreaseAngle,
-                                        true,   // initialBuild,
-                                        gholder);
-
-        geomData = new GeometryData();
-        //TODO : should initialize vfCCW   // TODO : check for explicit initialization of other fields as well
-        geomData.geometryType = GeometryData.TRIANGLES;
-        gutils.copyData(gholder, geomData);
-
-        if (implGeom.isLive())
-            implGeom.boundsChanged(this);
-        else
-            updateNodeBoundsChanges(implGeom);
-
-        if (implGeom.isLive())
-            implGeom.dataChanged(this);
-        else
-            updateNodeDataChanges(implGeom);
-
-        // Make an array of objects for the texture setting
-        float[][] textures = gholder.textureCoordinates;
-        int[] tex_type = { TriangleArray.TEXTURE_COORDINATE_2 };
-        ((VertexGeometry)implGeom).setTextureCoordinates(tex_type, textures, 1);
-
-        // Setup texture units
-        int[] tex_maps = new int[numTexCoordSets];
-
-        for(int i=0; i < numTexCoordSets; i++)
-            tex_maps[i] = 0;
-
-        ((VertexGeometry)implGeom).setTextureSetMap(tex_maps, numTexCoordSets);
-    }
-
-    /**
-     * Result: Completed "coords" array: An array of all the float information
-     * describing each vertex in the extrusion, created by applying the
-     * transforms to the vfCrossSection points
-     *
-     * @author Eric Fickenscher
-     */
-    private void createExtrusionCoordinates(){
-
-        // calculate the number of coordinates needed for the sides
-        // of the extrusion: 3 coordinates per vertex, one vertex per
-        // crossSectionPoint, and one set of crossSectionPoints per spinePoint
-        coords = new float[ numSpine * uniqueCrossSectionPoints * 3 ];
-
-        for(int i = 0; i < numSpine; i++) {
-
-            Matrix4f tx = transforms[i];
-
-            for(int j = 0; j < uniqueCrossSectionPoints; j++) {
-
-                int ind = (i * uniqueCrossSectionPoints + j) * 3;
-
-                // basically a transform, in place
-                float c_x = vfCrossSection[j*2   ];
-                float c_z = vfCrossSection[j*2 +1];
-
-                float x = c_x * tx.m00 + c_z * tx.m02 + tx.m03;
-                float y = c_x * tx.m10 + c_z * tx.m12 + tx.m13;
-                float z = c_x * tx.m20 + c_z * tx.m22 + tx.m23;
-
-                coords[ind] = x;
-                coords[ind + 1] = y;
-                coords[ind + 2] = z;
-            }
-        }
-    }
-
-    /**
-     * Result: Completed "coordIndex" array: an int array representing an
-     * IndexedFaceSet representation of the extrusion.
-     *
-     * @author Eric Fickenscher
-     */
-    private void createIndicesTriangleArray(){
-
-        int sizeOfCoordIndex = 5*(numCrossSection-1) * (numSpine-1);
-        if( vfBeginCap) sizeOfCoordIndex += uniqueCrossSectionPoints+1;
-        if( vfEndCap)   sizeOfCoordIndex += uniqueCrossSectionPoints+1;
-
-        coordIndex = new int[sizeOfCoordIndex];
-
-        int indx = 0;
-        int curIndex;
-
-        // for each separate segment between two spine points
-        for(int i = 0; i<numSpine-1; i++){
-
-            curIndex = i*uniqueCrossSectionPoints;
-
-            // build a quadrilateral for every crossSection-to-crossSection side around that segment
-            // note that Xj3D wireframe mode shows triangulation even though quads are being built here
-            for(int j = 0; j < numCrossSection-1; j++){
-
-                if(vfCCW){
-                    coordIndex[ indx++ ] = j + curIndex;
-                    coordIndex[ indx++ ] = j + curIndex +1;
-                    coordIndex[ indx++ ] = j + curIndex + uniqueCrossSectionPoints +1;
-                    coordIndex[ indx++ ] = j + curIndex + uniqueCrossSectionPoints;
-                } else {
-                    coordIndex[ indx++ ] = j + curIndex + uniqueCrossSectionPoints;
-                    coordIndex[ indx++ ] = j + curIndex + uniqueCrossSectionPoints +1;
-                    coordIndex[ indx++ ] = j + curIndex +1;
-                    coordIndex[ indx++ ] = j + curIndex;
-                }
-
-                coordIndex[ indx++ ] = -1;
-            }
-
-            if(crossSectionClosed){
-                coordIndex[indx -4] -= uniqueCrossSectionPoints;
-                coordIndex[indx -3] -= uniqueCrossSectionPoints;
-            }
-        }
-        
-        //if spineClosed, then index of last cross section can be changed into index of 1st cross section.
-        if(spineClosed)
-            for(int j = 0; j < uniqueCrossSectionPoints; j++)
-            {
-                coordIndex[indx - j * 5 - 3] -= (uniqueCrossSectionPoints * (numSpine-1));
-                coordIndex[indx - j * 5 - 2] -= (uniqueCrossSectionPoints * (numSpine-1));
-            }
-                
-        // note that Xj3D wireframe mode shows triangulation even though N-sided polygons are being built here
-        if( vfBeginCap) {
-
-            for(int i = 0; i < uniqueCrossSectionPoints; i++){
-                if(vfCCW) coordIndex[ indx++ ] = uniqueCrossSectionPoints -i -1;
-                else coordIndex[ indx++ ] = i;
-            }
-            coordIndex[ indx++ ] = -1;
-        }
-        if( vfEndCap) {
-
-            for(int i = 0; i < uniqueCrossSectionPoints; i++){
-                if(vfCCW) coordIndex[ indx++ ] = (numSpine-1)*uniqueCrossSectionPoints + i;
-                else coordIndex[ indx++ ] = numSpine*uniqueCrossSectionPoints -i -1;
-            }
-            coordIndex[ indx ] = -1;
-        }
-    }
-
-    //-------------------------------------------------------------
-    // Methods defined by OGLGeometryNodeType
-    //-------------------------------------------------------------
-
-    /**
-     * Returns a OGL Geometry node
-     *
-     * @return A Geometry node
-     */
-    @Override
-    public Geometry getGeometry() {
-        return implGeom;
-    }
-
-    /**
-     * Set the number of textures that were found on the accompanying Appearance
-     * node. Used to set the number of texture coordinates that need to be
-     * passed in to the renderer when no explicit texture coordinates were
-     * given.
-     *
-     * @param count The number of texture coordinate sets to add
-     */
-    @Override
-    public void setTextureCount(int count) {
-        numTexCoordSets = count;
-    }
-    
-    /**
-     * Get the number of texture coordinate sets contained by this node
-     *
-     * @return the number of texture coordinate sets
-     */
-    @Override
-    public int getNumSets() {
-        return 0;
-    }
-
-    /**
-     * Get the texture coordinate generation mode.  NULL is returned
-     * if the texture coordinates are not generated.
-     *
-     * @param setNum The set which this tex gen mode refers
-     * @return The mode or NULL
-     */
-    @Override
-    public String getTexCoordGenMode(int setNum) {
-        return null;
-    }
-
-    /**
-     * Set the value of the field at the given index as an array of floats.
-     * This would be used to set MFFloat, SFVec2f, SFVec3f and SFRotation
-     * field types.
-     *
-     * @param index The index of destination field to set
-     * @param value The new value to use for the node
-     * @param numValid The number of valid values to copy from the array
-     * @throws InvalidFieldException The field index is not known
-     * @throws InvalidFieldValueException The value provided is out of range
-     *    for the field type.
-     */
-    @Override
-    public void setValue(int index, float[] value, int numValid)
-        throws InvalidFieldException, InvalidFieldValueException {
-
-        super.setValue(index, value, numValid);
-
-        if(!inSetup)
-            stateManager.addEndOfThisFrameListener(this);
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by FrameStateListener
-    //----------------------------------------------------------
-
-    /**
-     * Notification that the rendering of the event model is complete and that
-     * rendering is about to begin. Used to update the j3d representation
-     * only once per frame.
-     */
-    @Override
-    public void allEventsComplete() {
-        buildImplTriangleArray();
-// TODO private trace variable
-//        printDebugMessagesToConsole ();
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by OGLVRMLNode
-    //----------------------------------------------------------
-
-    /**
-     * Get the Java3D scene graph object representation of this node. This will
-     * need to be cast to the appropriate parent type when being used.
-     *
-     * @return The OGL representation.
-     */
-    @Override
-    public SceneGraphObject getSceneGraphObject() {
-        return implGeom;
-    }
-
-    /**
-     * Notification that the construction phase of this node has finished.
-     * If the node would like to do any internal processing, such as setting
-     * up geometry, then go for it now.
-     */
-    @Override
-    public void setupFinished() {
-        if(!inSetup)
-            return;
-
-        super.setupFinished();
-
-        // if using a TriangleArray instead of an IndexedTriangleStripArray {
-        implGeom = new TriangleArray(true, VertexGeometry.VBO_HINT_STATIC);
-        //OGLUserData u_data = new OGLUserData();
-        //u_data.geometryData = geomData;
-        //implGeom.setUserData(u_data);
-
-        buildImplTriangleArray();
-// TODO private trace variable
-//        printDebugMessagesToConsole ();
-
-        //} else {
-        //    implGeom = new IndexedTriangleStripArray(true, VertexGeometry.VBO_HINT_STATIC);
-        //    buildImpl();
-        //}
-    }
-
-    //-------------------------------------------------------------
-    // Local methods
-    //-------------------------------------------------------------
-
-    /**
-     * Instantiate the various variables needed for processing.
-     */
-    private void initSetup() {
-
-        numTexCoordSets = 0;
-        normalsChanged = false;
-        texCoordsChanged = false;
-        colorsChanged = false;
-        vboChanged = false;
-
-        collinear = false;
-        // spineClosed :   1st Spine == last Spine
-        //              && 1st Scale == last Scale 
-        spineClosed =  (vfSpine[0] == vfSpine[vfSpine.length-3] &&
-                        vfSpine[1] == vfSpine[vfSpine.length-2] &&
-                        vfSpine[2] == vfSpine[vfSpine.length-1] &&
-                        vfScale[0] == vfScale[vfScale.length-2] &&
-                        vfScale[1] == vfScale[vfScale.length-1]);
-
-        uniqueCrossSectionPoints = numCrossSection;
-        crossSectionClosed =
-            (vfCrossSection[0] == vfCrossSection[vfCrossSection.length-2] &&
-             vfCrossSection[1] == vfCrossSection[vfCrossSection.length-1]);
-        if(crossSectionClosed) uniqueCrossSectionPoints--;
-
-        if (numSpine != (vfSpine.length / 3)) {
-            errorReporter.warningReport("A numSpine differs from (vfSpine.length/3) at initSetup() in OGLExtrusion.java", null);
-        }
-        
-        // Convert the spine array into a Point3f array for
-        // easier manipulation later
-        spines = new Point3f[numSpine];
-        for(int i = 0; i < spines.length; i++) {
-            spines[i] = new Point3f(vfSpine[i * 3],
-                                    vfSpine[i * 3 + 1],
-                                    vfSpine[i * 3 + 2]);
-        }
-
-        // Convert the orientation points so they match specification
-        //
-        // Note: if the number of scale or orientation points is greater
-        // than the number of spine points, the excess values are ignored.
-        // If they contain one value, it is applied at all spine points.
-        // (results are 'undefined' if the number of sets of scale or orientation
-        // values is greater than one but less than the number of spine
-        // points... in such a case, we repeat the final set of values for
-        // the remainder of spine points)
-        orientations = new AxisAngle4f[numSpine];
-        for(int i = 0; i < orientations.length; i++) {
-            if(i * 4 + 3 < vfOrientation.length)
-                orientations[i] = new AxisAngle4f(
-                    vfOrientation[i * 4],
-                    vfOrientation[i * 4 + 1],
-                    vfOrientation[i * 4 + 2],
-                    vfOrientation[i * 4 + 3]
-               );
-            else
-                orientations[i] = new AxisAngle4f(orientations[i-1]);
-        }
-
-        // Convert the scale points so they match specification
-        //
-        // Note that scales are really just 2D scalars,
-        // but this version uses a 3f for some reason,
-        // leaving the "y" value as 1.
-        scales = new Vector3f[numSpine];
-        for(int i = 0; i < scales.length; i++) {
-            if(i * 2 + 1 < vfScale.length)
-                scales[i] = new Vector3f(vfScale[i * 2],
-                                         1,
-                                         vfScale[i * 2 + 1]);
-            else  // if vfScale.length is short, copy previous scale.
-                scales[i] = new Vector3f(scales[i-1]); 
-        }
-
-        rotations = new Matrix3f[vfSpine.length / 3];
-
-        // if entirely collinear
-        Vector3d v2 = new Vector3d();
-        Vector3d v1 = new Vector3d();
-        Vector3d v0 = new Vector3d();
-        double d = 0;
-        for(int i = 1; i < spines.length - 1; i++) {
-            v2.set(spines[i+1]);
-            v1.set(spines[i]);
-            v0.set(spines[i - 1]);
-            v2.sub(v1);
-            v1.sub(v0);
-            v0.cross(v2,v1);
-            d += v0.dot(v0);
-        }
-
-        collinear = (d == 0);
-    }
-
-    /**
-     * Create the spine information and verify that this is a valid object.
-     *
-     * @return true if everything is valid, false otherwise
-     */
-    private boolean calculateSCP() {
-        // find an orthonormal basis and construct rotation matrix
-        // for each spine. handle special cases in second pass
-        Vector3f u, v;
-
-        int last = numSpine - 1;
-        Vector3f[] x, y, z;
-
-        x = new Vector3f[numSpine];
-        y = new Vector3f[numSpine];
-        z = new Vector3f[numSpine];
-
-        if (collinear) {
-            if (spineClosed) {
-                errorReporter.warningReport(SOR_ERR, null);
-                StringBuilder buf = new StringBuilder("Spine data:");
-
-                for (Point3f spine : spines) {
-                    buf.append(spine);
-                    buf.append(' ');
-                }
-
-                errorReporter.messageReport(buf.toString());
-
-                return false;
-            }
-
-            // Direction is the first spine point that does not equal to
-            // spines[0]
-            Vector3f direction = null;
-            for (Point3f spine : spines) {
-                if (!spines[0].equals(spine)) {
-                    direction = new Vector3f(spine);
-                }
-            }
-
-            y[0] = new Vector3f();
-            if (direction != null) {
-                y[0].sub(direction, spines[0]);
-// fixed NPE C:/x3d-code/www.web3d.org/x3d/content/examples/X3dForWebAuthors/KelpForestExhibit/CircleFishPrototype.wrl
-// https://docs.oracle.com/cd/E17802_01/j2se/javase/technologies/desktop/java3d/forDevelopers/j3dapi/javax/vecmath/Tuple3d.html
-            } else {
-                errorReporter.warningReport("Direction is null at calculateSCP() in OGLExtrusion.java", null);
-            }
-
-            if (!norm(y[0])) {
-                errorReporter.warningReport(Y_NORM_MSG, null);
-            }
-
-            // Create an initial x[0]
-            if (y[0].x == 1) {
-                x[0] = new Vector3f(0, -1, 0);
-            } else if (y[0].x == -1) {
-                x[0] = new Vector3f(0, 1, 0);
-            } else {
-                x[0] = new Vector3f(1, 0, 0);
-            }
-            // Create z[0]
-            z[0] = new Vector3f();
-            z[0].cross(x[0], y[0]);
-
-            // Create final x[0]
-            x[0].cross(y[0], z[0]);
-            for (int i = 1; i < spines.length; i++) {
-                // redo, this should take the direction of y
-                // redone by Pasi Paasiala < < check this >  >
-                x[i] = new Vector3f(x[0]);
-                y[i] = new Vector3f(y[0]);
-                z[i] = new Vector3f(z[0]);
-            }
-        } else { // "collinear" is false
-
-            // find y[i] for all but first and last
-            // most times the exception cases are bad data and hopefully
-            // wont happen. It is free to try catch you later, so hopes
-            // 99% cases will be one if faster by not checking the if
-            for (int i = 1; i < last; i++) {
-                y[i] = new Vector3f();
-                y[i].sub(spines[i + 1], spines[i - 1]);
-                if (!norm(y[i])) {
-                    // spines[i+1] equals spines[i - 1]
-                    y[i].sub(spines[i + 1], spines[i]);
-                    if (!norm(y[i])) {
-                        // spines[i+1] equaled spines[i]
-                        y[i].sub(spines[i], spines[i - 1]);
-                        if (!norm(y[i])) {
-                            // spines[i] equaled spines[i - 1]
-                            // real bad case, do something
-                            int w = i + 2;
-                            while ((w < last + 1) && (spines[i - 1].equals(spines[w]))) {
-                                w++;
-                            }
-                            if (w < last + 1) {
-                                y[i].sub(spines[w], spines[i - 1]);
-                                norm(y[i]); // should never divide by zero here
-                            } else { // worst worst case
-                                y[i] = new Vector3f(0, 1, 0);
-                            }
-                        }
-                    }
-                }
-            } // find y[i] in the case of non-collinear, 
-
-            // y for ends
-            if (spineClosed) {
-                // spineClosed and not collinear - >  not all one point
-                y[0] = new Vector3f();
-                y[0].sub(spines[1], spines[last - 1]);
-                if (!norm(y[0])) {
-                    // bad case that the spine[n-2] == spine[1]
-                    int w = last - 2;
-                    while ((w > 1) && (spines[1].equals(spines[w]))) {
-                        w--;
-                    }
-                    if (w > 1) {
-                        y[0].sub(spines[1], spines[w]);
-                        norm(y[0]); // should never divide by zero here
-                    } else // how did this happen?
-                    {
-                        y[0].set(0, 0, 1);
-                    }
-                }
-                y[last] = new Vector3f(y[0]);
-            } else {
-                y[0] = new Vector3f();
-                y[last] = new Vector3f();
-                y[0].sub(spines[1], spines[0]);
-                if (!norm(y[0])) {
-                    int w = 2;
-                    while ((w < last) && (spines[0].equals(spines[w]))) {
-                        w++;
-                    }
-                    if (w < last) {
-                        y[0].sub(spines[w], spines[0]);
-                        norm(y[0]); // should not divide by zero here
-                    } else {
-                        y[0].set(0, 0, 1);
-                    }
-                }
-                y[last] = new Vector3f();
-                y[last].sub(spines[last], spines[last - 1]);
-
-                if (!norm(y[last])) {
-                    int w = last - 2;
-                    while ((w > -1) && (spines[last].equals(spines[w]))) {
-                        w--;
-                    }
-                    if (w > -1) {
-                        y[last].sub(spines[last], spines[w]);
-                        norm(y[last]);
-                    } else {
-                        y[last].set(0, 0, 1);
-                    }
-                }
-            }
-
-            // now z axis for each spine
-            // first all except first and last
-            boolean recheck = false;
-            for (int i = 1; i < last; i++) {
-                u = new Vector3f();
-                v = new Vector3f();
-                z[i] = new Vector3f();
-                u.sub(spines[i - 1], spines[i]);
-                v.sub(spines[i + 1], spines[i]);
-                // spec seems backwards on u and v
-                // shouldn't it be z[i].cross(u,v)???
-                //z[i].cross(v,u);
-                //-- >  z[i].cross(u,v); is correct < < check this >  >
-                // Modified by Pasi Paasiala (Pasi.Paasiala@solibri.com)
-                // skwon : Modified by Sungmin Kwon (lucidaim@gmail.com)
-                //-- >  z[i].cross(v,u) is correct by right hand rule.
-                z[i].cross(v, u);
-                if (!norm(z[i])) {
-                    recheck = true;
-                }
-            }
-            if (spineClosed) {
-                z[0] = z[last] = new Vector3f();
-                u = new Vector3f();
-                v = new Vector3f();
-                u.sub(spines[last - 1], spines[0]);
-                v.sub(spines[1], spines[0]);
-                try {
-                    // skwon : Modified by Sungmin Kwon (lucidaim@gmail.com)
-                    // z[0].cross(v, u) is correct by right hand rule.
-                    z[0].cross(v, u);
-                    // skwon : z[0] should be normalized.
-                    norm(z[0]);
-                } catch (ArithmeticException ae) {
-                    recheck = true;
-                }
-            } else { // not spineClosed
-                z[0] = new Vector3f(z[1]);
-                z[last] = new Vector3f(z[last - 1]);
-            }
-
-            if (recheck) { // found adjacent collinear spines
-                // first z has no length ?
-                if (z[0].dot(z[0]) == 0) {
-                    for (int i = 1; i < spines.length; i++) {
-                        if (z[i].dot(z[i]) > 0) {
-                            z[0] = new Vector3f(z[i]);
-                        }
-                    }
-                    // test again could be most degenerate of cases
-                    if (z[0].dot(z[0]) == 0) {
-                        z[0] = new Vector3f(0, 0, 1);
-                    }
-                }
-
-                // check rest of z's
-                for (int i = 1; i < last + 1; i++) {
-                    if (z[i].dot(z[i]) == 0) {
-                        z[i] = new Vector3f(z[i - 1]);
-                    }
-                }
-            }
-
-            // finally, do a neighbor comparison
-            // and evaluate the x's
-            for (int i = 0; i < spines.length; i++) {
-                if ((i > 0) && (z[i].dot(z[i - 1]) < 0)) {
-                    z[i].negate();
-                }
-
-                // at this point, y and z should be nice
-                x[i] = new Vector3f();
-
-                //Original was: x[i].cross(z[i],y[i]); < < check this >  >
-                //but it doesn't result in right handed coordinates
-                // Modified by Pasi Paasiala
-                x[i].cross(y[i], z[i]);
-                norm(x[i]);
-            }
-        }
-
-        // should now have orthonormal vectors for each
-        // spine. create the rotation matrix with scale for
-        // each spine. spec is unclear whether a twist imparted
-        // at one of the spines is inherited by its "children"
-        // so assume not.
-        // also, the order looks like SxTxRscpxRo , ie ,
-        // the spec doc looks suspect, double check
-        Matrix3f m = new Matrix3f();
-        transforms = new Matrix4f[spines.length];
-        for (int i = 0; i < spines.length; i++) {
-            rotations[i] = new Matrix3f();
-            // Original had setRow. This is correct < < check this >  >
-            // Modified by Pasi Paasiala
-            rotations[i].setColumn(0, x[i]);
-            rotations[i].setColumn(1, y[i]);
-            rotations[i].setColumn(2, z[i]);
-        }
-
-        // skwon : I am not sure a purpose of correctionRotations[i] matrix
-        //         No correctionRotation brings same result with other viewers.
-        //Matrix3f[] correctionRotations = createCorrectionRotations(z);
-        Vector3f tmp = new Vector3f();
-        // Create the transforms
-        for (int i = 0; i < spines.length; i++) {
-            // skwon : I am not sure a purpose of correctionRotations[i] matrix
-            //         No correctionRotation brings same result with other viewers.
-            //rotations[i].mul(correctionRotations[i]);
-            m.set(orientations[i]);
-            rotations[i].mul(m);
-            transforms[i] = new Matrix4f();
-            transforms[i].setIdentity();
-            
-            // skwon : Modified by Sungmin Kwon (lucidaim@gmail.com)
-            //-->matrix m is contaminated when used for an orientation.
-            //   m must be reset before being used for scaling.
-            //   otherwise, the rest entries from rotation will bother you.
-            m.setZero();;
-            m.m00 = scales[i].x;
-            m.m11 = scales[i].y; // should always be '1'
-            m.m22 = scales[i].z;
-            
-            // skwon : Modified by Sungmin Kwon (lucidaim@gmail.com)
-            //--> ((ROTATION)(ORIENTATION))(SCALE) is correct
-            //    instead of old code : (SCALE)((ROTATION)(ORIENTATION))
-            // [[ old code ]]
-            //m.mul(rotations[i]);
-            //transforms[i].setRotationScale(m);
-            rotations[i].mul(m);
-            transforms[i].setRotationScale(rotations[i]);
-
-            tmp.set(spines[i]);
-            transforms[i].setTranslation(tmp);
-        }
-
-        return true;
-    }
-
-    /**
-     * Creates a rotation for each spine point to avoid twisting of the profile
-     * when the orientation of SCP changes.
-     * This method appears to be a prior bugfix work around that is no longer required. 
-     * @author Pasi Paasiala
-     * @param z the vector containing the z unit vectors for each spine point
-     */
-    @Deprecated 
-    private Matrix3f[] createCorrectionRotations(Vector3f[] z) {
-
-        Matrix3f[] correctionRotations = new Matrix3f[spines.length];
-        correctionRotations[0] = new Matrix3f();
-        correctionRotations[0].setIdentity();
-        AxisAngle4f checkAngle = new AxisAngle4f();
-
-        // testPoint is used to find the angle that gives the smallest distance
-        // between the previous and current rotation. Find a point that is not
-        // in the origin.
-        Point3f testPoint = new Point3f(vfCrossSection[0], 0, vfCrossSection[1]);
-
-        for(int i = 0; i < numCrossSection; i++) {
-            if(vfCrossSection[i*2] != 0 || vfCrossSection[i*2 +1] != 0) {
-                testPoint = new Point3f(vfCrossSection[i*2], 0, vfCrossSection[i*2 +1]);
-                break;
-            }
-        }
-
-        // Fix the orientations by using the angle between previous z and current z
-        for(int i = 1; i < spines.length; i++) {
-            float angle = z[i].angle(z[i - 1]);
-            correctionRotations[i] = correctionRotations[i - 1];
-            if(angle != 0) {
-                correctionRotations[i] = new Matrix3f(correctionRotations[i - 1]);
-                Point3f previous = new Point3f();
-                //Point3f previous = testPoint;
-                // Test with negative angle:
-                Matrix3f previousRotation = new Matrix3f(rotations[i - 1]);
-                previousRotation.mul(correctionRotations[i - 1]);
-                previousRotation.transform(testPoint, previous);
-                Matrix3f delta = new Matrix3f();
-                delta.setIdentity();
-                delta.rotY(-angle);
-                correctionRotations[i].mul(delta);
-
-                Matrix3f negativeRotation = new Matrix3f(rotations[i]);
-                negativeRotation.mul(correctionRotations[i]);
-
-                Point3f pointNegative = new Point3f();
-                negativeRotation.transform(testPoint,pointNegative);
-
-                float distNegative = pointNegative.distance(previous);
-
-                // Test with positive angle
-                delta.rotY(angle*2);
-                correctionRotations[i].mul(delta);
-                Matrix3f positiveRotation = new Matrix3f(rotations[i]);
-                positiveRotation.mul(correctionRotations[i]);
-                Point3f pointPositive = new Point3f();
-                positiveRotation.transform(pointPositive);
-                float distPositive = pointPositive.distance(previous);
-
-                if(distPositive > distNegative) {
-                    // Reset correctionRotations to negative angle
-                    delta.rotY(-angle*2);
-                    correctionRotations[i].mul(delta);
-                }
-
-                // Check that the angle is not more than PI.
-                // If it is subtract PI from angle
-                checkAngle.set(correctionRotations[i]);
-                if(((float)Math.PI - checkAngle.angle) < 0.001) {
-                    correctionRotations[i].rotY((float)(checkAngle.angle - Math.PI));
-                }
-            }
-        }
-
-        return correctionRotations;
-    }
-
-    /**
-     * Variant on the traditional normalisation process. If the length is zero
-     * we've had something go wrong so should let the user know, courtesy of
-     * the return value.
-     *
-     * @param n The vector to normalise
-     * @return false when the vector is zero length
-     */
-    private boolean norm(Vector3f n) {
-
-        float norml = n.x*n.x + n.y*n.y + n.z*n.z;
-
-        if(norml == 0)
-            return false;
-
-        norml = 1 / (float)Math.sqrt(norml);
-
-        n.x *= norml;
-        n.y *= norml;
-        n.z *= norml;
-
-        return true;
-    }
-
-    /**
-     * Just a helper method that may prove useful for debugging purposes.
-     */
-    private void printCrossSectionPoints(){
-        System.out.println("printCrossSectionPoints: ");
-        if (vfCrossSection.length == 0)
-           System.out.println("none");
-        for(int i = 0; i < vfCrossSection.length; i++){
-//            if(vfCrossSection[i] >= 0)
-//                System.out.print(" ");
-            System.out.print("[" + i/2 + "] (" + vfCrossSection[i++]);
-            System.out.print(", " + vfCrossSection[i] + "), ");
-            if(((i+1)/2)%5 == 0)
-                 System.out.println(); // skip line after every 5 pairs
-            else System.out.print("\t");
-        }
-        if (crossSectionClosed)
-             System.out.println("\ncrossSection is closed");
-        else System.out.println("\ncrossSection is open");
-        System.out.println("=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~");
-    }
-    /**
-     * Just a helper method that may prove useful for debugging purposes.
-     */
-    private void printCoords(){
-        System.out.println("printCoords: ");
-        if (coords.length == 0)
-             System.out.println("none");
-        else System.out.print  ("[0] ");
-        for(int i = 0; i < coords.length; i++){
-            System.out.print(coords[i]);
-//            if(i%(uniqueCrossSectionPoints*3) == (uniqueCrossSectionPoints*3-1))
-//                 System.out.println();
-//            else if(i%3 == 2)
-//                 System.out.print("\t");
-//            else System.out.print(",\t");
-//            if(i%3 == 0) i++;
-            if      (((i+1)%(3*numCrossSection) == 0) && (i < coords.length - 1))
-                 System.out.print(",\n\n" + "[" + (i+1)/3 + "] "); // skip 2 lines every numCrossSection coordinates, except at end
-            else if (((i+1)%3  == 0) && (i < coords.length - 1))   // 3 coordinates per line
-                 System.out.print(",\n"   + "[" + (i+1)/3 + "] "); // skip 1 line, except at end
-            else System.out.print(",\t");
-        }
-        System.out.println("\n=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~");
-    }
-    /**
-     * Just a helper method that may prove useful for debugging purposes.
-     */
-    private void printIndices(){
-        System.out.println("printIndices: ");
-        if (coordIndex.length == 0)
-           System.out.println("none");
-        for(int i = 0; i < coordIndex.length; i++){
-            if(coordIndex[i] == -1)
-                 System.out.println(coordIndex[i] + ",");
-            else System.out.print(  coordIndex[i] + ",\t");
-        }
-        System.out.println("\n=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~");
-    }
-
-    /**
-     * Just a helper method that may prove useful for debugging purposes.
-     */
-    private void printSpines(){
-        System.out.println("printSpines: ");
-        if (spines.length == 0)
-           System.out.println("none");
-        for(int i = 0; i < spines.length; i++){
-            System.out.print("[" + i + "] " + spines[i]);
-            if ((i+1)%10 == 0)
-                 System.out.print(",\n\n"); // skip 2 lines
-            else if ((i+1)%5  == 0)
-                 System.out.print(",\n"  ); // skip 1 line
-            else System.out.print(",\t");
-        }
-        if (spineClosed)
-             System.out.println("\nspine is closed");
-        else System.out.println("\nspine is open");
-        System.out.println("=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~");
-    }
-
-    /**
-     * Debug diagnostics
-     */
-    @SuppressWarnings("DeadBranch")
-    private void printDebugMessagesToConsole ()
-    {
-        // debug
-        System.out.println("\n=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~");
-        if (false) // compile unused invocations to avoid IDE warnings
-        {
-            printCrossSectionPoints();
-            printSpines();
-            printIndices();
-            printCoords();
-        }
-        printCrossSectionPoints();
-        printSpines();
-        printIndices();
-        printCoords();
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.renderer.ogl.nodes.geom3d;
+
+// External imports
+import javax.vecmath.*;
+
+import org.j3d.aviatrix3d.*;
+
+import org.j3d.geom.GeometryData;
+
+// Local import
+import org.web3d.vrml.lang.*;
+
+import org.web3d.vrml.nodes.VRMLNodeType;
+import org.web3d.vrml.renderer.common.nodes.geom3d.BaseExtrusion;
+import org.web3d.vrml.renderer.common.nodes.GeometryUtils;
+import org.web3d.vrml.renderer.common.nodes.GeometryHolder;
+import org.web3d.vrml.renderer.ogl.nodes.OGLGeometryNodeType;
+
+/**
+ * OpenGL implGeomementation of an Extrusion
+ * <p> The 1.16 version of OGLExtrusion generates
+ * end caps correctly for both convex and concave
+ * crossSections.  More thorough testing is needed
+ * to see if textures are handled properly, however.
+ *
+ * @author Justin Couch, Andrzej Kapolka, Rick Goldberg
+ * @version $Revision: 1.20 $
+ */
+public class OGLExtrusion extends BaseExtrusion
+    implements OGLGeometryNodeType, NodeUpdateListener{
+
+    /** Message when we detect a solid of revolution */
+    private static final String SOR_ERR =
+        "Invalid Extrusion data; looks like a solid of revolution";
+
+    /** When the normalisation of the Y axis fails because it is zero length */
+    private static final String Y_NORM_MSG =
+        "Error normalizing Y in Extrusion";
+
+    /** The OpenGL geometry implGeommentation
+     * Previous implementation of OGLExtrusion used an IndexedTriangleStripArray;
+     * more recently implGeom is a TriangleArray.        */
+    private Geometry implGeom;
+
+    /** The number of texture coordinate sets to be set by Shape Class */
+    private int numTexCoordSets;
+    
+    /** The coord array defines the 3D vertices referenced by the coordIndex field. */
+    private float[] coords;
+
+    /** The coordIndex array specifies polygonal faces by indexing into coordinates
+     * in the 'coords' array.  An index of -1 indicates that the current face has
+     * ended and the next one begins.     */
+    private int[] coordIndex;
+
+    /** The Point3f[] version of vfSpine.
+     * One point for every spine.      */
+    private Point3f[] spines;
+
+    /** The Vector3f[] version of vfScale. */
+    private Vector3f[] scales;
+
+    /** The AxisAngle4f[] version of vfOrientation. */
+    private AxisAngle4f[] orientations;
+
+    /** rotations will contain the per spine transform composed with
+     * orientation after the call to calculateSCP(); */
+    private Matrix3f[] rotations;
+    private Matrix4f[] transforms;
+
+    private boolean collinear;
+
+    /** Flag to say normals have changed when updating the geometry */
+    private boolean normalsChanged;
+
+    /** Flag to say texture coords have changed when updating the geometry */
+    private boolean texCoordsChanged;
+
+    /** Flag to say colors have changed when updating the geometry */
+    private boolean colorsChanged;
+
+    /** Did the vbo state change */
+    private boolean vboChanged;
+
+    /** Flag indicating if the spine is closed as a surface of revolution */
+    private boolean spineClosed;
+
+    /** Flag to say if the crossSection is closed or not.
+     * Fundamental enough that it may belong in the base class */
+    boolean crossSectionClosed;
+
+    /** Userdata kept in the triangle geometry */
+    protected GeometryData geomData;
+
+    /** Set to "numCrossSection-1" if(crossSectionClosed)
+     * else equal to numCrossSection.  */
+    int uniqueCrossSectionPoints;
+
+    /**
+     * Construct a default sphere instance
+     */
+    public OGLExtrusion() {
+    }
+
+    /**
+     * Construct a new instance of this node based on the details from the
+     * given node. If the node is not a Box node, an exception will be
+     * thrown.
+     *
+     * @param node The node to copy
+     * @throws IllegalArgumentException The node is not a Group node
+     */
+    public OGLExtrusion(VRMLNodeType node) {
+        super(node);
+    }
+
+    //----------------------------------------------------------
+    // Methods required by the UpdateListener interface.
+    //----------------------------------------------------------
+
+    /**
+     * Notification that its safe to update the node now with any operations
+     * that could potentially effect the node's bounds.
+     *
+     * @param src The node or Node Component that is to be updated.
+     */
+    @Override
+    public void updateNodeBoundsChanges(Object src) {
+        ((VertexGeometry)implGeom).setVertices(  TriangleArray.COORDINATE_3,
+                                                geomData.coordinates,
+                                                geomData.vertexCount);
+    }
+
+    /**
+     * Notification that its safe to update the node now with any operations
+     * that only change the node's properties, but do not change the bounds.
+     *
+     * @param src The node or Node Component that is to be updated.
+     */
+    @Override
+    public void updateNodeDataChanges(Object src) {
+
+/*        if(colorsChanged) {
+            int num_comp =
+                (vfColor == null) ? 0 : vfColor.getNumColorComponents();
+            boolean has_alpha = num_comp == 4;
+
+            implGeom.setColors(has_alpha, geomData.colors);
+            colorsChanged = false;
+
+            if (vfColor == null) {
+                localColors = false;
+            }
+        }
+
+        if(normalsChanged) {*/
+            ((VertexGeometry)implGeom).setNormals(geomData.normals);
+            /*normalsChanged = false;
+        }
+
+        if(texCoordsChanged) {
+            implGeom.setTextureCoordinates(texTypes,
+                                           texCoords,
+                                           numUniqueTexSets);
+            implGeom.setTextureSetMap(texSetMap, numTexSets);
+
+            texCoordsChanged = false;
+        }
+
+        if (vboChanged) {
+            // Only ever change to false after activity
+            implGeom.setVBOEnabled(false);
+
+            vboChanged = false;
+        }*/
+    }
+
+    //-------------------------------------------------------------
+    // Methods used to set implGeom as TriangleArray
+    //-------------------------------------------------------------
+
+    /**
+     * Build the implGeom, set the normals, etc.:
+     * Basically let GeometryUtils do all the work.
+     *
+     * @author Eric Fickenscher
+     */
+    private void buildImplTriangleArray(){
+
+        // convert vrml data to intermediate form
+        initSetup();
+        // calculate per spine SCP transforms
+        // results in transforms[] being filled withs SCP info
+        // complete with scale, translation and orientation from
+        // fields
+        if(!calculateSCP()) return;
+
+        // transform the crossSections to coordinates
+        createExtrusionCoordinates();
+
+        // set coordIndex to create an IndexedFaceSet representing this extrusion
+        createIndicesTriangleArray();
+        //printIndices();
+
+        GeometryUtils gutils = new GeometryUtils();
+        GeometryHolder gholder = new GeometryHolder();
+
+        gutils.generateTriangleArrays(  coords,
+                                        null,   // float[] color
+                                        null,   // float[] normal
+                                        null,   // float[] texture
+                                        1,
+                                        true,   // genTexCoords,
+                                        true,   // genNormals,
+                                        coordIndex,
+                                        coordIndex.length,
+                                        null,   // int[] vfColorIndex,
+                                        null,   // int[] vfNormalIndex,
+                                        null,   // int[] vfTexCoordIndex,
+                                                // TODO : are we obeying the ccw right-hand-
+                                        true,   // rule or not?  this is far different
+                                                // than the meaning of vfCCW!
+                                        vfConvex,
+                                        false,  // colorPerVertex,
+                                        true,   // normalPerVertex,
+                                        0,
+                                        vfCreaseAngle,
+                                        true,   // initialBuild,
+                                        gholder);
+
+        geomData = new GeometryData();
+        //TODO : should initialize vfCCW   // TODO : check for explicit initialization of other fields as well
+        geomData.geometryType = GeometryData.TRIANGLES;
+        gutils.copyData(gholder, geomData);
+
+        if (implGeom.isLive())
+            implGeom.boundsChanged(this);
+        else
+            updateNodeBoundsChanges(implGeom);
+
+        if (implGeom.isLive())
+            implGeom.dataChanged(this);
+        else
+            updateNodeDataChanges(implGeom);
+
+        // Make an array of objects for the texture setting
+        float[][] textures = gholder.textureCoordinates;
+        int[] tex_type = { TriangleArray.TEXTURE_COORDINATE_2 };
+        ((VertexGeometry)implGeom).setTextureCoordinates(tex_type, textures, 1);
+
+        // Setup texture units
+        int[] tex_maps = new int[numTexCoordSets];
+
+        for(int i=0; i < numTexCoordSets; i++)
+            tex_maps[i] = 0;
+
+        ((VertexGeometry)implGeom).setTextureSetMap(tex_maps, numTexCoordSets);
+    }
+
+    /**
+     * Result: Completed "coords" array: An array of all the float information
+     * describing each vertex in the extrusion, created by applying the
+     * transforms to the vfCrossSection points
+     *
+     * @author Eric Fickenscher
+     */
+    private void createExtrusionCoordinates(){
+
+        // calculate the number of coordinates needed for the sides
+        // of the extrusion: 3 coordinates per vertex, one vertex per
+        // crossSectionPoint, and one set of crossSectionPoints per spinePoint
+        coords = new float[ numSpine * uniqueCrossSectionPoints * 3 ];
+
+        for(int i = 0; i < numSpine; i++) {
+
+            Matrix4f tx = transforms[i];
+
+            for(int j = 0; j < uniqueCrossSectionPoints; j++) {
+
+                int ind = (i * uniqueCrossSectionPoints + j) * 3;
+
+                // basically a transform, in place
+                float c_x = vfCrossSection[j*2   ];
+                float c_z = vfCrossSection[j*2 +1];
+
+                float x = c_x * tx.m00 + c_z * tx.m02 + tx.m03;
+                float y = c_x * tx.m10 + c_z * tx.m12 + tx.m13;
+                float z = c_x * tx.m20 + c_z * tx.m22 + tx.m23;
+
+                coords[ind] = x;
+                coords[ind + 1] = y;
+                coords[ind + 2] = z;
+            }
+        }
+    }
+
+    /**
+     * Result: Completed "coordIndex" array: an int array representing an
+     * IndexedFaceSet representation of the extrusion.
+     *
+     * @author Eric Fickenscher
+     */
+    private void createIndicesTriangleArray(){
+
+        int sizeOfCoordIndex = 5*(numCrossSection-1) * (numSpine-1);
+        if( vfBeginCap) sizeOfCoordIndex += uniqueCrossSectionPoints+1;
+        if( vfEndCap)   sizeOfCoordIndex += uniqueCrossSectionPoints+1;
+
+        coordIndex = new int[sizeOfCoordIndex];
+
+        int indx = 0;
+        int curIndex;
+
+        // for each separate segment between two spine points
+        for(int i = 0; i<numSpine-1; i++){
+
+            curIndex = i*uniqueCrossSectionPoints;
+
+            // build a quadrilateral for every crossSection-to-crossSection side around that segment
+            // note that Xj3D wireframe mode shows triangulation even though quads are being built here
+            for(int j = 0; j < numCrossSection-1; j++){
+
+                if(vfCCW){
+                    coordIndex[ indx++ ] = j + curIndex;
+                    coordIndex[ indx++ ] = j + curIndex +1;
+                    coordIndex[ indx++ ] = j + curIndex + uniqueCrossSectionPoints +1;
+                    coordIndex[ indx++ ] = j + curIndex + uniqueCrossSectionPoints;
+                } else {
+                    coordIndex[ indx++ ] = j + curIndex + uniqueCrossSectionPoints;
+                    coordIndex[ indx++ ] = j + curIndex + uniqueCrossSectionPoints +1;
+                    coordIndex[ indx++ ] = j + curIndex +1;
+                    coordIndex[ indx++ ] = j + curIndex;
+                }
+
+                coordIndex[ indx++ ] = -1;
+            }
+
+            if(crossSectionClosed){
+                coordIndex[indx -4] -= uniqueCrossSectionPoints;
+                coordIndex[indx -3] -= uniqueCrossSectionPoints;
+            }
+        }
+        
+        //if spineClosed, then index of last cross section can be changed into index of 1st cross section.
+        if(spineClosed)
+            for(int j = 0; j < uniqueCrossSectionPoints; j++)
+            {
+                coordIndex[indx - j * 5 - 3] -= (uniqueCrossSectionPoints * (numSpine-1));
+                coordIndex[indx - j * 5 - 2] -= (uniqueCrossSectionPoints * (numSpine-1));
+            }
+                
+        // note that Xj3D wireframe mode shows triangulation even though N-sided polygons are being built here
+        if( vfBeginCap) {
+
+            for(int i = 0; i < uniqueCrossSectionPoints; i++){
+                if(vfCCW) coordIndex[ indx++ ] = uniqueCrossSectionPoints -i -1;
+                else coordIndex[ indx++ ] = i;
+            }
+            coordIndex[ indx++ ] = -1;
+        }
+        if( vfEndCap) {
+
+            for(int i = 0; i < uniqueCrossSectionPoints; i++){
+                if(vfCCW) coordIndex[ indx++ ] = (numSpine-1)*uniqueCrossSectionPoints + i;
+                else coordIndex[ indx++ ] = numSpine*uniqueCrossSectionPoints -i -1;
+            }
+            coordIndex[ indx ] = -1;
+        }
+    }
+
+    //-------------------------------------------------------------
+    // Methods defined by OGLGeometryNodeType
+    //-------------------------------------------------------------
+
+    /**
+     * Returns a OGL Geometry node
+     *
+     * @return A Geometry node
+     */
+    @Override
+    public Geometry getGeometry() {
+        return implGeom;
+    }
+
+    /**
+     * Set the number of textures that were found on the accompanying Appearance
+     * node. Used to set the number of texture coordinates that need to be
+     * passed in to the renderer when no explicit texture coordinates were
+     * given.
+     *
+     * @param count The number of texture coordinate sets to add
+     */
+    @Override
+    public void setTextureCount(int count) {
+        numTexCoordSets = count;
+    }
+    
+    /**
+     * Get the number of texture coordinate sets contained by this node
+     *
+     * @return the number of texture coordinate sets
+     */
+    @Override
+    public int getNumSets() {
+        return 0;
+    }
+
+    /**
+     * Get the texture coordinate generation mode.  NULL is returned
+     * if the texture coordinates are not generated.
+     *
+     * @param setNum The set which this tex gen mode refers
+     * @return The mode or NULL
+     */
+    @Override
+    public String getTexCoordGenMode(int setNum) {
+        return null;
+    }
+
+    /**
+     * Set the value of the field at the given index as an array of floats.
+     * This would be used to set MFFloat, SFVec2f, SFVec3f and SFRotation
+     * field types.
+     *
+     * @param index The index of destination field to set
+     * @param value The new value to use for the node
+     * @param numValid The number of valid values to copy from the array
+     * @throws InvalidFieldException The field index is not known
+     * @throws InvalidFieldValueException The value provided is out of range
+     *    for the field type.
+     */
+    @Override
+    public void setValue(int index, float[] value, int numValid)
+        throws InvalidFieldException, InvalidFieldValueException {
+
+        super.setValue(index, value, numValid);
+
+        if(!inSetup)
+            stateManager.addEndOfThisFrameListener(this);
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by FrameStateListener
+    //----------------------------------------------------------
+
+    /**
+     * Notification that the rendering of the event model is complete and that
+     * rendering is about to begin. Used to update the j3d representation
+     * only once per frame.
+     */
+    @Override
+    public void allEventsComplete() {
+        buildImplTriangleArray();
+// TODO private trace variable
+//        printDebugMessagesToConsole ();
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by OGLVRMLNode
+    //----------------------------------------------------------
+
+    /**
+     * Get the Java3D scene graph object representation of this node. This will
+     * need to be cast to the appropriate parent type when being used.
+     *
+     * @return The OGL representation.
+     */
+    @Override
+    public SceneGraphObject getSceneGraphObject() {
+        return implGeom;
+    }
+
+    /**
+     * Notification that the construction phase of this node has finished.
+     * If the node would like to do any internal processing, such as setting
+     * up geometry, then go for it now.
+     */
+    @Override
+    public void setupFinished() {
+        if(!inSetup)
+            return;
+
+        super.setupFinished();
+
+        // if using a TriangleArray instead of an IndexedTriangleStripArray {
+        implGeom = new TriangleArray(true, VertexGeometry.VBO_HINT_STATIC);
+        //OGLUserData u_data = new OGLUserData();
+        //u_data.geometryData = geomData;
+        //implGeom.setUserData(u_data);
+
+        buildImplTriangleArray();
+// TODO private trace variable
+//        printDebugMessagesToConsole ();
+
+        //} else {
+        //    implGeom = new IndexedTriangleStripArray(true, VertexGeometry.VBO_HINT_STATIC);
+        //    buildImpl();
+        //}
+    }
+
+    //-------------------------------------------------------------
+    // Local methods
+    //-------------------------------------------------------------
+
+    /**
+     * Instantiate the various variables needed for processing.
+     */
+    private void initSetup() {
+
+        numTexCoordSets = 0;
+        normalsChanged = false;
+        texCoordsChanged = false;
+        colorsChanged = false;
+        vboChanged = false;
+
+        collinear = false;
+        // spineClosed :   1st Spine == last Spine
+        //              && 1st Scale == last Scale 
+        spineClosed =  (vfSpine[0] == vfSpine[vfSpine.length-3] &&
+                        vfSpine[1] == vfSpine[vfSpine.length-2] &&
+                        vfSpine[2] == vfSpine[vfSpine.length-1] &&
+                        vfScale[0] == vfScale[vfScale.length-2] &&
+                        vfScale[1] == vfScale[vfScale.length-1]);
+
+        uniqueCrossSectionPoints = numCrossSection;
+        crossSectionClosed =
+            (vfCrossSection[0] == vfCrossSection[vfCrossSection.length-2] &&
+             vfCrossSection[1] == vfCrossSection[vfCrossSection.length-1]);
+        if(crossSectionClosed) uniqueCrossSectionPoints--;
+
+        if (numSpine != (vfSpine.length / 3)) {
+            errorReporter.warningReport("A numSpine differs from (vfSpine.length/3) at initSetup() in OGLExtrusion.java", null);
+        }
+        
+        // Convert the spine array into a Point3f array for
+        // easier manipulation later
+        spines = new Point3f[numSpine];
+        for(int i = 0; i < spines.length; i++) {
+            spines[i] = new Point3f(vfSpine[i * 3],
+                                    vfSpine[i * 3 + 1],
+                                    vfSpine[i * 3 + 2]);
+        }
+
+        // Convert the orientation points so they match specification
+        //
+        // Note: if the number of scale or orientation points is greater
+        // than the number of spine points, the excess values are ignored.
+        // If they contain one value, it is applied at all spine points.
+        // (results are 'undefined' if the number of sets of scale or orientation
+        // values is greater than one but less than the number of spine
+        // points... in such a case, we repeat the final set of values for
+        // the remainder of spine points)
+        orientations = new AxisAngle4f[numSpine];
+        for(int i = 0; i < orientations.length; i++) {
+            if(i * 4 + 3 < vfOrientation.length)
+                orientations[i] = new AxisAngle4f(
+                    vfOrientation[i * 4],
+                    vfOrientation[i * 4 + 1],
+                    vfOrientation[i * 4 + 2],
+                    vfOrientation[i * 4 + 3]
+               );
+            else
+                orientations[i] = new AxisAngle4f(orientations[i-1]);
+        }
+
+        // Convert the scale points so they match specification
+        //
+        // Note that scales are really just 2D scalars,
+        // but this version uses a 3f for some reason,
+        // leaving the "y" value as 1.
+        scales = new Vector3f[numSpine];
+        for(int i = 0; i < scales.length; i++) {
+            if(i * 2 + 1 < vfScale.length)
+                scales[i] = new Vector3f(vfScale[i * 2],
+                                         1,
+                                         vfScale[i * 2 + 1]);
+            else  // if vfScale.length is short, copy previous scale.
+                scales[i] = new Vector3f(scales[i-1]); 
+        }
+
+        rotations = new Matrix3f[vfSpine.length / 3];
+
+        // if entirely collinear
+        Vector3d v2 = new Vector3d();
+        Vector3d v1 = new Vector3d();
+        Vector3d v0 = new Vector3d();
+        double d = 0;
+        for(int i = 1; i < spines.length - 1; i++) {
+            v2.set(spines[i+1]);
+            v1.set(spines[i]);
+            v0.set(spines[i - 1]);
+            v2.sub(v1);
+            v1.sub(v0);
+            v0.cross(v2,v1);
+            d += v0.dot(v0);
+        }
+
+        collinear = (d == 0);
+    }
+
+    /**
+     * Create the spine information and verify that this is a valid object.
+     *
+     * @return true if everything is valid, false otherwise
+     */
+    private boolean calculateSCP() {
+        // find an orthonormal basis and construct rotation matrix
+        // for each spine. handle special cases in second pass
+        Vector3f u, v;
+
+        int last = numSpine - 1;
+        Vector3f[] x, y, z;
+
+        x = new Vector3f[numSpine];
+        y = new Vector3f[numSpine];
+        z = new Vector3f[numSpine];
+
+        if (collinear) {
+            if (spineClosed) {
+                errorReporter.warningReport(SOR_ERR, null);
+                StringBuilder buf = new StringBuilder("Spine data:");
+
+                for (Point3f spine : spines) {
+                    buf.append(spine);
+                    buf.append(' ');
+                }
+
+                errorReporter.messageReport(buf.toString());
+
+                return false;
+            }
+
+            // Direction is the first spine point that does not equal to
+            // spines[0]
+            Vector3f direction = null;
+            for (Point3f spine : spines) {
+                if (!spines[0].equals(spine)) {
+                    direction = new Vector3f(spine);
+                }
+            }
+
+            y[0] = new Vector3f();
+            if (direction != null) {
+                y[0].sub(direction, spines[0]);
+// fixed NPE C:/x3d-code/www.web3d.org/x3d/content/examples/X3dForWebAuthors/KelpForestExhibit/CircleFishPrototype.wrl
+// https://docs.oracle.com/cd/E17802_01/j2se/javase/technologies/desktop/java3d/forDevelopers/j3dapi/javax/vecmath/Tuple3d.html
+            } else {
+                errorReporter.warningReport("Direction is null at calculateSCP() in OGLExtrusion.java", null);
+            }
+
+            if (!norm(y[0])) {
+                errorReporter.warningReport(Y_NORM_MSG, null);
+            }
+
+            // Create an initial x[0]
+            if (y[0].x == 1) {
+                x[0] = new Vector3f(0, -1, 0);
+            } else if (y[0].x == -1) {
+                x[0] = new Vector3f(0, 1, 0);
+            } else {
+                x[0] = new Vector3f(1, 0, 0);
+            }
+            // Create z[0]
+            z[0] = new Vector3f();
+            z[0].cross(x[0], y[0]);
+
+            // Create final x[0]
+            x[0].cross(y[0], z[0]);
+            for (int i = 1; i < spines.length; i++) {
+                // redo, this should take the direction of y
+                // redone by Pasi Paasiala < < check this >  >
+                x[i] = new Vector3f(x[0]);
+                y[i] = new Vector3f(y[0]);
+                z[i] = new Vector3f(z[0]);
+            }
+        } else { // "collinear" is false
+
+            // find y[i] for all but first and last
+            // most times the exception cases are bad data and hopefully
+            // wont happen. It is free to try catch you later, so hopes
+            // 99% cases will be one if faster by not checking the if
+            for (int i = 1; i < last; i++) {
+                y[i] = new Vector3f();
+                y[i].sub(spines[i + 1], spines[i - 1]);
+                if (!norm(y[i])) {
+                    // spines[i+1] equals spines[i - 1]
+                    y[i].sub(spines[i + 1], spines[i]);
+                    if (!norm(y[i])) {
+                        // spines[i+1] equaled spines[i]
+                        y[i].sub(spines[i], spines[i - 1]);
+                        if (!norm(y[i])) {
+                            // spines[i] equaled spines[i - 1]
+                            // real bad case, do something
+                            int w = i + 2;
+                            while ((w < last + 1) && (spines[i - 1].equals(spines[w]))) {
+                                w++;
+                            }
+                            if (w < last + 1) {
+                                y[i].sub(spines[w], spines[i - 1]);
+                                norm(y[i]); // should never divide by zero here
+                            } else { // worst worst case
+                                y[i] = new Vector3f(0, 1, 0);
+                            }
+                        }
+                    }
+                }
+            } // find y[i] in the case of non-collinear, 
+
+            // y for ends
+            if (spineClosed) {
+                // spineClosed and not collinear - >  not all one point
+                y[0] = new Vector3f();
+                y[0].sub(spines[1], spines[last - 1]);
+                if (!norm(y[0])) {
+                    // bad case that the spine[n-2] == spine[1]
+                    int w = last - 2;
+                    while ((w > 1) && (spines[1].equals(spines[w]))) {
+                        w--;
+                    }
+                    if (w > 1) {
+                        y[0].sub(spines[1], spines[w]);
+                        norm(y[0]); // should never divide by zero here
+                    } else // how did this happen?
+                    {
+                        y[0].set(0, 0, 1);
+                    }
+                }
+                y[last] = new Vector3f(y[0]);
+            } else {
+                y[0] = new Vector3f();
+                y[last] = new Vector3f();
+                y[0].sub(spines[1], spines[0]);
+                if (!norm(y[0])) {
+                    int w = 2;
+                    while ((w < last) && (spines[0].equals(spines[w]))) {
+                        w++;
+                    }
+                    if (w < last) {
+                        y[0].sub(spines[w], spines[0]);
+                        norm(y[0]); // should not divide by zero here
+                    } else {
+                        y[0].set(0, 0, 1);
+                    }
+                }
+                y[last] = new Vector3f();
+                y[last].sub(spines[last], spines[last - 1]);
+
+                if (!norm(y[last])) {
+                    int w = last - 2;
+                    while ((w > -1) && (spines[last].equals(spines[w]))) {
+                        w--;
+                    }
+                    if (w > -1) {
+                        y[last].sub(spines[last], spines[w]);
+                        norm(y[last]);
+                    } else {
+                        y[last].set(0, 0, 1);
+                    }
+                }
+            }
+
+            // now z axis for each spine
+            // first all except first and last
+            boolean recheck = false;
+            for (int i = 1; i < last; i++) {
+                u = new Vector3f();
+                v = new Vector3f();
+                z[i] = new Vector3f();
+                u.sub(spines[i - 1], spines[i]);
+                v.sub(spines[i + 1], spines[i]);
+                // spec seems backwards on u and v
+                // shouldn't it be z[i].cross(u,v)???
+                //z[i].cross(v,u);
+                //-- >  z[i].cross(u,v); is correct < < check this >  >
+                // Modified by Pasi Paasiala (Pasi.Paasiala@solibri.com)
+                // skwon : Modified by Sungmin Kwon (lucidaim@gmail.com)
+                //-- >  z[i].cross(v,u) is correct by right hand rule.
+                z[i].cross(v, u);
+                if (!norm(z[i])) {
+                    recheck = true;
+                }
+            }
+            if (spineClosed) {
+                z[0] = z[last] = new Vector3f();
+                u = new Vector3f();
+                v = new Vector3f();
+                u.sub(spines[last - 1], spines[0]);
+                v.sub(spines[1], spines[0]);
+                try {
+                    // skwon : Modified by Sungmin Kwon (lucidaim@gmail.com)
+                    // z[0].cross(v, u) is correct by right hand rule.
+                    z[0].cross(v, u);
+                    // skwon : z[0] should be normalized.
+                    norm(z[0]);
+                } catch (ArithmeticException ae) {
+                    recheck = true;
+                }
+            } else { // not spineClosed
+                z[0] = new Vector3f(z[1]);
+                z[last] = new Vector3f(z[last - 1]);
+            }
+
+            if (recheck) { // found adjacent collinear spines
+                // first z has no length ?
+                if (z[0].dot(z[0]) == 0) {
+                    for (int i = 1; i < spines.length; i++) {
+                        if (z[i].dot(z[i]) > 0) {
+                            z[0] = new Vector3f(z[i]);
+                        }
+                    }
+                    // test again could be most degenerate of cases
+                    if (z[0].dot(z[0]) == 0) {
+                        z[0] = new Vector3f(0, 0, 1);
+                    }
+                }
+
+                // check rest of z's
+                for (int i = 1; i < last + 1; i++) {
+                    if (z[i].dot(z[i]) == 0) {
+                        z[i] = new Vector3f(z[i - 1]);
+                    }
+                }
+            }
+
+            // finally, do a neighbor comparison
+            // and evaluate the x's
+            for (int i = 0; i < spines.length; i++) {
+                if ((i > 0) && (z[i].dot(z[i - 1]) < 0)) {
+                    z[i].negate();
+                }
+
+                // at this point, y and z should be nice
+                x[i] = new Vector3f();
+
+                //Original was: x[i].cross(z[i],y[i]); < < check this >  >
+                //but it doesn't result in right handed coordinates
+                // Modified by Pasi Paasiala
+                x[i].cross(y[i], z[i]);
+                norm(x[i]);
+            }
+        }
+
+        // should now have orthonormal vectors for each
+        // spine. create the rotation matrix with scale for
+        // each spine. spec is unclear whether a twist imparted
+        // at one of the spines is inherited by its "children"
+        // so assume not.
+        // also, the order looks like SxTxRscpxRo , ie ,
+        // the spec doc looks suspect, double check
+        Matrix3f m = new Matrix3f();
+        transforms = new Matrix4f[spines.length];
+        for (int i = 0; i < spines.length; i++) {
+            rotations[i] = new Matrix3f();
+            // Original had setRow. This is correct < < check this >  >
+            // Modified by Pasi Paasiala
+            rotations[i].setColumn(0, x[i]);
+            rotations[i].setColumn(1, y[i]);
+            rotations[i].setColumn(2, z[i]);
+        }
+
+        // skwon : I am not sure a purpose of correctionRotations[i] matrix
+        //         No correctionRotation brings same result with other viewers.
+        //Matrix3f[] correctionRotations = createCorrectionRotations(z);
+        Vector3f tmp = new Vector3f();
+        // Create the transforms
+        for (int i = 0; i < spines.length; i++) {
+            // skwon : I am not sure a purpose of correctionRotations[i] matrix
+            //         No correctionRotation brings same result with other viewers.
+            //rotations[i].mul(correctionRotations[i]);
+            m.set(orientations[i]);
+            rotations[i].mul(m);
+            transforms[i] = new Matrix4f();
+            transforms[i].setIdentity();
+            
+            // skwon : Modified by Sungmin Kwon (lucidaim@gmail.com)
+            //-->matrix m is contaminated when used for an orientation.
+            //   m must be reset before being used for scaling.
+            //   otherwise, the rest entries from rotation will bother you.
+            m.setZero();;
+            m.m00 = scales[i].x;
+            m.m11 = scales[i].y; // should always be '1'
+            m.m22 = scales[i].z;
+            
+            // skwon : Modified by Sungmin Kwon (lucidaim@gmail.com)
+            //--> ((ROTATION)(ORIENTATION))(SCALE) is correct
+            //    instead of old code : (SCALE)((ROTATION)(ORIENTATION))
+            // [[ old code ]]
+            //m.mul(rotations[i]);
+            //transforms[i].setRotationScale(m);
+            rotations[i].mul(m);
+            transforms[i].setRotationScale(rotations[i]);
+
+            tmp.set(spines[i]);
+            transforms[i].setTranslation(tmp);
+        }
+
+        return true;
+    }
+
+    /**
+     * Creates a rotation for each spine point to avoid twisting of the profile
+     * when the orientation of SCP changes.
+     * This method appears to be a prior bugfix work around that is no longer required. 
+     * @author Pasi Paasiala
+     * @param z the vector containing the z unit vectors for each spine point
+     */
+    @Deprecated 
+    private Matrix3f[] createCorrectionRotations(Vector3f[] z) {
+
+        Matrix3f[] correctionRotations = new Matrix3f[spines.length];
+        correctionRotations[0] = new Matrix3f();
+        correctionRotations[0].setIdentity();
+        AxisAngle4f checkAngle = new AxisAngle4f();
+
+        // testPoint is used to find the angle that gives the smallest distance
+        // between the previous and current rotation. Find a point that is not
+        // in the origin.
+        Point3f testPoint = new Point3f(vfCrossSection[0], 0, vfCrossSection[1]);
+
+        for(int i = 0; i < numCrossSection; i++) {
+            if(vfCrossSection[i*2] != 0 || vfCrossSection[i*2 +1] != 0) {
+                testPoint = new Point3f(vfCrossSection[i*2], 0, vfCrossSection[i*2 +1]);
+                break;
+            }
+        }
+
+        // Fix the orientations by using the angle between previous z and current z
+        for(int i = 1; i < spines.length; i++) {
+            float angle = z[i].angle(z[i - 1]);
+            correctionRotations[i] = correctionRotations[i - 1];
+            if(angle != 0) {
+                correctionRotations[i] = new Matrix3f(correctionRotations[i - 1]);
+                Point3f previous = new Point3f();
+                //Point3f previous = testPoint;
+                // Test with negative angle:
+                Matrix3f previousRotation = new Matrix3f(rotations[i - 1]);
+                previousRotation.mul(correctionRotations[i - 1]);
+                previousRotation.transform(testPoint, previous);
+                Matrix3f delta = new Matrix3f();
+                delta.setIdentity();
+                delta.rotY(-angle);
+                correctionRotations[i].mul(delta);
+
+                Matrix3f negativeRotation = new Matrix3f(rotations[i]);
+                negativeRotation.mul(correctionRotations[i]);
+
+                Point3f pointNegative = new Point3f();
+                negativeRotation.transform(testPoint,pointNegative);
+
+                float distNegative = pointNegative.distance(previous);
+
+                // Test with positive angle
+                delta.rotY(angle*2);
+                correctionRotations[i].mul(delta);
+                Matrix3f positiveRotation = new Matrix3f(rotations[i]);
+                positiveRotation.mul(correctionRotations[i]);
+                Point3f pointPositive = new Point3f();
+                positiveRotation.transform(pointPositive);
+                float distPositive = pointPositive.distance(previous);
+
+                if(distPositive > distNegative) {
+                    // Reset correctionRotations to negative angle
+                    delta.rotY(-angle*2);
+                    correctionRotations[i].mul(delta);
+                }
+
+                // Check that the angle is not more than PI.
+                // If it is subtract PI from angle
+                checkAngle.set(correctionRotations[i]);
+                if(((float)Math.PI - checkAngle.angle) < 0.001) {
+                    correctionRotations[i].rotY((float)(checkAngle.angle - Math.PI));
+                }
+            }
+        }
+
+        return correctionRotations;
+    }
+
+    /**
+     * Variant on the traditional normalisation process. If the length is zero
+     * we've had something go wrong so should let the user know, courtesy of
+     * the return value.
+     *
+     * @param n The vector to normalise
+     * @return false when the vector is zero length
+     */
+    private boolean norm(Vector3f n) {
+
+        float norml = n.x*n.x + n.y*n.y + n.z*n.z;
+
+        if(norml == 0)
+            return false;
+
+        norml = 1 / (float)Math.sqrt(norml);
+
+        n.x *= norml;
+        n.y *= norml;
+        n.z *= norml;
+
+        return true;
+    }
+
+    /**
+     * Just a helper method that may prove useful for debugging purposes.
+     */
+    private void printCrossSectionPoints(){
+        System.out.println("printCrossSectionPoints: ");
+        if (vfCrossSection.length == 0)
+           System.out.println("none");
+        for(int i = 0; i < vfCrossSection.length; i++){
+//            if(vfCrossSection[i] >= 0)
+//                System.out.print(" ");
+            System.out.print("[" + i/2 + "] (" + vfCrossSection[i++]);
+            System.out.print(", " + vfCrossSection[i] + "), ");
+            if(((i+1)/2)%5 == 0)
+                 System.out.println(); // skip line after every 5 pairs
+            else System.out.print("\t");
+        }
+        if (crossSectionClosed)
+             System.out.println("\ncrossSection is closed");
+        else System.out.println("\ncrossSection is open");
+        System.out.println("=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~");
+    }
+    /**
+     * Just a helper method that may prove useful for debugging purposes.
+     */
+    private void printCoords(){
+        System.out.println("printCoords: ");
+        if (coords.length == 0)
+             System.out.println("none");
+        else System.out.print  ("[0] ");
+        for(int i = 0; i < coords.length; i++){
+            System.out.print(coords[i]);
+//            if(i%(uniqueCrossSectionPoints*3) == (uniqueCrossSectionPoints*3-1))
+//                 System.out.println();
+//            else if(i%3 == 2)
+//                 System.out.print("\t");
+//            else System.out.print(",\t");
+//            if(i%3 == 0) i++;
+            if      (((i+1)%(3*numCrossSection) == 0) && (i < coords.length - 1))
+                 System.out.print(",\n\n" + "[" + (i+1)/3 + "] "); // skip 2 lines every numCrossSection coordinates, except at end
+            else if (((i+1)%3  == 0) && (i < coords.length - 1))   // 3 coordinates per line
+                 System.out.print(",\n"   + "[" + (i+1)/3 + "] "); // skip 1 line, except at end
+            else System.out.print(",\t");
+        }
+        System.out.println("\n=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~");
+    }
+    /**
+     * Just a helper method that may prove useful for debugging purposes.
+     */
+    private void printIndices(){
+        System.out.println("printIndices: ");
+        if (coordIndex.length == 0)
+           System.out.println("none");
+        for(int i = 0; i < coordIndex.length; i++){
+            if(coordIndex[i] == -1)
+                 System.out.println(coordIndex[i] + ",");
+            else System.out.print(  coordIndex[i] + ",\t");
+        }
+        System.out.println("\n=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~");
+    }
+
+    /**
+     * Just a helper method that may prove useful for debugging purposes.
+     */
+    private void printSpines(){
+        System.out.println("printSpines: ");
+        if (spines.length == 0)
+           System.out.println("none");
+        for(int i = 0; i < spines.length; i++){
+            System.out.print("[" + i + "] " + spines[i]);
+            if ((i+1)%10 == 0)
+                 System.out.print(",\n\n"); // skip 2 lines
+            else if ((i+1)%5  == 0)
+                 System.out.print(",\n"  ); // skip 1 line
+            else System.out.print(",\t");
+        }
+        if (spineClosed)
+             System.out.println("\nspine is closed");
+        else System.out.println("\nspine is open");
+        System.out.println("=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~");
+    }
+
+    /**
+     * Debug diagnostics
+     */
+    @SuppressWarnings("DeadBranch")
+    private void printDebugMessagesToConsole ()
+    {
+        // debug
+        System.out.println("\n=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~");
+        if (false) // compile unused invocations to avoid IDE warnings
+        {
+            printCrossSectionPoints();
+            printSpines();
+            printIndices();
+            printCoords();
+        }
+        printCrossSectionPoints();
+        printSpines();
+        printIndices();
+        printCoords();
+    }
+}
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geom3d/OGLIndexedFaceSet.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geom3d/OGLIndexedFaceSet.java
index e599ee4e439d5d014e8766940fb82e9f86e8315e..585b740a579defd85b4df8a786c04700b55d98ac 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geom3d/OGLIndexedFaceSet.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geom3d/OGLIndexedFaceSet.java
@@ -28,6 +28,7 @@ import org.web3d.vrml.renderer.common.nodes.GeometryUtils;
 
 /**
  * OpenGL implementation of an IndexedFaceSet.
+ * <p>
  *
  * @author Alan Hudson, Justin Couch
  * @version $Revision: 1.37 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoCoordinate.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoCoordinate.java
index 4000423b552517ef048a1eda141cba38aeb32270..75677576c3442af47d441738b7274a727bff32cc 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoCoordinate.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoCoordinate.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * OpenGL implementation of an GeoCoordinate
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoECParameters.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoECParameters.java
index 9cd81eefa726f35576cc90448c87dbf0f883e750..040fac9a77a0915ff7b29b8fd6bb03e32a6a1786 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoECParameters.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoECParameters.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * OpenGL implementation of an GeoECParameters
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLCCParameters.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLCCParameters.java
index 83436007898ac6ccb599c3be30afd1bd14270ebd..ac88c27003e4badc3025fe8137aba6444a79c15b 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLCCParameters.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLCCParameters.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * OpenGL implementation of an GeoLCCParameters
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLCE3DParameters.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLCE3DParameters.java
index bd2ec0539090eb6732d7ea89a44552cebcd4d941..8170cd0c69657717d88961d9d1b780a50eb33abc 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLCE3DParameters.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLCE3DParameters.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * OpenGL implementation of an GeoLCE3DParameters
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLOD.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLOD.java
index 82c7b5561dbb56a358c2bbc0b8a8e519bc21ec79..a1d8a8f10b0a94de21c2e61262665c5fd9088a0e 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLOD.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLOD.java
@@ -31,7 +31,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVisibilityListener;
 import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
- * OpenGL-renderer implementation of a GeoLOD node.
+ * OpenGL-renderer implementation of a GeoLOD node. <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.15 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLSR3DParameters.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLSR3DParameters.java
index 335d0d0696e9c9fcbc9017b9aca17abc6fa6e6d3..45b736e599e495d1040e43802d46e24c34250b76 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLSR3DParameters.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLSR3DParameters.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoLSR3DParameters;
 import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
- * OpenGL implementation of an GeoLSR3DParameters.
+ * OpenGL implementation of an GeoLSR3DParameters
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLTSEParameters.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLTSEParameters.java
index 38cd04e44c4c03fc3aed30ebf27af2477f83acec..a2cc88c436710e90b8f8ed8f4b23c4e083698c87 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLTSEParameters.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLTSEParameters.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoLTSEParameters;
 import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
- * OpenGL implementation of an GeoLTSEParameters.
+ * OpenGL implementation of an GeoLTSEParameters
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLocalTangentParameters.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLocalTangentParameters.java
index ea4652bd1b8dbdfdd8f685478e72517a043af166..969c819c6ebf314970cd01345c10f49ec9481af6 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLocalTangentParameters.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLocalTangentParameters.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoLocalTangentParame
 import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
- * OpenGL implementation of an GeoLocalTangentParameters.
+ * OpenGL implementation of an GeoLocalTangentParameters
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLocation.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLocation.java
index 0106907a0c4c00418d1a6b30bf82c03d81a402e4..c4d90d3157c5da11740a973983c2119dbf4deb4c 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLocation.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoLocation.java
@@ -39,7 +39,8 @@ import org.web3d.vrml.renderer.common.geospatial.GTTransformUtils;
 
 
 /**
- * OpenGL implementation of an GeoLocation.
+ * OpenGL implementation of an GeoLocation
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.11 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoMParameters.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoMParameters.java
index 42b627d9d190843130acd355fe97dced1ff5ca66..b3fe190caf62a22ba1f51816490dc95d3a4008cc 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoMParameters.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoMParameters.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoMParameters;
 import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
- * OpenGL implementation of an GeoMParameters.
+ * OpenGL implementation of an GeoMParameters
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoMetadata.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoMetadata.java
index df261edfa319cb689cc0f8b2ffc1c14e989958aa..46ad1e060ea086dfb8331045a4c69d72503b0bd6 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoMetadata.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoMetadata.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoMetadata;
 import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
- * OpenGL implementation of an GeoMetadata.
+ * OpenGL implementation of an GeoMetadata
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoObliqueMercatorParameters.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoObliqueMercatorParameters.java
index c5ee58fd55517f75cb68d870cb0d279365122c8d..7591fa689469927ac782eb62a6c5a827bf996777 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoObliqueMercatorParameters.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoObliqueMercatorParameters.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoObliqueMercatorPar
 import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
- * OpenGL implementation of an ObliqueMercatorParameters.
+ * OpenGL implementation of an ObliqueMercatorParameters
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoOrigin.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoOrigin.java
index 9cd2b711ebe02ea0f78a1ceb52e9ec8e2c5b3e57..f6f266bfb7f23a8ab96548bf30e3088d7899b24b 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoOrigin.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoOrigin.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoOrigin;
 import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
- * OpenGL implementation of an GeoOrigin.
+ * OpenGL implementation of an GeoOrigin
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoPSParameters.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoPSParameters.java
index a7279bd58be07028db76f6e60dfc36e0a553565a..4368d60ebc661e6dd5e4a99480ba3baebf5e38de 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoPSParameters.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoPSParameters.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoPSParameters;
 import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
- * OpenGL implementation of an GeoPSParameters.
+ * OpenGL implementation of an GeoPSParameters
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoPositionInterpolator.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoPositionInterpolator.java
index 3ba39e7b18b99e16915deef43c03bcc25feaa968..6cc02af051031b2550cefb0983b6424151f6e5cc 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoPositionInterpolator.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoPositionInterpolator.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoPositionInterpolat
 import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
- * OpenGL implementation of an GeoPositionInterpolator.
+ * OpenGL implementation of an GeoPositionInterpolator
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoReferenceSurfaceInfo.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoReferenceSurfaceInfo.java
index cb4aefa0e671ce9963cf94c1d06173d5200fc844..fd87e1af8a5dd100dc74ce3b160f407504e9ebf7 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoReferenceSurfaceInfo.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoReferenceSurfaceInfo.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoReferenceSurfaceIn
 import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
- * OpenGL implementation of an GeoReferenceSurfaceInfo.
+ * OpenGL implementation of an GeoReferenceSurfaceInfo
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoSRFInstance.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoSRFInstance.java
index 8d359e53c575c36ae2c9ef790c4c57c89a449e95..69c379b188b596d0f6a3755c1508569d46fe71ac 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoSRFInstance.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoSRFInstance.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoSRFInstance;
 import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
- * OpenGL implementation of an GeoSRFInstance.
+ * OpenGL implementation of an GeoSRFInstance
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoSRFParametersInfo.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoSRFParametersInfo.java
index 96ed9238c777267d6e0641e9541f757e810c588d..4da2b3b587ecf6fedcbfc7683f56b64afa2f175a 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoSRFParametersInfo.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoSRFParametersInfo.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoSRFParametersInfo;
 import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
- * OpenGL implementation of an GeoSRFParametersInfo.
+ * OpenGL implementation of an GeoSRFParametersInfo
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoSRFSet.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoSRFSet.java
index 9157191b46d54d4aaef3717253ae1fc3b10bb4de..c9c9d2b936f9fc413175b452b98569b027b27ac3 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoSRFSet.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoSRFSet.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoSRFSet;
 import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
- * OpenGL implementation of an GeoSRFSet.
+ * OpenGL implementation of an GeoSRFSet
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoSRFTemplate.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoSRFTemplate.java
index bbe93a83c9dc4ded4b5e4c0f64c0ed0a2b2943d0..74d573e143b4645f3b2f1495d09ddf3bee9f1007 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoSRFTemplate.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoSRFTemplate.java
@@ -21,8 +21,9 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoSRFTemplate;
 import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
- * OpenGL implementation of an GeoSRFTemplate.
- * 
+ * OpenGL implementation of an GeoSRFTemplate
+ * <p>
+ *
  * @author Justin Couch
  * @version $Revision: 1.1 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoTMParameters.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoTMParameters.java
index e3d0b4169faaaa2cb35bfda30a9418a7c328cf34..1a9cb3f67a18d9953f58e4f85df0d9ca817eb7da 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoTMParameters.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoTMParameters.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoTMParameters;
 import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
- * OpenGL implementation of an GeoTMParameters.
+ * OpenGL implementation of an GeoTMParameters
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoTouchSensor.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoTouchSensor.java
index 037c8e1c8a6a7b369515e69cdba9f6dde325de1e..5cf22216b9f6e549c60f2efdeab4c1612f9393fa 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoTouchSensor.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoTouchSensor.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoTouchSensor;
 import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
- * OpenGL implementation of an GeoTouchSensor.
+ * OpenGL implementation of an GeoTouchSensor
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoTransform.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoTransform.java
index 4760a4fbfcb8b481cd743e64b1b8c59019948df7..ced7adc7a2720e1ba5f35f9560f007a6d8a99177 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoTransform.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoTransform.java
@@ -34,6 +34,7 @@ import org.web3d.vrml.renderer.common.nodes.geospatial.BaseGeoTransform;
 
 /**
  * OpenGL implementation of a GeoTransform node.
+ * <p>
  *
  * @author Rex Melton
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoViewpoint.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoViewpoint.java
index fc2316d69203884819841b3fb5c0f9ca6173778f..52fa79e13cb29572f461a410c40acf1895f86e84 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoViewpoint.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/geospatial/OGLGeoViewpoint.java
@@ -33,7 +33,8 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLUserData;
 import org.xj3d.core.eventmodel.OriginListener;
 
 /**
- * OpenGL implementation of an GeoViewpoint.
+ * OpenGL implementation of an GeoViewpoint
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.12 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/group/OGLGroup.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/group/OGLGroup.java
index 3b13c9af6571a4bff99098f4040b435ab2028ff6..294924ba42fc27a4256721a435f668f03e248583 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/group/OGLGroup.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/group/OGLGroup.java
@@ -37,6 +37,7 @@ import org.web3d.vrml.renderer.common.nodes.group.BaseGroup;
 
 /**
  * OpenGL implementation of a Group node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.22 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/group/OGLMatrixTransform.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/group/OGLMatrixTransform.java
index 7f1ef228ddad5e9d24259c3e7fe29bcf5e812982..1072368f2fe4c8fa05246950c6e480758631aae0 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/group/OGLMatrixTransform.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/group/OGLMatrixTransform.java
@@ -34,6 +34,7 @@ import org.web3d.vrml.renderer.common.nodes.group.BaseMatrixTransform;
 
 /**
  * OpenGL implementation of a MatrixTransform node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/group/OGLStaticGroup.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/group/OGLStaticGroup.java
index c85d780b2f574c36c1b9c79319ed4d5f0cc91788..f284be0d047c0f03d416b92ed6d085beac70378e 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/group/OGLStaticGroup.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/group/OGLStaticGroup.java
@@ -33,6 +33,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * OpenGL implementation of a StaticGroup node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.9 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/group/OGLTransform.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/group/OGLTransform.java
index eab8372a35d35b9069419299544f4ad470b9e6b4..94cbf885d96f707ea47c0319ec91abec702a31c0 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/group/OGLTransform.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/group/OGLTransform.java
@@ -34,6 +34,7 @@ import org.web3d.vrml.renderer.common.nodes.group.BaseTransform;
 
 /**
  * OpenGL implementation of a Transform node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.32 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/hanim/OGLHAnimJoint.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/hanim/OGLHAnimJoint.java
index 24df4344291027a0aa49987d5ad6c9ba79f5648c..780590ba2341172c2d2b2c890aa1b0bae8aae94c 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/hanim/OGLHAnimJoint.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/hanim/OGLHAnimJoint.java
@@ -32,6 +32,7 @@ import org.web3d.vrml.renderer.common.nodes.hanim.BaseHAnimJoint;
 
 /**
  * OpenGL implementation of a HAnimJoint node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 2.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/hanim/OGLHAnimSegment.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/hanim/OGLHAnimSegment.java
index 78350890cf1754efcb96224effdd9086c5d26137..7e70dc7710e52f8c6e17b004b3f8cce6e8d87fec 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/hanim/OGLHAnimSegment.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/hanim/OGLHAnimSegment.java
@@ -35,6 +35,7 @@ import org.web3d.vrml.renderer.common.nodes.hanim.BaseHAnimSegment;
 
 /**
  * OpenGL implementation of a HAnimSegment node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 2.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/hanim/OGLHAnimSite.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/hanim/OGLHAnimSite.java
index 14b48ff29b0e4e487b86eb79415541627d1c0db2..d9f812e98221100edb2c2516376e3291338745db 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/hanim/OGLHAnimSite.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/hanim/OGLHAnimSite.java
@@ -35,6 +35,7 @@ import org.web3d.vrml.renderer.common.nodes.hanim.BaseHAnimSite;
 
 /**
  * OpenGL implementation of a HAnimSite node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 2.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLColorInterpolator.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLColorInterpolator.java
index 47ac038c291f67ef564f8d9f2ef3dea762ac53d9..d05aae4ef0f5d66ad0ed34e460cb984f908e84bd 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLColorInterpolator.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLColorInterpolator.java
@@ -23,7 +23,8 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of a ColorInterpolator.
- * 
+ * <p>
+ *
  * @author Justin Couch
  * @version $Revision: 1.5 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLCoordinateInterpolator.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLCoordinateInterpolator.java
index 7b2359bdbac2d32fe627bb72929055f19c863ee7..186c9195f120692c7b4dcf3343e3e43abc6c1c5c 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLCoordinateInterpolator.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLCoordinateInterpolator.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of a CoordinateInterpolator.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLCoordinateInterpolator2D.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLCoordinateInterpolator2D.java
index 963c99661fed86db755d844856a570544abe46b6..96bc6adbff268883b6e20d0d73adba47270c4b75 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLCoordinateInterpolator2D.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLCoordinateInterpolator2D.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of a CoordinateInterpolator2D.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLNormalInterpolator.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLNormalInterpolator.java
index 3543ee60a360297c4eca4228859464ed7db5b044..127094d37767d1e1e01f65b57a49a31779f6a61c 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLNormalInterpolator.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLNormalInterpolator.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of a NormalInterpolator.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLOrientationInterpolator.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLOrientationInterpolator.java
index bce3f1a9f25d4fa85218eebe50f6d6ed86bde452..cd56865cbe530ff85c1bcc1800ea3b5f9c455d3c 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLOrientationInterpolator.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLOrientationInterpolator.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of a OrientationInterpolator.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLPositionInterpolator.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLPositionInterpolator.java
index b33c77681a215015abe289f2a2e63de9b1cbe235..6b56d7897a29fb27ec49255a3da2e134e09c844e 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLPositionInterpolator.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLPositionInterpolator.java
@@ -23,6 +23,8 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of the PositionIterpolator.
+ * <p>
+ *
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLPositionInterpolator2D.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLPositionInterpolator2D.java
index a9e5781d573522bb33c8d0220d2f21baab1a0c28..0d8b56d1e7d658aedacc49a796c4c762c42e999d 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLPositionInterpolator2D.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLPositionInterpolator2D.java
@@ -23,7 +23,9 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of the PositionIterpolator.
- * 
+ * <p>
+ *
+ *
  * @author Justin Couch
  * @version $Revision: 1.2 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLScalarInterpolator.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLScalarInterpolator.java
index d1a23e224dfb7b6bb3ce2d235a3744c3e0e6298f..6b83ed6b5e5fe675e4609e39a3018e5c6a5ccc4d 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLScalarInterpolator.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/interpolator/OGLScalarInterpolator.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of the VRML ScalarInterpolator node.
+ * <p>
  *
  *
  * @author Justin Couch
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/layering/OGLCustomViewport.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/layering/OGLCustomViewport.java
index 008768fdc0197dd84e4df6e59502265428740fd9..361764684e86b38f9255e95e6a9dc4234ba2e8ad 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/layering/OGLCustomViewport.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/layering/OGLCustomViewport.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of the CustomViewport.
+ * <p>
  *
  *
  * @author Justin Couch
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/layering/OGLFixedViewport.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/layering/OGLFixedViewport.java
index 21a216976b9a484b4755a14a260d3e2cee5a72ce..452f2fe2e905dddb0118c3823b9c8ccaedf881a0 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/layering/OGLFixedViewport.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/layering/OGLFixedViewport.java
@@ -23,7 +23,9 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of the FixedViewport.
- * 
+ * <p>
+ *
+ *
  * @author Justin Couch
  * @version $Revision: 1.1 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/layering/OGLLayer.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/layering/OGLLayer.java
index c1ebb4a391a0a2fe976b9ddd94464633bf97cd44..69383b4f401fd8022bb8a6e7252f1b65e7305b04 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/layering/OGLLayer.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/layering/OGLLayer.java
@@ -32,6 +32,8 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * OpenGL Implementation of the Layer node.
+ * <p>
+ *
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/layering/OGLLayerSet.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/layering/OGLLayerSet.java
index 9d6b2cc46ef6c351aaa824c15020f8bbd013ea41..0a3ff6395c1b7d87bb46656764e439a356bb3348 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/layering/OGLLayerSet.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/layering/OGLLayerSet.java
@@ -23,6 +23,8 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of the LayerSet.
+ * <p>
+ *
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/layering/OGLProportionalViewport.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/layering/OGLProportionalViewport.java
index 2262eaefea93e8d325173a71a00b0c168ff7e4ff..72fc42fd31564e395cf11730e094266729cbc17d 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/layering/OGLProportionalViewport.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/layering/OGLProportionalViewport.java
@@ -23,7 +23,9 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of the ProportionalViewport.
- * 
+ * <p>
+ *
+ *
  * @author Justin Couch
  * @version $Revision: 1.1 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/lighting/OGLDirectionalLight.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/lighting/OGLDirectionalLight.java
index 650c0d505c731271b7988a00b44736e9fa13a86d..84056993c653342ff64963daa1e70f505a6827ce 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/lighting/OGLDirectionalLight.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/lighting/OGLDirectionalLight.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLLightNodeType;
 
 /**
  * OpenGL implementation of a directional light.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.8 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/lighting/OGLPointLight.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/lighting/OGLPointLight.java
index c5de861d47ac473b487327cb29ef0f859bb03309..ac42910c822d7382b8b63344776742b2182fc0c0 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/lighting/OGLPointLight.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/lighting/OGLPointLight.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLLightNodeType;
 
 /**
  * OpenGL implementation of a pointlight.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.11 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/lighting/OGLSpotLight.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/lighting/OGLSpotLight.java
index cebe4953c128d24b916efc27fcbbcbe0e6951a34..7d9ab5d26c8dc6ef232c0f03463587a523f0f585 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/lighting/OGLSpotLight.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/lighting/OGLSpotLight.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLLightNodeType;
 
 /**
  * OpenGL implementation of a spotlight.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.11 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/marker/OGLScreenMarker.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/marker/OGLScreenMarker.java
index 9a43f99a3f676ae0825ff67a97bea525e213f1c4..0a66f0aaf5d266e5de09ee9c507e37c19f9454cf 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/marker/OGLScreenMarker.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/marker/OGLScreenMarker.java
@@ -42,6 +42,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * OpenGL-renderer implementation of a ScreenMarker node.
+ * <p>
  *
  * @author Rex Melton
  * @version $Revision: 1.8 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/navigation/OGLBillboard.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/navigation/OGLBillboard.java
index 6b60b295b2861fb143d3ca64a1031baba1d18322..20f731b95748ef59f62ab3338682101bbac53ceb 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/navigation/OGLBillboard.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/navigation/OGLBillboard.java
@@ -45,6 +45,7 @@ import org.web3d.vrml.renderer.common.nodes.navigation.BaseBillboard;
 
 /**
  * OpenGL-renderer implementation of a Billboard node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.18 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/navigation/OGLNavigationInfo.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/navigation/OGLNavigationInfo.java
index 78088a115080da11f67764d02fe71f425eac61a3..2a81a81b46bc3b3dda798c1727b5dc777d5cc426 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/navigation/OGLNavigationInfo.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/navigation/OGLNavigationInfo.java
@@ -22,11 +22,13 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Null renderer implementation of a NavigationInfo node.
+ * <p>
  *
  * The NavigationInfo node does not occupy a space in the Java 3D
  * scene graph. This is used as a VRML construct only. When VRML changes the
  * values here, we pass them back courtesy of the listeners to the children
  * nodes.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.4 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/networking/OGLLoadSensor.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/networking/OGLLoadSensor.java
index 988e0e4e013365bbbaa7b6f83e7aef2a2a4112b1..1aed5faddfdd80918ccf75d3b40e57704b056702 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/networking/OGLLoadSensor.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/networking/OGLLoadSensor.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * OpenGL implementation of a LoadSensor node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/nurbs/OGLContourPolyline2D.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/nurbs/OGLContourPolyline2D.java
index 25e076faa235d59253e0139a24b4bf3aeae85ad2..778d0ae9253900b061ba98c078dcc36a2d1fc5f3 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/nurbs/OGLContourPolyline2D.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/nurbs/OGLContourPolyline2D.java
@@ -1,44 +1,44 @@
-package org.web3d.vrml.renderer.ogl.nodes.nurbs;
-
-import org.j3d.aviatrix3d.Geometry;
-import org.j3d.aviatrix3d.SceneGraphObject;
-import org.web3d.vrml.renderer.common.nodes.nurbs.BaseContourPolyline2D;
-import org.web3d.vrml.renderer.ogl.nodes.OGLGeometryNodeType;
-
-import net.jgeom.nurbs.UVCoord2f;
-
-public class OGLContourPolyline2D extends BaseContourPolyline2D implements
-        TrimSegment, OGLGeometryNodeType {
-
-    public OGLContourPolyline2D() {
-    }
-
-    @Override
-    public void setupFinished() {
-        super.setupFinished();
-    }
-
-    @Override
-    public void setQuality(float q) {
-    }
-
-    @Override
-    public UVCoord2f[] getPoints() {
-        UVCoord2f[] retVal = new UVCoord2f[vfControlPoint.length / 2];
-        for (int i = 0, j = 0; i < vfControlPoint.length; i += 2, j++) {
-            retVal[j] = new UVCoord2f((float) vfControlPoint[i], (float) vfControlPoint[i + 1]);
-        }
-        return retVal;
-    }
-
-    @Override
-    public Geometry getGeometry() {
-
-        return null;
-    }
-
-    @Override
-    public SceneGraphObject getSceneGraphObject() {
-        return null;
-    }
-}
+package org.web3d.vrml.renderer.ogl.nodes.nurbs;
+
+import org.j3d.aviatrix3d.Geometry;
+import org.j3d.aviatrix3d.SceneGraphObject;
+import org.web3d.vrml.renderer.common.nodes.nurbs.BaseContourPolyline2D;
+import org.web3d.vrml.renderer.ogl.nodes.OGLGeometryNodeType;
+
+import net.jgeom.nurbs.UVCoord2f;
+
+public class OGLContourPolyline2D extends BaseContourPolyline2D implements
+        TrimSegment, OGLGeometryNodeType {
+
+    public OGLContourPolyline2D() {
+    }
+
+    @Override
+    public void setupFinished() {
+        super.setupFinished();
+    }
+
+    @Override
+    public void setQuality(float q) {
+    }
+
+    @Override
+    public UVCoord2f[] getPoints() {
+        UVCoord2f[] retVal = new UVCoord2f[vfControlPoint.length / 2];
+        for (int i = 0, j = 0; i < vfControlPoint.length; i += 2, j++) {
+            retVal[j] = new UVCoord2f((float) vfControlPoint[i], (float) vfControlPoint[i + 1]);
+        }
+        return retVal;
+    }
+
+    @Override
+    public Geometry getGeometry() {
+
+        return null;
+    }
+
+    @Override
+    public SceneGraphObject getSceneGraphObject() {
+        return null;
+    }
+}
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/nurbs/OGLNurbsCurve.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/nurbs/OGLNurbsCurve.java
index 8a4fc4ac745bc11748cc9ebfc5340cabc94231d7..8c1d18c6c31a7e097ab88fca906d7ce7d58cb600 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/nurbs/OGLNurbsCurve.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/nurbs/OGLNurbsCurve.java
@@ -1,122 +1,122 @@
-package org.web3d.vrml.renderer.ogl.nodes.nurbs;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import net.jgeom.nurbs.BasicNurbsCurve;
-import net.jgeom.nurbs.ControlPoint4f;
-import net.jgeom.nurbs.MeshedNurbsCurve;
-import net.jgeom.nurbs.evaluators.BasicNurbsCurveEvaluator;
-import net.jgeom.nurbs.geomContainers.LineStripArray;
-
-import org.j3d.aviatrix3d.Geometry;
-import org.j3d.aviatrix3d.SceneGraphObject;
-import org.j3d.aviatrix3d.VertexGeometry;
-import org.web3d.vrml.renderer.common.nodes.nurbs.BaseNurbsCurve;
-import org.web3d.vrml.renderer.ogl.nodes.OGLGeometryNodeType;
-
-public class OGLNurbsCurve extends BaseNurbsCurve implements
-        OGLGeometryNodeType {
-
-    private org.j3d.aviatrix3d.LineStripArray impl;
-
-    public OGLNurbsCurve() {
-    }
-
-    @Override
-    public Geometry getGeometry() {
-        return impl;
-    }
-
-    @Override
-    public SceneGraphObject getSceneGraphObject() {
-        return impl;
-    }
-
-    @Override
-    public void setupFinished() {
-
-        float[] vfControlPoint = new float[0];
-        if (vfCoord != null && vfCoord.getNumPoints() > 0) {
-            vfControlPoint = new float[vfCoord.getNumPoints()];
-            vfCoord.getPoint(vfControlPoint);
-        } else {
-            System.out.println("OGLNurbsCurve.setupFinished: null Coordinates node");
-        }
-
-        impl = new org.j3d.aviatrix3d.LineStripArray(true,
-                VertexGeometry.VBO_HINT_STATIC);
-        List<ControlPoint4f> cpsa = new ArrayList<>();
-        int dimension = vfControlPoint.length / 3;
-        {
-            for (int i = 0; i < dimension; i++) {
-                float wt;
-                if (vfWeight != null && vfWeight.length > i) {
-                    wt = (float) vfWeight[i];
-                } else {
-                    wt = (float) 1.0;
-                }
-
-                float winv = ((float) 1.0) / wt;
-
-                cpsa.add(new ControlPoint4f(
-                        vfControlPoint[3 * i] * winv,
-                        vfControlPoint[3 * i + 1] * winv,
-                        vfControlPoint[3 * i + 2] * winv,
-                        winv));
-            }
-        }
-        ControlPoint4f cps[] = new ControlPoint4f[cpsa.size()];
-        cpsa.toArray(cps);
-
-        //recompute knot vector if not supplied or wrong size
-//		boolean computeKnot = false;
-        float uk[];
-        if (this.vfKnot != null) {
-            uk = new float[this.vfKnot.length];
-            for (int i = 0; i < uk.length; i++) {
-                uk[i] = (float) vfKnot[i];
-            }
-        } else {    // compute  a uniform knot
-            int Nk = dimension + vfOrder;   // number of knot values (including extraneous)
-            uk = new float[Nk];
-            int ic = 0;
-            for (; ic < vfOrder; ic++) {
-                uk[ic] = (float) 0.0;
-            }
-            int Nseg = dimension - vfOrder + 1; // number of internal segments
-            float delt = (float) 1.0 / Nseg;
-            for (int iseg = 1; iseg < Nseg; iseg++, ic++) {
-                uk[ic] = iseg * delt;
-            }
-            for (; ic < Nk; ic++) {
-                uk[ic] = (float) 1.0;
-            }
-        }
-
-
-        BasicNurbsCurve nc = new BasicNurbsCurve(cps, uk, this.vfOrder - 1);
-
-        MeshedNurbsCurve mnc = new MeshedNurbsCurve(nc);
-        mnc.setEvaluator(new BasicNurbsCurveEvaluator());
-
-        LineStripArray ga = (LineStripArray) mnc.getMeshedCurve();
-        float[] coordinates = new float[ga.getValidVertexCount() * 3];
-        ga.getCoordinates(0, coordinates);
-
-        impl.setVertices(VertexGeometry.COORDINATE_3,
-                coordinates);
-
-        impl.setStripCount(new int[]{coordinates.length / 3}, 1);
-
-        super.setupFinished();
-    }
-
-    @Override
-    public void render() {
-    }
-
-    @Override
-    public void set_renderer(Object renderer) {
-    }
-}
+package org.web3d.vrml.renderer.ogl.nodes.nurbs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.jgeom.nurbs.BasicNurbsCurve;
+import net.jgeom.nurbs.ControlPoint4f;
+import net.jgeom.nurbs.MeshedNurbsCurve;
+import net.jgeom.nurbs.evaluators.BasicNurbsCurveEvaluator;
+import net.jgeom.nurbs.geomContainers.LineStripArray;
+
+import org.j3d.aviatrix3d.Geometry;
+import org.j3d.aviatrix3d.SceneGraphObject;
+import org.j3d.aviatrix3d.VertexGeometry;
+import org.web3d.vrml.renderer.common.nodes.nurbs.BaseNurbsCurve;
+import org.web3d.vrml.renderer.ogl.nodes.OGLGeometryNodeType;
+
+public class OGLNurbsCurve extends BaseNurbsCurve implements
+        OGLGeometryNodeType {
+
+    private org.j3d.aviatrix3d.LineStripArray impl;
+
+    public OGLNurbsCurve() {
+    }
+
+    @Override
+    public Geometry getGeometry() {
+        return impl;
+    }
+
+    @Override
+    public SceneGraphObject getSceneGraphObject() {
+        return impl;
+    }
+
+    @Override
+    public void setupFinished() {
+
+        float[] vfControlPoint = new float[0];
+        if (vfCoord != null && vfCoord.getNumPoints() > 0) {
+            vfControlPoint = new float[vfCoord.getNumPoints()];
+            vfCoord.getPoint(vfControlPoint);
+        } else {
+            System.out.println("OGLNurbsCurve.setupFinished: null Coordinates node");
+        }
+
+        impl = new org.j3d.aviatrix3d.LineStripArray(true,
+                VertexGeometry.VBO_HINT_STATIC);
+        List<ControlPoint4f> cpsa = new ArrayList<>();
+        int dimension = vfControlPoint.length / 3;
+        {
+            for (int i = 0; i < dimension; i++) {
+                float wt;
+                if (vfWeight != null && vfWeight.length > i) {
+                    wt = (float) vfWeight[i];
+                } else {
+                    wt = (float) 1.0;
+                }
+
+                float winv = ((float) 1.0) / wt;
+
+                cpsa.add(new ControlPoint4f(
+                        vfControlPoint[3 * i] * winv,
+                        vfControlPoint[3 * i + 1] * winv,
+                        vfControlPoint[3 * i + 2] * winv,
+                        winv));
+            }
+        }
+        ControlPoint4f cps[] = new ControlPoint4f[cpsa.size()];
+        cpsa.toArray(cps);
+
+        //recompute knot vector if not supplied or wrong size
+//		boolean computeKnot = false;
+        float uk[];
+        if (this.vfKnot != null) {
+            uk = new float[this.vfKnot.length];
+            for (int i = 0; i < uk.length; i++) {
+                uk[i] = (float) vfKnot[i];
+            }
+        } else {    // compute  a uniform knot
+            int Nk = dimension + vfOrder;   // number of knot values (including extraneous)
+            uk = new float[Nk];
+            int ic = 0;
+            for (; ic < vfOrder; ic++) {
+                uk[ic] = (float) 0.0;
+            }
+            int Nseg = dimension - vfOrder + 1; // number of internal segments
+            float delt = (float) 1.0 / Nseg;
+            for (int iseg = 1; iseg < Nseg; iseg++, ic++) {
+                uk[ic] = iseg * delt;
+            }
+            for (; ic < Nk; ic++) {
+                uk[ic] = (float) 1.0;
+            }
+        }
+
+
+        BasicNurbsCurve nc = new BasicNurbsCurve(cps, uk, this.vfOrder - 1);
+
+        MeshedNurbsCurve mnc = new MeshedNurbsCurve(nc);
+        mnc.setEvaluator(new BasicNurbsCurveEvaluator());
+
+        LineStripArray ga = (LineStripArray) mnc.getMeshedCurve();
+        float[] coordinates = new float[ga.getValidVertexCount() * 3];
+        ga.getCoordinates(0, coordinates);
+
+        impl.setVertices(VertexGeometry.COORDINATE_3,
+                coordinates);
+
+        impl.setStripCount(new int[]{coordinates.length / 3}, 1);
+
+        super.setupFinished();
+    }
+
+    @Override
+    public void render() {
+    }
+
+    @Override
+    public void set_renderer(Object renderer) {
+    }
+}
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/nurbs/OGLNurbsPatchSurface.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/nurbs/OGLNurbsPatchSurface.java
index 194785563828e150083253859af42ac83707d4a2..a43a51b062b42def9cff5be1a76f0eb9eccf4978 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/nurbs/OGLNurbsPatchSurface.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/nurbs/OGLNurbsPatchSurface.java
@@ -1,175 +1,175 @@
-package org.web3d.vrml.renderer.ogl.nodes.nurbs;
-
-import org.web3d.vrml.renderer.ogl.nodes.nurbs.mesh.RectangularMesh;
-
-import net.jgeom.nurbs.BasicNurbsSurface;
-import net.jgeom.nurbs.ControlNet;
-import net.jgeom.nurbs.ControlPoint4f;
-
-import org.j3d.aviatrix3d.Geometry;
-import org.j3d.aviatrix3d.SceneGraphObject;
-import org.web3d.vrml.renderer.common.nodes.nurbs.BaseNurbsPatchSurface;
-import org.web3d.vrml.renderer.ogl.nodes.OGLGeometryNodeType;
-
-public class OGLNurbsPatchSurface extends BaseNurbsPatchSurface implements
-        OGLGeometryNodeType {
-
-    private org.j3d.aviatrix3d.VertexGeometry impl;
-
-    private BasicNurbsSurface nurbsSurfaceImpl;
-
-    public OGLNurbsPatchSurface() {
-    }
-
-    @Override
-    public Geometry getGeometry() {
-        return impl;
-    }
-
-    @Override
-    public SceneGraphObject getSceneGraphObject() {
-        return impl;
-    }
-
-    @Override
-    public BasicNurbsSurface getNurbsImpl() {
-        return nurbsSurfaceImpl;
-    }
-
-    @Override
-    public void setupFinished() {
-
-
-
-        // for(double f: vfControlPoint)
-        // {
-        // System.out.println(f);
-        // }
-
-        // System.out.println("cps : ");
-        // for(double f:vfControlPoint)
-        // System.out.print(f+", ");
-
-        float[] vfControlPoint = new float[0];
-        if (vfCoord != null && vfCoord.getNumPoints() > 0) {
-            vfControlPoint = new float[vfCoord.getNumPoints()];
-            vfCoord.getPoint(vfControlPoint);
-        } else {
-            System.out.println("OGLNurbsPatchSurface.setupFinished: null Coordinates node");
-        }
-
-
-        ControlPoint4f cpss[][] = new ControlPoint4f[this.vfUDimension][this.vfVDimension];
-        if (vfControlPoint.length < this.vfUDimension * this.vfVDimension) {
-            errorReporter.messageReport("Not enough control points for this surface");
-            return;
-        }
-        /*
-         System.out.println("Unwrapping control points list");
-         System.out.println("Nu: "+this.vfUDimension+" Nv: "+this.vfVDimension);
-         System.out.println("vfControlPoint.length: "+ vfControlPoint.length);
-         */
-
-        // this needs to be modified in light that ControlPoint4f looks like it should
-        // be the coordinates in rational space
-        for (int k = 0, j = 0; j < this.vfVDimension; j++) {
-            for (int i = 0; i < this.vfUDimension; i++) {
-                float wt;
-                if (vfWeight != null && vfWeight.length > k) {
-                    wt = (float) vfWeight[k];
-                } else {
-                    wt = (float) 1.0;
-                }
-
-                float winv = ((float) 1.0) / wt;
-
-                cpss[i][j] = new ControlPoint4f(
-                        vfControlPoint[3 * k] * winv,
-                        vfControlPoint[3 * k + 1] * winv,
-                        vfControlPoint[3 * k + 2] * winv,
-                        wt);
-                //System.out.println("OGLNurbsPatchSurface: index " + k + " weight: "+vfWeight[k]);
-                k += 1;
-
-            }
-        }
-
-        // recompute knot vector if not supplied or wrong size
-        float uk[];
-        if (this.vfUKnot != null) {
-            uk = new float[this.vfUKnot.length];
-            for (int i = 0; i < uk.length; i++) {
-                uk[i] = (float) vfUKnot[i];
-            }
-        } else {
-            uk = uniformKnotVector(vfUOrder, vfUDimension);
-        }
-
-        float vk[];
-        if (this.vfVKnot != null) {
-            vk = new float[this.vfVKnot.length];
-            for (int i = 0; i < vk.length; i++) {
-                vk[i] = (float) vfVKnot[i];
-            }
-        } else {
-            vk = uniformKnotVector(vfVOrder, vfVDimension);
-        }
-
-
-        ControlNet cn = new ControlNet(cpss);
-
-        // the BasicNurbsSurface needs to be initialized with the
-        // polynomial degree, not the order
-        nurbsSurfaceImpl = new BasicNurbsSurface(cn, uk, vk,
-                (this.vfUOrder - 1), (this.vfVOrder - 1));
-
-        RectangularMesh mesh = new RectangularMesh(nurbsSurfaceImpl, 20, 20);
-        impl = mesh.sceneGraphObject();
-        super.setupFinished();
-
-    }
-
-    /**
-     * Returns a uniform vector of knot values (clamped) for a spline of order
-     * (order=polynomial degree + 1; order=4 are cubic splines) and dimension
-     * (dimension = number of control points)
-     *
-     * returns for parameter range 0 to 1 follows definition of uniform knot
-     * from "The Nurbs Book" (L. Piegl &amp; W Tiller, 2nd ed) section 2.4
-     *
-     * @param dimension
-     * @return float[] array of knot values
-     */
-    public float[] uniformKnotVector(int order, int dimension) {
-        int Nk = dimension + order;   // number of knot values
-        float uk[] = new float[Nk];
-        int ic = 0;
-        for (; ic < order; ic++) {
-            uk[ic] = (float) 0.0;
-        }
-        int Nseg = dimension - order + 1; // number of internal segments
-        float delt = (float) 1.0 / Nseg;
-        for (int iseg = 1; iseg < Nseg; iseg++, ic++) {
-            uk[ic] = iseg * delt;
-        }
-        for (; ic < Nk; ic++) {
-            uk[ic] = (float) 1.0;
-        }
-        return uk;
-    }
-
-    @Override
-    public void render() {
-    }
-
-    @Override
-    public void set_renderer(Object renderer) {
-        //this.renderer=(CADKernelRenderer)renderer;
-    }
-
-    // method defined in interface import org.web3d.vrml.renderer.ogl.nodes.OGLGeometryNodeType;
-    @Override
-    public boolean isSolid() {
-        return vfSolid;
-    }
-}
+package org.web3d.vrml.renderer.ogl.nodes.nurbs;
+
+import org.web3d.vrml.renderer.ogl.nodes.nurbs.mesh.RectangularMesh;
+
+import net.jgeom.nurbs.BasicNurbsSurface;
+import net.jgeom.nurbs.ControlNet;
+import net.jgeom.nurbs.ControlPoint4f;
+
+import org.j3d.aviatrix3d.Geometry;
+import org.j3d.aviatrix3d.SceneGraphObject;
+import org.web3d.vrml.renderer.common.nodes.nurbs.BaseNurbsPatchSurface;
+import org.web3d.vrml.renderer.ogl.nodes.OGLGeometryNodeType;
+
+public class OGLNurbsPatchSurface extends BaseNurbsPatchSurface implements
+        OGLGeometryNodeType {
+
+    private org.j3d.aviatrix3d.VertexGeometry impl;
+
+    private BasicNurbsSurface nurbsSurfaceImpl;
+
+    public OGLNurbsPatchSurface() {
+    }
+
+    @Override
+    public Geometry getGeometry() {
+        return impl;
+    }
+
+    @Override
+    public SceneGraphObject getSceneGraphObject() {
+        return impl;
+    }
+
+    @Override
+    public BasicNurbsSurface getNurbsImpl() {
+        return nurbsSurfaceImpl;
+    }
+
+    @Override
+    public void setupFinished() {
+
+
+
+        // for(double f: vfControlPoint)
+        // {
+        // System.out.println(f);
+        // }
+
+        // System.out.println("cps : ");
+        // for(double f:vfControlPoint)
+        // System.out.print(f+", ");
+
+        float[] vfControlPoint = new float[0];
+        if (vfCoord != null && vfCoord.getNumPoints() > 0) {
+            vfControlPoint = new float[vfCoord.getNumPoints()];
+            vfCoord.getPoint(vfControlPoint);
+        } else {
+            System.out.println("OGLNurbsPatchSurface.setupFinished: null Coordinates node");
+        }
+
+
+        ControlPoint4f cpss[][] = new ControlPoint4f[this.vfUDimension][this.vfVDimension];
+        if (vfControlPoint.length < this.vfUDimension * this.vfVDimension) {
+            errorReporter.messageReport("Not enough control points for this surface");
+            return;
+        }
+        /*
+         System.out.println("Unwrapping control points list");
+         System.out.println("Nu: "+this.vfUDimension+" Nv: "+this.vfVDimension);
+         System.out.println("vfControlPoint.length: "+ vfControlPoint.length);
+         */
+
+        // this needs to be modified in light that ControlPoint4f looks like it should
+        // be the coordinates in rational space
+        for (int k = 0, j = 0; j < this.vfVDimension; j++) {
+            for (int i = 0; i < this.vfUDimension; i++) {
+                float wt;
+                if (vfWeight != null && vfWeight.length > k) {
+                    wt = (float) vfWeight[k];
+                } else {
+                    wt = (float) 1.0;
+                }
+
+                float winv = ((float) 1.0) / wt;
+
+                cpss[i][j] = new ControlPoint4f(
+                        vfControlPoint[3 * k] * winv,
+                        vfControlPoint[3 * k + 1] * winv,
+                        vfControlPoint[3 * k + 2] * winv,
+                        wt);
+                //System.out.println("OGLNurbsPatchSurface: index " + k + " weight: "+vfWeight[k]);
+                k += 1;
+
+            }
+        }
+
+        // recompute knot vector if not supplied or wrong size
+        float uk[];
+        if (this.vfUKnot != null) {
+            uk = new float[this.vfUKnot.length];
+            for (int i = 0; i < uk.length; i++) {
+                uk[i] = (float) vfUKnot[i];
+            }
+        } else {
+            uk = uniformKnotVector(vfUOrder, vfUDimension);
+        }
+
+        float vk[];
+        if (this.vfVKnot != null) {
+            vk = new float[this.vfVKnot.length];
+            for (int i = 0; i < vk.length; i++) {
+                vk[i] = (float) vfVKnot[i];
+            }
+        } else {
+            vk = uniformKnotVector(vfVOrder, vfVDimension);
+        }
+
+
+        ControlNet cn = new ControlNet(cpss);
+
+        // the BasicNurbsSurface needs to be initialized with the
+        // polynomial degree, not the order
+        nurbsSurfaceImpl = new BasicNurbsSurface(cn, uk, vk,
+                (this.vfUOrder - 1), (this.vfVOrder - 1));
+
+        RectangularMesh mesh = new RectangularMesh(nurbsSurfaceImpl, 20, 20);
+        impl = mesh.sceneGraphObject();
+        super.setupFinished();
+
+    }
+
+    /**
+     * Returns a uniform vector of knot values (clamped) for a spline of order
+     * (order=polynomial degree + 1; order=4 are cubic splines) and dimension
+     * (dimension = number of control points)
+     *
+     * returns for parameter range 0 to 1 follows definition of uniform knot
+     * from "The Nurbs Book" (L. Piegl &amp; W Tiller, 2nd ed) section 2.4
+     *
+     * @param dimension
+     * @return float[] array of knot values
+     */
+    public float[] uniformKnotVector(int order, int dimension) {
+        int Nk = dimension + order;   // number of knot values
+        float uk[] = new float[Nk];
+        int ic = 0;
+        for (; ic < order; ic++) {
+            uk[ic] = (float) 0.0;
+        }
+        int Nseg = dimension - order + 1; // number of internal segments
+        float delt = (float) 1.0 / Nseg;
+        for (int iseg = 1; iseg < Nseg; iseg++, ic++) {
+            uk[ic] = iseg * delt;
+        }
+        for (; ic < Nk; ic++) {
+            uk[ic] = (float) 1.0;
+        }
+        return uk;
+    }
+
+    @Override
+    public void render() {
+    }
+
+    @Override
+    public void set_renderer(Object renderer) {
+        //this.renderer=(CADKernelRenderer)renderer;
+    }
+
+    // method defined in interface import org.web3d.vrml.renderer.ogl.nodes.OGLGeometryNodeType;
+    @Override
+    public boolean isSolid() {
+        return vfSolid;
+    }
+}
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/nurbs/OGLNurbsTrimmedSurface.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/nurbs/OGLNurbsTrimmedSurface.java
index 1b970c9f5efb40eef7cfbe60d425a8367cb97775..a5689257cf080685c79ce51a78efd9f42e72fc08 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/nurbs/OGLNurbsTrimmedSurface.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/nurbs/OGLNurbsTrimmedSurface.java
@@ -1,175 +1,175 @@
-package org.web3d.vrml.renderer.ogl.nodes.nurbs;
-
-// Standard library imports
-import java.util.ArrayList;
-import java.util.List;
-
-// Application specific imports
-import net.jgeom.nurbs.BasicNurbsSurface;
-import net.jgeom.nurbs.ControlNet;
-import net.jgeom.nurbs.ControlPoint4f;
-import net.jgeom.nurbs.TrimCurve;
-
-import org.j3d.aviatrix3d.Geometry;
-import org.j3d.aviatrix3d.SceneGraphObject;
-
-import org.web3d.vrml.nodes.VRMLNodeType;
-import org.web3d.vrml.renderer.common.nodes.nurbs.BaseNurbsTrimmedSurface;
-import org.web3d.vrml.renderer.ogl.nodes.OGLGeometryNodeType;
-import org.web3d.vrml.renderer.ogl.nodes.nurbs.mesh.TrimmedNurbsMesh;
-
-public class OGLNurbsTrimmedSurface extends BaseNurbsTrimmedSurface implements
-        OGLGeometryNodeType {
-
-    private org.j3d.aviatrix3d.VertexGeometry impl;
-
-    private BasicNurbsSurface nurbsSurfaceImpl;
-
-    public BasicNurbsSurface getNurbsImpl() {
-        return nurbsSurfaceImpl;
-    }
-
-    public OGLNurbsTrimmedSurface() {
-    }
-
-    @Override
-    public Geometry getGeometry() {
-        return impl;
-    }
-
-    @Override
-    public SceneGraphObject getSceneGraphObject() {
-        return impl;
-    }
-
-    @Override
-    public void setupFinished() {
-
-        super.setupFinished();
-
-        float[] vfControlPoint = new float[0];
-        if (vfCoord != null && vfCoord.getNumPoints() > 0) {
-            vfControlPoint = new float[vfCoord.getNumPoints()];
-            vfCoord.getPoint(vfControlPoint);
-        } else {
-            System.out.println("OGLNurbsTrimmedSurface.setupFinished: null Coordinates node");
-        }
-
-
-        ControlPoint4f cpss[][] = new ControlPoint4f[this.vfUDimension][this.vfVDimension];
-        if (vfControlPoint.length < this.vfUDimension * this.vfVDimension) {
-            errorReporter.messageReport("Not enough control points for this surface");
-            return;
-        }
-
-
-        for (int k = 0, j = 0; j < this.vfVDimension; j++) {
-            for (int i = 0; i < this.vfUDimension; i++) {
-                float wt;
-                if (vfWeight != null && vfWeight.length > k) {
-                    wt = (float) vfWeight[k];
-                } else {
-                    wt = (float) 1.0;
-                }
-
-                float winv = ((float) 1.0) / wt;
-
-                cpss[i][j] = new ControlPoint4f(
-                        vfControlPoint[3 * k] * winv,
-                        vfControlPoint[3 * k + 1] * winv,
-                        vfControlPoint[3 * k + 2] * winv,
-                        wt);
-                k += 1;
-
-            }
-        }
-
-        // recompute knot vector if not supplied or wrong size
-        float uk[];
-        if (this.vfUKnot != null) {
-            uk = new float[this.vfUKnot.length];
-            for (int i = 0; i < uk.length; i++) {
-                uk[i] = (float) vfUKnot[i];
-            }
-        } else {
-            uk = uniformKnotVector(vfUOrder, vfUDimension);
-        }
-
-        float vk[];
-        if (this.vfVKnot != null) {
-            vk = new float[this.vfVKnot.length];
-            for (int i = 0; i < vk.length; i++) {
-                vk[i] = (float) vfVKnot[i];
-            }
-        } else {
-            vk = uniformKnotVector(vfVOrder, vfVDimension);
-        }
-
-        ControlNet cn = new ControlNet(cpss);
-        nurbsSurfaceImpl = new BasicNurbsSurface(cn, uk, vk,
-                (this.vfUOrder - 1), (this.vfVOrder - 1));
-
-        List<TrimCurve> outerBounds = new ArrayList<>();
-        List<TrimCurve> innerBounds = new ArrayList<>();
-        for (VRMLNodeType nd : vfContour) {
-            OGLContour2D contour = (OGLContour2D) nd;
-            TrimCurve tc = contour.getTrimCurve();
-            if (contour.getSense()) {
-                outerBounds.add(tc);
-            } else {
-                innerBounds.add(tc);
-            }
-        }
-
-        if (outerBounds.size() != 1) {
-            //throw new Exception("no outerBounds");
-            System.out.println("OGLNurbsTrimmedCurve: No outer bound");
-        } else {
-            nurbsSurfaceImpl.addOuterTrimCurve(outerBounds.get(0));
-        }
-
-        for (TrimCurve tc : innerBounds) {
-            nurbsSurfaceImpl.addInnerTrimCurve(tc);
-        }
-
-        TrimmedNurbsMesh mesh = new TrimmedNurbsMesh(nurbsSurfaceImpl);
-        impl = mesh.sceneGraphObject();
-
-
-    }
-
-    /**
-     * Returns a uniform vector of knot values (clamped) for a spline of order
-     * (order=polynomial degree + 1; order=4 are cubic splines) and dimension
-     * (dimension = number of control points)
-     *
-     * returns for parameter range 0 to 1 follows definition of uniform knot
-     * from "The Nurbs Book" (L. Piegl &amp; W Tiller, 2nd ed) section 2.4
-     *
-     * @param dimension
-     * @return float[] array of knot values
-     */
-    public float[] uniformKnotVector(int order, int dimension) {
-        int Nk = dimension + order;   // number of knot values
-        float uk[] = new float[Nk];
-        int ic = 0;
-        for (; ic < order; ic++) {
-            uk[ic] = (float) 0.0;
-        }
-        int Nseg = dimension - order + 1; // number of internal segments
-        float delt = (float) 1.0 / Nseg;
-        for (int iseg = 1; iseg < Nseg; iseg++, ic++) {
-            uk[ic] = iseg * delt;
-        }
-        for (; ic < Nk; ic++) {
-            uk[ic] = (float) 1.0;
-        }
-        return uk;
-    }
-
-    // method defined in interface import org.web3d.vrml.renderer.ogl.nodes.OGLGeometryNodeType;
-    @Override
-    public boolean isSolid() {
-        return vfSolid;
-    }
-}
+package org.web3d.vrml.renderer.ogl.nodes.nurbs;
+
+// Standard library imports
+import java.util.ArrayList;
+import java.util.List;
+
+// Application specific imports
+import net.jgeom.nurbs.BasicNurbsSurface;
+import net.jgeom.nurbs.ControlNet;
+import net.jgeom.nurbs.ControlPoint4f;
+import net.jgeom.nurbs.TrimCurve;
+
+import org.j3d.aviatrix3d.Geometry;
+import org.j3d.aviatrix3d.SceneGraphObject;
+
+import org.web3d.vrml.nodes.VRMLNodeType;
+import org.web3d.vrml.renderer.common.nodes.nurbs.BaseNurbsTrimmedSurface;
+import org.web3d.vrml.renderer.ogl.nodes.OGLGeometryNodeType;
+import org.web3d.vrml.renderer.ogl.nodes.nurbs.mesh.TrimmedNurbsMesh;
+
+public class OGLNurbsTrimmedSurface extends BaseNurbsTrimmedSurface implements
+        OGLGeometryNodeType {
+
+    private org.j3d.aviatrix3d.VertexGeometry impl;
+
+    private BasicNurbsSurface nurbsSurfaceImpl;
+
+    public BasicNurbsSurface getNurbsImpl() {
+        return nurbsSurfaceImpl;
+    }
+
+    public OGLNurbsTrimmedSurface() {
+    }
+
+    @Override
+    public Geometry getGeometry() {
+        return impl;
+    }
+
+    @Override
+    public SceneGraphObject getSceneGraphObject() {
+        return impl;
+    }
+
+    @Override
+    public void setupFinished() {
+
+        super.setupFinished();
+
+        float[] vfControlPoint = new float[0];
+        if (vfCoord != null && vfCoord.getNumPoints() > 0) {
+            vfControlPoint = new float[vfCoord.getNumPoints()];
+            vfCoord.getPoint(vfControlPoint);
+        } else {
+            System.out.println("OGLNurbsTrimmedSurface.setupFinished: null Coordinates node");
+        }
+
+
+        ControlPoint4f cpss[][] = new ControlPoint4f[this.vfUDimension][this.vfVDimension];
+        if (vfControlPoint.length < this.vfUDimension * this.vfVDimension) {
+            errorReporter.messageReport("Not enough control points for this surface");
+            return;
+        }
+
+
+        for (int k = 0, j = 0; j < this.vfVDimension; j++) {
+            for (int i = 0; i < this.vfUDimension; i++) {
+                float wt;
+                if (vfWeight != null && vfWeight.length > k) {
+                    wt = (float) vfWeight[k];
+                } else {
+                    wt = (float) 1.0;
+                }
+
+                float winv = ((float) 1.0) / wt;
+
+                cpss[i][j] = new ControlPoint4f(
+                        vfControlPoint[3 * k] * winv,
+                        vfControlPoint[3 * k + 1] * winv,
+                        vfControlPoint[3 * k + 2] * winv,
+                        wt);
+                k += 1;
+
+            }
+        }
+
+        // recompute knot vector if not supplied or wrong size
+        float uk[];
+        if (this.vfUKnot != null) {
+            uk = new float[this.vfUKnot.length];
+            for (int i = 0; i < uk.length; i++) {
+                uk[i] = (float) vfUKnot[i];
+            }
+        } else {
+            uk = uniformKnotVector(vfUOrder, vfUDimension);
+        }
+
+        float vk[];
+        if (this.vfVKnot != null) {
+            vk = new float[this.vfVKnot.length];
+            for (int i = 0; i < vk.length; i++) {
+                vk[i] = (float) vfVKnot[i];
+            }
+        } else {
+            vk = uniformKnotVector(vfVOrder, vfVDimension);
+        }
+
+        ControlNet cn = new ControlNet(cpss);
+        nurbsSurfaceImpl = new BasicNurbsSurface(cn, uk, vk,
+                (this.vfUOrder - 1), (this.vfVOrder - 1));
+
+        List<TrimCurve> outerBounds = new ArrayList<>();
+        List<TrimCurve> innerBounds = new ArrayList<>();
+        for (VRMLNodeType nd : vfContour) {
+            OGLContour2D contour = (OGLContour2D) nd;
+            TrimCurve tc = contour.getTrimCurve();
+            if (contour.getSense()) {
+                outerBounds.add(tc);
+            } else {
+                innerBounds.add(tc);
+            }
+        }
+
+        if (outerBounds.size() != 1) {
+            //throw new Exception("no outerBounds");
+            System.out.println("OGLNurbsTrimmedCurve: No outer bound");
+        } else {
+            nurbsSurfaceImpl.addOuterTrimCurve(outerBounds.get(0));
+        }
+
+        for (TrimCurve tc : innerBounds) {
+            nurbsSurfaceImpl.addInnerTrimCurve(tc);
+        }
+
+        TrimmedNurbsMesh mesh = new TrimmedNurbsMesh(nurbsSurfaceImpl);
+        impl = mesh.sceneGraphObject();
+
+
+    }
+
+    /**
+     * Returns a uniform vector of knot values (clamped) for a spline of order
+     * (order=polynomial degree + 1; order=4 are cubic splines) and dimension
+     * (dimension = number of control points)
+     *
+     * returns for parameter range 0 to 1 follows definition of uniform knot
+     * from "The Nurbs Book" (L. Piegl &amp; W Tiller, 2nd ed) section 2.4
+     *
+     * @param dimension
+     * @return float[] array of knot values
+     */
+    public float[] uniformKnotVector(int order, int dimension) {
+        int Nk = dimension + order;   // number of knot values
+        float uk[] = new float[Nk];
+        int ic = 0;
+        for (; ic < order; ic++) {
+            uk[ic] = (float) 0.0;
+        }
+        int Nseg = dimension - order + 1; // number of internal segments
+        float delt = (float) 1.0 / Nseg;
+        for (int iseg = 1; iseg < Nseg; iseg++, ic++) {
+            uk[ic] = iseg * delt;
+        }
+        for (; ic < Nk; ic++) {
+            uk[ic] = (float) 1.0;
+        }
+        return uk;
+    }
+
+    // method defined in interface import org.web3d.vrml.renderer.ogl.nodes.OGLGeometryNodeType;
+    @Override
+    public boolean isSolid() {
+        return vfSolid;
+    }
+}
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/nurbs/mesh/TrimmedNurbsMesh.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/nurbs/mesh/TrimmedNurbsMesh.java
index aeb6d88338e29c4f4ee07e7af52ebcfaea75a1ba..6b6c033889442ac55cd2d44d13c8a463f8327939 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/nurbs/mesh/TrimmedNurbsMesh.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/nurbs/mesh/TrimmedNurbsMesh.java
@@ -27,7 +27,7 @@ import org.j3d.aviatrix3d.IndexedQuadArray;
 import org.j3d.aviatrix3d.VertexGeometry;
 
 /**
- * Trimmed Nurbs Mesh
+ *
  *
  * @author Vincent Marchetti
  * @version 0.1
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLExplosionEmitter.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLExplosionEmitter.java
index 8d07506a67d86da269b4774d7186e1551407c982..7ea5f30c7cc6b7e392eeeaf8e9083e84d08da645 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLExplosionEmitter.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLExplosionEmitter.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * OpenGL implementation of a ExplosionEmitter.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLGravityPhysicsModel.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLGravityPhysicsModel.java
index f9bf965eda553930c707f8a18e0b83d05076a018..bf5ac815a65e729510e4b8d984e38903c4db0141 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLGravityPhysicsModel.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLGravityPhysicsModel.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * OpenGL implementation of a GravityPhysicsModel.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLParticleSystem.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLParticleSystem.java
index 473458c9e6ccb5a4243907b17f273903c0298b8b..9d4014f774d56453511aca6c43468b66def4203a 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLParticleSystem.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLParticleSystem.java
@@ -27,6 +27,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLAppearanceNodeType;
 
 /**
  * OpenGL implementation of a ParticleSystem.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.6 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLPointEmitter.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLPointEmitter.java
index 139aeb8d6b9b628a6ac05b188e0ff9a313c79905..32621f9e075659fefd3e35ab2c3a42bf9b1492a6 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLPointEmitter.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLPointEmitter.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * OpenGL implementation of a PointEmitter.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLPolylineEmitter.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLPolylineEmitter.java
index 4c8bf860d88cf7c5503e832e32ea835ada52dfb6..d113030cbbaeef5c2b21eea5ad1bf560c016659f 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLPolylineEmitter.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLPolylineEmitter.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * OpenGL implementation of a PolylineEmitter.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLWindPhysicsModel.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLWindPhysicsModel.java
index 7a1e2951deafd23a77329ed78e4c789812df8733..06f846b68fdd8ccd7075478521921e2fbde8a24a 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLWindPhysicsModel.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/particle/OGLWindPhysicsModel.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * OpenGL implementation of a WindPhysicsModel.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/picking/OGLLinePicker.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/picking/OGLLinePicker.java
index 08bf12a5173ab8a52f86c5e7b2e952ff33bb0747..304ae69cab9abed854e0b21c79597cd0430f7efa 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/picking/OGLLinePicker.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/picking/OGLLinePicker.java
@@ -33,6 +33,7 @@ import org.web3d.vrml.renderer.common.nodes.picking.BaseLinePicker;
 
 /**
  * OpenGL renderer implementation of a LinePicker node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/picking/OGLPointPicker.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/picking/OGLPointPicker.java
index 8652a75a34deb48670aafc4f20e605ed36e2cc3b..960425f235b6b5536dc8b9e97b50f4640667140a 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/picking/OGLPointPicker.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/picking/OGLPointPicker.java
@@ -33,6 +33,7 @@ import org.web3d.vrml.renderer.common.nodes.picking.BasePointPicker;
 
 /**
  * OpenGL renderer implementation of a PointPicker node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/picking/OGLPrimitivePicker.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/picking/OGLPrimitivePicker.java
index 7fd62c1f3249ac51e89885f3741f062ed011c248..ec793c05e6be3e462bce9686f4b0fc1b4723f702 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/picking/OGLPrimitivePicker.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/picking/OGLPrimitivePicker.java
@@ -33,6 +33,7 @@ import org.web3d.vrml.renderer.common.nodes.picking.BasePrimitivePicker;
 
 /**
  * OpenGL-renderer implementation of a PrimitivePicker node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/picking/OGLVolumePicker.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/picking/OGLVolumePicker.java
index 20156876b222c63674372f9c7fca92e4fd54eaff..408cfc0bfa6de167bab2c0d56d04e4634038104a 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/picking/OGLVolumePicker.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/picking/OGLVolumePicker.java
@@ -34,6 +34,7 @@ import org.web3d.vrml.renderer.common.nodes.picking.BaseVolumePicker;
 
 /**
  * OpenGL renderer implementation of a VolumePicker node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/render/OGLCoordinate.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/render/OGLCoordinate.java
index c9b76c531bd1c252a3f6e1dd707b3dcbbfb0a7eb..36f89e98d17279af9c1833a94ea36454c4b306fa 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/render/OGLCoordinate.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/render/OGLCoordinate.java
@@ -21,7 +21,6 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 import org.web3d.vrml.renderer.common.nodes.render.BaseCoordinate;
 
 /**
- * OpenGL coordinate
  * @author Rick Goldberg
  * @version $Revision: 1.2 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/render/OGLNormal.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/render/OGLNormal.java
index 2339dcda824bbf1a5a9f181001293319b32e8203..3e6ac546be5ebd3e13baf0da7dcf73d94ed8f852 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/render/OGLNormal.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/render/OGLNormal.java
@@ -21,7 +21,6 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 import org.web3d.vrml.renderer.common.nodes.render.BaseNormal;
 
 /**
- * OpenGL normal
  * @author Rick Goldberg
  * @version $Revision: 1.2 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/render/OGLTriangleSet.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/render/OGLTriangleSet.java
index df09b9bc74d2e75bf95e84d57c24c358f15f64ee..fcc82e41585658c29d45e0fa27596c9ba88d4c35 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/render/OGLTriangleSet.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/render/OGLTriangleSet.java
@@ -31,6 +31,7 @@ import org.web3d.vrml.renderer.common.nodes.GeometryUtils;
 
 /**
  * OpenGL implementation of an TriangleSet.
+ * <p>
  *
  * @author Justin Couch, Alan Hudson
  * @version $Revision: 1.18 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLBallJoint.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLBallJoint.java
index 2118d78b2360250ecbbeeb8c40291c6b5186b0d4..b2e6e9ee076143c34332d7c94ce298e3f924d876 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLBallJoint.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLBallJoint.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of a BallJoint.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLCollidableOffset.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLCollidableOffset.java
index 49eb28cc9ea1437dbdfd6f3ba1dbe52a5ef002f4..879170a3654f353343714984fa5f5c9714a618fe 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLCollidableOffset.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLCollidableOffset.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of a CollidableOffset.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLCollidableShape.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLCollidableShape.java
index 70f2f0bcbddd98dfed7991e7fd424a1b5801ed9c..21b01e18546d7930e9fee730a19266c7bb1688b8 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLCollidableShape.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLCollidableShape.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of a CollidableShape.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLCollisionCollection.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLCollisionCollection.java
index 318edc6fe5826cd56ea9762eb44c8d90d06a1a24..39bd22caa081a8b23ba09712be896093931cf5b2 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLCollisionCollection.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLCollisionCollection.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of a CollisionCollection.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLCollisionSensor.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLCollisionSensor.java
index ff149ef652d562219ef22a951e4bffc7c6931aef..9079bb84be668ddd0c1b2e9ddf8e9f89dda97a51 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLCollisionSensor.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLCollisionSensor.java
@@ -24,6 +24,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of a CollisionSensor.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLCollisionSpace.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLCollisionSpace.java
index 722be3a961ea372bb169d34a06c583352381698f..a43aef33368a769e7e87b67bec3582b5e41c64af 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLCollisionSpace.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLCollisionSpace.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of a CollisionSpace.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLContact.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLContact.java
index f19a48b2627894307c4ec1bc1c4f163b05060f8e..88578c451346afdea5350959502602a7e3afa40a 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLContact.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLContact.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of a Contact.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLDoubleAxisHingeJoint.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLDoubleAxisHingeJoint.java
index 34bfb0c4d70751e349b5823bf6548cfc31c24f4d..1281d52a4055207710c409b7348e2e84ce9c712a 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLDoubleAxisHingeJoint.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLDoubleAxisHingeJoint.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of a DoubleAxisHingeJoint.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLMotorJoint.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLMotorJoint.java
index 61e1dbd7f550e6506cce549f45b654d67ee40ac2..adf45a47c1d6d3d0acdeca5356a4ba388c8042aa 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLMotorJoint.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLMotorJoint.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of a MotorJoint.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLRigidBody.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLRigidBody.java
index 9b6789ccd59e6d91c70ce0bd684b2b5391dfbc17..6417403bca1b3a78ccfa4c95a8abb71963e1491d 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLRigidBody.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLRigidBody.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of a RigidBody.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLRigidBodyCollection.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLRigidBodyCollection.java
index 6c706710d624e7e49f47674dabe3a587abecaf0f..5764f19e1bd57dfcdcef4b86d62ddf7a74fed24c 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLRigidBodyCollection.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLRigidBodyCollection.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of a RigidBodyCollection.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLSingleAxisHingeJoint.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLSingleAxisHingeJoint.java
index c3d7c730cc3657499b081b113c0e3861aae05c73..d96cb8f8934e30e2273b2766cd32f41fdf4605d7 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLSingleAxisHingeJoint.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLSingleAxisHingeJoint.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of a SingleAxisHingeJoint.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLSliderJoint.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLSliderJoint.java
index e70941ccd14e1b33af41915f61d23684958a97f5..e5f5fbfc29f04dfd7e509f439ccfa0ff4a26d51b 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLSliderJoint.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLSliderJoint.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of a SliderJoint.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLUniversalJoint.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLUniversalJoint.java
index fe06aba84b1f1cf130ce5836b284853b30296647..35693bbe3f52b74bd11ae665f477ffe7ae88acf8 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLUniversalJoint.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/rigidphysics/OGLUniversalJoint.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Implementation of a UniversalJoint.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/sensor/OGLCylinderSensor.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/sensor/OGLCylinderSensor.java
index 7b6e4988311c1a7665abc529f5d6df3aa84a4f31..30615d4e29938c78a12581d46f18f01baae0c829 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/sensor/OGLCylinderSensor.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/sensor/OGLCylinderSensor.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * OpenGL-renderer implementation of a CylinderSensor node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/sensor/OGLPlaneSensor.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/sensor/OGLPlaneSensor.java
index 5d1a035287e2c16fff3cdece50516abfdd8c5e36..3c1d33ab0086e1e35d83c3d63e01426fe0e31d74 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/sensor/OGLPlaneSensor.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/sensor/OGLPlaneSensor.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * OpenGL-renderer implementation of a PlaneSensor node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/sensor/OGLSphereSensor.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/sensor/OGLSphereSensor.java
index 10eb4323c4fc3d8863b48a47590412afdfd4175d..3c0c97dfb8386c3e8a76a3d31759b65e36f40c4b 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/sensor/OGLSphereSensor.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/sensor/OGLSphereSensor.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * OpenGL-renderer implementation of a SphereSensor node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/sensor/OGLTouchSensor.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/sensor/OGLTouchSensor.java
index dde706f7db93dc7c202a9c64f2fc3d28f9ab2cfe..602b6d0e19e72faf8b4de31656abb2daa0411ed2 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/sensor/OGLTouchSensor.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/sensor/OGLTouchSensor.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * OpenGL-renderer implementation of a TouchSensor node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLAppearance.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLAppearance.java
index 52d5e1201aa20cfbbb93a5d03c0fea6b4c09b3f6..fc4cc6a03f99bd631775c97b87422833334befe4 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLAppearance.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLAppearance.java
@@ -1,1929 +1,1929 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2003 - 2007
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.renderer.ogl.nodes.shape;
-
-// External imports
-import java.nio.ByteBuffer;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-import javax.vecmath.Matrix4f;
-
-import org.j3d.aviatrix3d.*;
-
-// Local imports
-import org.web3d.image.NIOBufferImage;
-import org.web3d.image.NIOBufferImageType;
-
-import org.web3d.vrml.lang.*;
-
-import org.web3d.vrml.nodes.*;
-
-import org.web3d.vrml.renderer.common.nodes.shape.BaseAppearance;
-import org.web3d.vrml.renderer.common.nodes.shape.TextureStage;
-
-import org.web3d.vrml.renderer.ogl.nodes.*;
-import org.web3d.vrml.renderer.ogl.nodes.TextureCache;
-
-/**
- * OpenGL implementation of an Appearance node.
- * <p>
- *
- * MultiTexture Notes: function and source not mapped
- *
- * 3D Texture Notes: Getting a rescale problem, not working.
- *
- * Cubic Environment Notes: Not implemented.
- *
- * @author Alan Hudson
- * @version $Revision: 1.70 $
- */
-public class OGLAppearance extends BaseAppearance
-        implements OGLAppearanceNodeType,
-        OGLTextureTransformListener,
-        NodeUpdateListener,
-        FrameStateListener {
-
-    /**
-     * Error message when something goes wrong in createTexture()
-     */
-    private static final String TEXTURE_CREATE_FAIL_MSG
-            = "Failed for an unknown reason during the creation of the base "
-            + "texture image in OGLAppearance.createTexture(). URL is: ";
-
-    /**
-     * The texture field contains a Multitexture with a nested multitexture
-     * instance as a child. This is baaaaad and not legal by the spec. Hopefully
-     * the parsing or scene building has picked this up, but we'll do another
-     * check anyway. This is the error message for that redundant check as we're
-     * building the scene graph.
-     */
-    private static final String NESTED_MULTITEXTURE_ERR
-            = "Discovered a nested MultiTexture node while processing a "
-            + "MultiTexture node. This is not legal. See 19775-1 18.4.3 "
-            + "paragraph 2 for more information";
-
-    /**
-     * The default mode to use for CLAMP. X3D spec is silent right now
-     */
-    private static final int DEFAULT_CLAMP_MODE = TextureConstants.BM_CLAMP_EDGE;
-
-    /**
-     * A map between TexCoordGen modes and AV3D modes
-     */
-    private static final Map<String, Integer> texGenModeMap;
-
-    /**
-     * The OpenGL Implementation node for the appearance
-     */
-    private Appearance oglImplNode;
-
-    /**
-     * The OpenGL Implementation node for the solid flag handling
-     */
-    private PolygonAttributes implPA;
-
-    /**
-     * The current Texture attribute information
-     */
-    private TextureAttributes[] texAttrs;
-
-    /**
-     * The TextureUnitStates used for multitexturing
-     */
-    private TextureUnit[] texUnits;
-
-    /**
-     * A map between texture unit and texture gen mode
-     */
-    private Map<Integer, String> texGenMap;
-
-    /**
-     * The OGL texture objects
-     */
-    private Texture[] texObjs;
-
-    /**
-     * The vrml texture objects
-     */
-    private VRMLTextureNodeType[] vrmlTexs;
-
-    /**
-     * The mode for each stage
-     */
-    private int[] modes;
-
-    /**
-     * The function for each stage
-     */
-    private int[] functions;
-
-    /**
-     * The source for each stage
-     */
-    private int[] sources;
-
-    /**
-     * Flag to indicate a textureUnit has changed off thread
-     */
-    private boolean threadedUnitChanged;
-
-    /**
-     * Flag indicating that the material has changed
-     */
-    private boolean materialChanged;
-
-    /**
-     * Flag indicating that the fill properties changed
-     */
-    private boolean fillPropsChanged;
-
-    /**
-     * Flag indicating that the line properties changed
-     */
-    private boolean linePropsChanged;
-
-    /**
-     * Flag indicating that the point properties changed
-     */
-    private boolean pointPropsChanged;
-
-    /**
-     * Did all the texture units get changed
-     */
-    private boolean textureUnitsChanged;
-
-    /**
-     * Flag indicating that the texture transform node has changed
-     */
-    private boolean textureTransformChanged;
-
-    /**
-     * Maps the AV3D TextureUnit to the TextureStage that has changed.
-     */
-    private Map<TextureUnit, TextureStage> changedTransforms;
-
-    /**
-     * Maps the AV3D TextureUnit to the TextureStage that has changed.
-     */
-    private Map<TextureUnit, TextureStage> changedTexCoordGeneration;
-
-    /**
-     * Flag indicating that the texture changed
-     */
-    private boolean textureChanged;
-
-    /**
-     * Solid state passed in from the geometry flags
-     */
-    private boolean savedSolidState;
-
-    /**
-     * Solid state passed in from the geometry flags
-     */
-    private boolean savedCCWState;
-
-    /**
-     * A double buffered list of tex units changed
-     */
-    private ConcurrentLinkedQueue<SceneGraphObject> texUnitsChanged;
-
-    /**
-     * The current lighting state
-     */
-    private boolean lightingState;
-
-    /**
-     * Whether to override diffuse color with local colors
-     */
-    private boolean localColor;
-
-    /**
-     * Whether the local color also includes alpha values
-     */
-    private boolean localColorAlpha;
-
-    /**
-     * Should we force lighting off
-     */
-    boolean lightingOverride;
-
-    /**
-     * The local texture cache for AV3D textures
-     */
-    private TextureCache textureCache;
-
-    /**
-     * Should we query for point sprites
-     */
-    private boolean queryPointSprites;
-
-    /**
-     * PointSprites supported
-     */
-    private static boolean pointSpritesSupported;
-
-    static {
-        texGenModeMap = new HashMap<>(3);
-        texGenModeMap.put("SPHERE", TexCoordGeneration.MAP_SPHERICAL);
-        texGenModeMap.put("CAMERASPACENORMAL", TexCoordGeneration.MAP_NORMALS);
-        texGenModeMap.put("CAMERASPACEREFLECTIONVECTOR", TexCoordGeneration.MAP_REFLECTIONS);
-
-        // TODO: Not positive this is the correct mapping from spec language
-        texGenModeMap.put("CAMERASPACEPOSITION", TexCoordGeneration.MAP_EYE_LINEAR);
-    }
-
-    /**
-     * Empty constructor
-     */
-    public OGLAppearance() {
-        init();
-    }
-
-    /**
-     * Construct a new instance of this node based on the details from the given
-     * node. If the node is not a Appearance node, an exception will be thrown.
-     *
-     * @param node The node to copy
-     * @throws IllegalArgumentException The node is not a Group node
-     */
-    public OGLAppearance(VRMLNodeType node) {
-        super(node);
-
-        init();
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by FrameStateListener
-    //----------------------------------------------------------
-
-    /**
-     * Notification that the rendering of the event model is complete and that
-     * rendering is about to begin.
-     */
-    @Override
-    public void allEventsComplete() {
-
-        if (materialChanged || linePropsChanged || pointPropsChanged
-                || fillPropsChanged) {
-            oglImplNode.dataChanged(this);
-        } else if (threadedUnitChanged) {
-
-            while (!texUnitsChanged.isEmpty()) {
-
-                SceneGraphObject unit
-                        = texUnitsChanged.poll();
-
-                if (unit.isLive()) {
-                    unit.dataChanged(this);
-                } else {
-                    updateNodeDataChanges(unit);
-                }
-
-                threadedUnitChanged = false;
-            }
-        } else if (queryPointSprites) {
-            queryPointSprites = false;
-
-            if (vfPointProperties != null) {
-                OGLVRMLNode o_n = (OGLVRMLNode) vfPointProperties;
-                PointAttributes pa = (PointAttributes) o_n.getSceneGraphObject();
-
-                pointSpritesSupported = pa.isPointSpriteAllowed();
-
-                if (!pointSpritesSupported) {
-                    System.out.println("OGL Point sprites not supported, unroll");
-                    pa.setPointSpriteEnabled(false);
-                    pa.setAntiAliased(true);
-
-                    // TODO: Disable texturing.  This is not exactly right if someone provided
-                    // PointProperties for a non pointset
-                    vfTexture = null;
-
-                    textureChanged = true;
-
-                    if (oglImplNode.isLive()) {
-                        oglImplNode.dataChanged(this);
-                    } else {
-                        updateNodeDataChanges(oglImplNode);
-                    }
-                }
-            }
-        }
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by VRMLAppearanceNodeType
-    //----------------------------------------------------------
-    
-    /**
-     * Set the material that should be used for this appearance. Setting a value
-     * of null will clear the current material.
-     *
-     * @param newMaterial The new material instance to be used.
-     * @throws InvalidFieldValueException The node does not match the required
-     * type.
-     */
-    @Override
-    public void setMaterial(VRMLNodeType newMaterial)
-            throws InvalidFieldValueException {
-
-        super.setMaterial(newMaterial);
-
-        if (inSetup) {
-            return;
-        }
-
-        if (vfMaterial != null && !lightingOverride) {
-            ((OGLMaterialNodeType) vfMaterial).setLightingEnable(lightingState);
-        }
-
-        materialChanged = true;
-        if (oglImplNode.isLive()) {
-            oglImplNode.dataChanged(this);
-        } else {
-            updateNodeDataChanges(oglImplNode);
-        }
-    }
-
-    /**
-     * Set the texture that should be used for this appearance. Setting a value
-     * of null will clear the current texture.
-     *
-     * @param newTexture The new texture instance to be used.
-     * @throws InvalidFieldValueException The node does not match the required
-     * type.
-     */
-    @Override
-    public void setTexture(VRMLNodeType newTexture)
-            throws InvalidFieldValueException {
-
-        VRMLTextureNodeType old_node = vfTexture;
-
-        super.setTexture(newTexture);
-
-        if (old_node != null) {
-            old_node.removeTextureListener(this);
-        }
-
-        if (vfTexture != null) {
-            vfTexture.addTextureListener(this);
-        }
-
-        if (inSetup) {
-            return;
-        }
-
-        textureChanged = true;
-
-        if (oglImplNode.isLive()) {
-            oglImplNode.dataChanged(this);
-        } else {
-            updateNodeDataChanges(oglImplNode);
-        }
-    }
-
-    /**
-     * Set the texture transform that should be used for this appearance.
-     * Setting a value of null will clear the current texture transform.
-     *
-     * @param newTransform The new texture transform instance to be used.
-     * @throws InvalidFieldValueException The node does not match the required
-     * type.
-     */
-    @Override
-    public void setTextureTransform(VRMLNodeType newTransform)
-            throws InvalidFieldValueException {
-
-        OGLTextureCoordinateTransformNodeType old_node
-                = (OGLTextureCoordinateTransformNodeType) vfTextureTransform;
-
-        super.setTextureTransform(newTransform);
-
-        OGLTextureCoordinateTransformNodeType node
-                = (OGLTextureCoordinateTransformNodeType) vfTextureTransform;
-
-        if (node != null) {
-            node.addTransformListener(this);
-        }
-
-        if (old_node != null) {
-            old_node.removeTransformListener(this);
-        }
-
-        if (inSetup) {
-            return;
-        }
-
-        textureTransformChanged = true;
-        if (oglImplNode.isLive()) {
-            oglImplNode.dataChanged(this);
-        } else {
-            updateNodeDataChanges(oglImplNode);
-        }
-    }
-
-    /**
-     * Set the line properties that should be used for this appearance. Setting
-     * a value of null will clear the current property.
-     *
-     * @param prop The new property instance instance to be used.
-     * @throws InvalidFieldValueException The node does not match the required
-     * type.
-     */
-    @Override
-    public void setLineProperties(VRMLNodeType prop)
-            throws InvalidFieldValueException {
-
-        super.setLineProperties(prop);
-
-        if (inSetup) {
-            return;
-        }
-
-        linePropsChanged = true;
-        if (oglImplNode.isLive()) {
-            oglImplNode.dataChanged(this);
-        } else {
-            updateNodeDataChanges(oglImplNode);
-        }
-    }
-
-    /**
-     * Set the point properties that should be used for this appearance. Setting
-     * a value of null will clear the current property.
-     *
-     * @param prop The new property instance instance to be used.
-     * @throws InvalidFieldValueException The node does not match the required
-     * type.
-     */
-    @Override
-    public void setPointProperties(VRMLNodeType prop)
-            throws InvalidFieldValueException {
-
-        super.setPointProperties(prop);
-
-        if (inSetup) {
-            return;
-        }
-
-        pointPropsChanged = true;
-        if (oglImplNode.isLive()) {
-            oglImplNode.dataChanged(this);
-        } else {
-            updateNodeDataChanges(oglImplNode);
-        }
-    }
-
-    /**
-     * Set the fillProperties that should be used for this appearance. Setting a
-     * value of null will clear the current property.
-     *
-     * @param prop The new fillProperties instance to be used.
-     * @throws InvalidFieldValueException The node does not match the required
-     * type.
-     */
-    @Override
-    public void setFillProperties(VRMLNodeType prop)
-            throws InvalidFieldValueException {
-
-        super.setFillProperties(prop);
-
-        if (inSetup) {
-            return;
-        }
-
-        fillPropsChanged = true;
-        if (oglImplNode.isLive()) {
-            oglImplNode.dataChanged(this);
-        } else {
-            updateNodeDataChanges(oglImplNode);
-        }
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by OGLAppearanceNodeType
-    //----------------------------------------------------------
-
-    /**
-     * Get the appearance instance used to represent this object.
-     *
-     * @return The appearance instance
-     */
-    @Override
-    public Appearance getAppearance() {
-        return oglImplNode;
-    }
-
-    /**
-     * Set the texture coordinate generation mode for a texture set. If its not
-     * set then texture coordinates will be used. A value of null will clear the
-     * setting.
-     *
-     * @param setNum The set which this tex gen mode refers
-     * @param mode The mode to use. Straight VRML field value
-     */
-    @Override
-    public void setTexCoordGenMode(int setNum, String mode) {
-        texGenMap.put(setNum, mode);
-
-        if (inSetup) {
-            return;
-        }
-
-        Integer imode = texGenModeMap.get(mode);
-
-        if (imode != null) {
-            TexCoordGeneration newtcg = new TexCoordGeneration();
-
-            newtcg.setParameter(TexCoordGeneration.TEXTURE_S,
-                    TexCoordGeneration.MODE_GENERIC, imode,
-                    null);
-            newtcg.setParameter(TexCoordGeneration.TEXTURE_T,
-                    TexCoordGeneration.MODE_GENERIC, imode,
-                    null);
-
-            if (vfTexture != null
-                    && vfTexture.getTextureType() == TextureConstants.TYPE_SINGLE_3D) {
-
-                newtcg.setParameter(TexCoordGeneration.TEXTURE_R,
-                        TexCoordGeneration.MODE_GENERIC, imode,
-                        null);
-            }
-
-            stages[setNum].texCoordGeneration = newtcg;
-
-            changedTexCoordGeneration.put(texUnits[setNum], stages[setNum]);
-
-            if (texUnits[setNum].isLive()) {
-                texUnits[setNum].dataChanged(this);
-            } else {
-                updateNodeDataChanges(texUnits[setNum]);
-            }
-
-        } else {
-            // Clear
-
-            stages[setNum].texCoordGeneration = null;
-
-            changedTexCoordGeneration.put(texUnits[setNum], stages[setNum]);
-
-            if (texUnits[setNum].isLive()) {
-                texUnits[setNum].dataChanged(this);
-            } else {
-                updateNodeDataChanges(texUnits[setNum]);
-            }
-        }
-    }
-
-    /**
-     * Specify whether an object is solid. The default is true. This will
-     * determine if we do backface culling and flip backface normals. Can only
-     * be set during setup
-     *
-     * @param solid Whether the object is solid
-     */
-    @Override
-    public void setSolid(boolean solid) {
-        savedSolidState = solid;
-        if (implPA.isLive()) {
-            implPA.dataChanged(this);
-        } else {
-            updateNodeDataChanges(implPA);
-        }
-
-        // May need to add or remove the polyAttr from the appearance
-        // depending on the combined state of this and CCW
-        fillPropsChanged = true;
-        if (oglImplNode.isLive()) {
-            oglImplNode.dataChanged(this);
-        } else {
-            updateNodeDataChanges(oglImplNode);
-        }
-    }
-
-    /**
-     * Set whether lighting will be used for this appearance. In general you
-     * should let the material node decide this. Needed to handle
-     * IndexedLineSets or other geometry that specifically declares lighting be
-     * turned off. This method will notify the related Material node for this
-     * Appearance.
-     *
-     * @param enable Whether lighting is enabled
-     */
-    @Override
-    public void setLightingEnabled(boolean enable) {
-        lightingState = enable;
-
-        if (vfMaterial != null && !lightingOverride) {
-            ((OGLMaterialNodeType) vfMaterial).setLightingEnable(enable);
-        }
-    }
-
-    /**
-     * Set whether the geometry has local colors to override the diffuse color.
-     *
-     * @param enable Whether local color is enabled
-     * @param hasAlpha true with the local color also contains alpha values
-     */
-    @Override
-    public void setLocalColor(boolean enable, boolean hasAlpha) {
-        localColor = enable;
-        localColorAlpha = hasAlpha;
-
-        if (vfMaterial != null) {
-            ((OGLMaterialNodeType) vfMaterial).setLocalColor(enable, hasAlpha);
-        }
-    }
-
-    /**
-     * Specify whether the geometry's triangles are in counter clockwise order
-     * (the default) or clockwise. The default is true. This will determine if
-     * we do backface culling and flip backface normals. Can only be set during
-     * setup
-     *
-     * @param ccw True for counter-clockwise ordering
-     */
-    @Override
-    public void setCCW(boolean ccw) {
-        savedCCWState = ccw;
-        if (implPA.isLive()) {
-            implPA.dataChanged(this);
-        } else {
-            updateNodeDataChanges(implPA);
-        }
-
-        // May need to add or remove the polyAttr from the appearance
-        // depending on the combined state of this and solid
-        fillPropsChanged = true;
-        if (oglImplNode.isLive()) {
-            oglImplNode.dataChanged(this);
-        } else {
-            updateNodeDataChanges(oglImplNode);
-        }
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by OGLTextureTransformListener
-    //----------------------------------------------------------
-
-    /**
-     * Invoked when a textureTransform has changed.
-     *
-     * @param src The node instance that was the source of this change
-     * @param tmatrix The new TransformMatrix array
-     * @param updated Flag for each index illustrating whether it has been
-     * updated or not.
-     */
-    @Override
-    public void textureTransformChanged(OGLVRMLNode src,
-            Matrix4f[] tmatrix,
-            boolean[] updated) {
-
-        int cnt = tmatrix.length;
-
-        insureStageSize(cnt, false);
-
-        for (int i = 0; i < cnt; i++) {
-            if (!updated[i]) {
-                continue;
-            }
-
-            changedTransforms.put(texUnits[i], stages[i]);
-
-            stages[i].transform = tmatrix[i];
-
-            if (texUnits[i].isLive()) {
-                texUnits[i].dataChanged(this);
-            } else {
-                updateNodeDataChanges(texUnits[i]);
-            }
-        }
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by VRMLTextureListener
-    //----------------------------------------------------------
-
-    /**
-     * Invoked when an underlying image has changed. Synchronized due to
-     * competition for the image arrays.
-     *
-     * @param idx The image idx which changed.
-     * @param node The texture which changed.
-     * @param image The image for this texture.
-     * @param url The url used to load this image.
-     */
-    @Override
-    public synchronized void textureImageChanged(
-            int idx,
-            VRMLNodeType node,
-            NIOBufferImage image,
-            String url) {
-
-        super.textureImageChanged(idx, node, image, url);
-
-        if (idx < numStages && vrmlTexs != null) {
-            int type = vfTexture.getTextureType();
-            switch (type) {
-                case TextureConstants.TYPE_SINGLE_2D:
-                    // rem /////////////////////////////////////////////////////
-                    // set ignore diffuse on the material node in the
-                    // case of a single texture, but not a multi-texture
-                    TextureStage tstage = stages[idx];
-                    if ((tstage.images != null) && (tstage.images.length > 0)) {
-                        setIgnoreDiffuse(tstage.images[0]);
-                    }
-                    // TDN 02 APR 2013 /////////////////////////////////////////
-                    // A break statement here WILL break texturing, therefore a
-                    // deliberate fallthrough is permitted here.
-                    ////////////////////////////////////////////////////////////
-                case TextureConstants.TYPE_MULTI:
-                    texObjs[idx] = createTexture(stages[idx],
-                            url,
-                            vrmlTexs[idx].getTextureType());
-                    /*
-                     System.out.println("Forcing call to texture atts");
-                     texAttrs[idx] = createTextureAttributes(idx,stages[idx]);
-                     */
-                    texUnitsChanged.add(texUnits[idx]);
-
-                    ((OGLTextureNodeType) vfTexture).setTexture(idx,
-                            texObjs[idx]);
-                    threadedUnitChanged = true;
-                    stateManager.addEndOfThisFrameListener(this);
-                    break;
-
-                case TextureConstants.TYPE_SINGLE_3D:
-                    texObjs[0] = createTexture(stages[0], url, type);
-                    texUnitsChanged.add(texUnits[0]);
-                    ((OGLTextureNodeType) vfTexture).setTexture(0, texObjs[0]);
-                    threadedUnitChanged = true;
-                    stateManager.addEndOfThisFrameListener(this);
-                    break;
-            }
-        } else {
-            //System.out.println("** Create TU: " + url);
-            createTextureUnits();
-        }
-    }
-
-    /**
-     * Invoked when all of the underlying images have changed.
-     *
-     * @param len The number of valid entries in the image array.
-     * @param node The textures which changed.
-     * @param image The images for this texture.
-     * @param url The urls used to load these images.
-     */
-    @Override
-    public void textureImageChanged(int len,
-            VRMLNodeType[] node,
-            NIOBufferImage[] image,
-            String[] url) {
-
-        super.textureImageChanged(len, node, image, url);
-
-        // rem //////////////////////////////////////////////////////////////////
-        // this has not been tested - doesn't look right
-        if (len <= numStages) {
-            int type = vfTexture.getTextureType();
-
-            if (type == TextureConstants.TYPE_SINGLE_3D) {
-                stages[0].mode = getMode(image[0], true);
-                texObjs[0] = createTexture(stages[0], null, type);
-                texUnits[0].setTexture(texObjs[0]);
-                ((OGLTextureNodeType) vfTexture).setTexture(0, texObjs[0]);
-
-            } else {
-                for (int idx = 0; idx < len; idx++) {
-                    stages[idx].mode = getMode(image[idx], (idx == 0));
-                    texObjs[idx] = createTexture(stages[idx],
-                            url[idx],
-                            vrmlTexs[idx].getTextureType());
-                    // TODO: shouldn't this call dataChanged?
-                    texUnits[idx].setTexture(texObjs[idx]);
-                    ((OGLTextureNodeType) vfTexture).setTexture(idx, texObjs[idx]);
-                }
-            }
-        } else {
-            createTextureUnits();
-        }
-        //////////////////////////////////////////////////////////////////////////
-    }
-
-    /**
-     * Invoked when the texture parameters have changed. The most efficient
-     * route is to set the parameters before the image.
-     *
-     * @param idx The texture index which changed.
-     * @param mode The mode for the stage.
-     * @param source The source for the stage.
-     * @param function The function to apply to the stage values.
-     * @param alpha The alpha value to use for modes requiring it.
-     * @param color The color to use for modes requiring it. 3 Component color.
-     */
-    @Override
-    public void textureParamsChanged(int idx, int mode,
-            int source, int function, float alpha, float[] color) {
-
-        super.textureParamsChanged(idx, mode, source, function, alpha, color);
-    }
-
-    /**
-     * Invoked when the texture parameters have changed. The most efficient
-     * route is to set the parameters before the image.
-     *
-     * @param len The number of valid entries in the arrays.
-     * @param mode The mode for the stage.
-     * @param source The source for the stage.
-     * @param function The function to apply to the stage values.
-     * @param alpha The alpha value to use for modes requiring it.
-     * @param color The color to use for modes requiring it. An array of 3
-     * component colors.
-     */
-    @Override
-    public void textureParamsChanged(int len,
-            int mode[],
-            int[] source,
-            int[] function,
-            float alpha,
-            float[] color) {
-
-        super.textureParamsChanged(len, mode, source, function, alpha, color);
-
-        if (len <= numStages) {
-            for (int idx = 0; idx < len; idx++) {
-                stages[idx].mode = mode[idx];
-                setTextureMode(idx, stages[idx], texAttrs[idx]);
-            }
-        } else {
-            createTextureUnits();
-        }
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by OGLVRMLNodeType
-    //----------------------------------------------------------
-
-    /**
-     * Get the scene graph object representation of this node. This will need to
-     * be cast to the appropriate parent type when being used.
-     *
-     * @return The OGL representation.
-     */
-    @Override
-    public SceneGraphObject getSceneGraphObject() {
-        return oglImplNode;
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by VRMLNodeType
-    //----------------------------------------------------------
-
-    /**
-     * Notification that the construction phase of this node has finished. If
-     * the node would like to do any internal processing, such as setting up
-     * geometry, then go for it now.
-     */
-    @Override
-    public void setupFinished() {
-
-        if (!inSetup) {
-            return;
-        }
-
-        super.setupFinished();
-
-        OGLMaterialNodeType node = (OGLMaterialNodeType) vfMaterial;
-        if (vfMaterial != null) {
-            node.setLightingEnable(lightingState);
-            node.setLocalColor(localColor, localColorAlpha);
-        }
-
-        Material mat = (node == null) ? null : node.getMaterial();
-        oglImplNode.setMaterial(mat);
-
-        if (vfLineProperties != null) {
-            OGLVRMLNode o_n = (OGLVRMLNode) vfLineProperties;
-            LineAttributes la = (LineAttributes) o_n.getSceneGraphObject();
-            oglImplNode.setLineAttributes(la);
-        }
-
-        if (vfPointProperties != null) {
-            queryPointSprites = true;
-            // Find out whether we have point sprite support
-            stateManager.addEndOfThisFrameListener(this);
-
-            OGLVRMLNode o_n = (OGLVRMLNode) vfPointProperties;
-            PointAttributes pa = (PointAttributes) o_n.getSceneGraphObject();
-
-            if (pointSpritesSupported && vfTexture != null) {
-                pa.setAntiAliased(false);
-                pa.setPointSpriteEnabled(true);
-            } else {
-                pa.setPointSpriteEnabled(false);
-                pa.setAntiAliased(true);
-
-                // TODO: Disable texturing.  This is not exactly right if
-                // someone provided PointProperties for a non pointset
-                vfTexture = null;
-            }
-
-            oglImplNode.setPointAttributes(pa);
-        }
-
-        createTextureTransform();
-        createTextureUnits();
-
-        materialChanged = false;
-        fillPropsChanged = false;
-        linePropsChanged = false;
-        pointPropsChanged = false;
-        textureUnitsChanged = false;
-        textureTransformChanged = false;
-        textureChanged = false;
-        threadedUnitChanged = false;
-    }
-
-    @Override
-    public synchronized void notifyExternProtoLoaded(int index, VRMLNodeType node)
-            throws InvalidFieldValueException {
-
-        if (inSetup) {
-            return;
-        }
-
-        super.notifyExternProtoLoaded(index, node);
-
-        OGLVRMLNode kid = (OGLVRMLNode) node;
-
-        switch (index) {
-            case FIELD_MATERIAL:
-                if (oglImplNode.isLive()) {
-                    materialChanged = true;
-                    stateManager.addEndOfThisFrameListener(this);
-                } else {
-                    Material mat = (Material) kid.getSceneGraphObject();
-                    oglImplNode.setMaterial(mat);
-                }
-                break;
-
-            case FIELD_TEXTURE:
-                createTextureUnits();
-                break;
-
-            case FIELD_TEXTURE_TRANSFORM:
-                createTextureTransform();
-                break;
-
-            case FIELD_LINE_PROPERTIES:
-                if (oglImplNode.isLive()) {
-                    linePropsChanged = true;
-                    stateManager.addEndOfThisFrameListener(this);
-                } else {
-                    LineAttributes la = (LineAttributes) kid.getSceneGraphObject();
-                    oglImplNode.setLineAttributes(la);
-                }
-                break;
-            case FIELD_POINT_PROPERTIES:
-                if (oglImplNode.isLive()) {
-                    linePropsChanged = true;
-                    stateManager.addEndOfThisFrameListener(this);
-                } else {
-                    PointAttributes pa = (PointAttributes) kid.getSceneGraphObject();
-                    oglImplNode.setPointAttributes(pa);
-                }
-                break;
-
-            case FIELD_FILL_PROPERTIES:
-                if (oglImplNode.isLive()) {
-                    fillPropsChanged = true;
-                    stateManager.addEndOfThisFrameListener(this);
-                } else {
-                //                    PolygonAttributes pa =
-                    //                        (PolygonAttributes)kid.getSceneGraphObject();
-                    //                    oglImplNode.setPolygonAttributes(pa);
-                }
-                break;
-        }
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by NodeUpdateListener
-    //----------------------------------------------------------
-
-    /**
-     * Notification that its safe to update the node now with any operations
-     * that could potentially effect the node's bounds.
-     *
-     * @param src The node or Node Component that is to be updated.
-     */
-    @Override
-    public void updateNodeBoundsChanges(Object src) {
-    }
-
-    /**
-     * Notification that its safe to update the node now with any operations
-     * that only change the node's properties, but do not change the bounds.
-     *
-     * @param src The node or Node Component that is to be updated.
-     */
-    @Override
-    public void updateNodeDataChanges(Object src) {
-        if (src == oglImplNode) {
-            if (materialChanged) {
-                materialChanged = false;
-
-                OGLMaterialNodeType node = (OGLMaterialNodeType) vfMaterial;
-                Material mat = (node == null) ? null : node.getMaterial();
-                oglImplNode.setMaterial(mat);
-            }
-
-            if (textureChanged) {
-                textureChanged = false;
-
-                // TODO: Can we optimize this?
-                createTextureUnits();
-            }
-
-            if (textureTransformChanged) {
-                textureTransformChanged = false;
-
-                // TODO: Can we optimize this?
-                createTextureTransform();
-            }
-
-            if (textureUnitsChanged) {
-                textureUnitsChanged = false;
-                oglImplNode.setTextureUnits(texUnits, numStages);
-            }
-
-            if (linePropsChanged) {
-                linePropsChanged = false;
-
-                LineAttributes la = null;
-
-                if (vfLineProperties != null) {
-                    OGLVRMLNode o_n = (OGLVRMLNode) vfLineProperties;
-                    la = (LineAttributes) o_n.getSceneGraphObject();
-                }
-
-                oglImplNode.setLineAttributes(la);
-            }
-
-            if (pointPropsChanged) {
-                pointPropsChanged = false;
-
-                PointAttributes pa = null;
-
-                if (vfPointProperties != null) {
-                    OGLVRMLNode o_n = (OGLVRMLNode) vfPointProperties;
-                    pa = (PointAttributes) o_n.getSceneGraphObject();
-                }
-
-                oglImplNode.setPointAttributes(pa);
-            }
-
-            if (fillPropsChanged) {
-                fillPropsChanged = false;
-
-                if (!savedSolidState || !savedCCWState) {
-                    oglImplNode.setPolygonAttributes(implPA);
-                } else {
-                    oglImplNode.setPolygonAttributes(null);
-                }
-
-                /*
-                 PolygonAttributes pa = null;
-
-                 if(vfFillProperties != null) {
-                 OGLVRMLNode o_n = (OGLVRMLNode)vfFillProperties;
-                 pa = (PolygonAttributes)o_n.getSceneGraphObject();
-                 }
-
-                 oglImplNode.setPolygonAttributes(pa);
-                 */
-            }
-
-        } else if (src == implPA) {
-            if (savedSolidState) {
-                implPA.setCulledFace(PolygonAttributes.CULL_BACK);
-                implPA.setTwoSidedLighting(false);
-            } else {
-                implPA.setCulledFace(PolygonAttributes.CULL_NONE);
-                implPA.setTwoSidedLighting(true);
-            }
-
-            implPA.setCCW(savedCCWState);
-        } else if (src instanceof TextureUnit) {
-            // Check for textureUnit
-            for (int i = 0; i < numStages; i++) {
-                if (texUnits[i] == src) {
-                    if (stages[i].mode != TextureConstants.MODE_OFF) {
-                        texUnits[i].setTexture(texObjs[i]);
-                    } else {
-                        // rem: for the multi-texture mode OFF
-                        // null out the Texture in the TextureUnit
-                        texUnits[i].setTexture(null);
-                    }
-                    break;
-                }
-            }
-
-            // Remove the processed unit
-            texUnitsChanged.remove((SceneGraphObject) src);
-
-            TextureStage ts = changedTransforms.get((TextureUnit) src);
-
-            if (ts != null) {
-                TextureUnit tu = (TextureUnit) src;
-                tu.setTextureTransform((Matrix4f) ts.transform);
-                changedTransforms.remove(tu);
-            }
-
-            ts = changedTexCoordGeneration.get((TextureUnit) src);
-
-            if (ts != null) {
-                TextureUnit tu = (TextureUnit) src;
-                tu.setTexCoordGeneration((TexCoordGeneration) ts.texCoordGeneration);
-                changedTexCoordGeneration.remove(tu);
-            }
-        }
-    }
-
-    //----------------------------------------------------------
-    // Private methods
-    //----------------------------------------------------------
-
-    /**
-     * Internal convenient method to do common initialization.
-     */
-    private void init() {
-        lightingState = true;
-        localColor = false;
-        localColorAlpha = false;
-        savedSolidState = true;
-        savedCCWState = true;
-        lightingOverride = false;
-        queryPointSprites = false;
-
-        oglImplNode = new Appearance();
-
-        implPA = new PolygonAttributes();
-        texGenMap = new HashMap<>(2);
-
-        changedTransforms = new HashMap<>();
-        changedTexCoordGeneration = new HashMap<>();
-
-        if (!savedCCWState || !savedSolidState) {
-            oglImplNode.setPolygonAttributes(implPA);
-        }
-
-        if (useTextureCache) {
-            textureCache = TextureCache.getInstance();
-        }
-
-        numStages = 0;
-
-        texUnitsChanged = new ConcurrentLinkedQueue<>();
-    }
-
-    /**
-     * Create the render specific structures for this field.
-     */
-    private void createTextureUnits() {
-        // Find out how many stages to setup
-        numStages = 0;
-
-        if (vfTexture != null) {
-            switch (vfTexture.getTextureType()) {
-                case TextureConstants.TYPE_SINGLE_2D:
-                    numStages++;
-                    vrmlTexs = new VRMLTextureNodeType[numStages];
-                    modes = new int[numStages];
-                    sources = new int[numStages];
-                    functions = new int[numStages];
-                    vrmlTexs[numStages - 1] = vfTexture;
-
-                    modes[numStages - 1]
-                            = getMode(((VRMLTexture2DNodeType) vfTexture).getImage(),
-                                    true);
-
-                    if (modes[numStages - 1] == TextureConstants.MODE_REPLACE) {
-                        OGLMaterialNodeType node = (OGLMaterialNodeType) vfMaterial;
-                        Material mat = (node == null) ? null : node.getMaterial();
-
-                        if (mat != null && vfMaterial.getTransparency() == 0) {
-                            mat.setLightingEnabled(false);
-                            lightingOverride = true;
-                        } else {
-                            if (mat != null && lightingState) {
-                                mat.setLightingEnabled(true);
-                            }
-                            lightingOverride = false;
-                        }
-                    }
-                    // TODO: Fill in source and function
-                    break;
-
-                case TextureConstants.TYPE_MULTI:
-                    VRMLMultiTextureNodeType mtex
-                            = ((VRMLMultiTextureNodeType) vfTexture);
-
-                    numStages += mtex.getNumberTextures();
-
-                    vrmlTexs = new VRMLTextureNodeType[numStages];
-                    modes = new int[numStages];
-                    sources = new int[numStages];
-                    functions = new int[numStages];
-
-                    mtex.getTextures(0, vrmlTexs);
-                    mtex.getTextureParams(0, modes, functions, sources);
-                    break;
-
-                case TextureConstants.TYPE_SINGLE_3D:
-                    VRMLComposedTextureNodeType ctex
-                            = ((VRMLComposedTextureNodeType) vfTexture);
-
-                    vrmlTexs = new VRMLTextureNodeType[numStages
-                            + ctex.getNumberTextures()];
-                    numStages++;
-                    modes = new int[numStages];
-                    sources = new int[numStages];
-                    functions = new int[numStages];
-
-                    ctex.getTextures(0, vrmlTexs);
-                    modes[numStages - 1] = TextureConstants.MODE_REPLACE;
-                    break;
-
-                case TextureConstants.TYPE_PBUFFER:
-                    numStages++;
-                    vrmlTexs = new VRMLTextureNodeType[numStages];
-                    modes = new int[numStages];
-                    sources = new int[numStages];
-                    functions = new int[numStages];
-
-                    vrmlTexs[numStages - 1] = vfTexture;
-                    modes[numStages - 1] = TextureConstants.MODE_REPLACE;
-                    break;
-
-                case TextureConstants.TYPE_CUBIC_ENVIRONMAP:
-                    break;
-            }
-        }
-
-        texObjs = new Texture[numStages];
-        texUnits = new TextureUnit[numStages];
-        texAttrs = new TextureAttributes[numStages];
-
-        insureStageSize(numStages, true);
-
-        int currStage = 0;
-
-        // Setup the TextureStage variables
-        for (int i = currStage; i < numStages; i++) {
-            TextureStage tstage = stages[i];
-            TexCoordGeneration tcg = null;
-            boolean have_texture = false;
-
-            // Common variables
-            if (vfTextureProperties != null) {
-                // Only use 2D properties
-                VRMLTextureProperties2DNodeType tp
-                        = vfTextureProperties;
-
-                tstage.boundaryModeS = tp.getBoundaryModeS();
-                tstage.boundaryModeT = tp.getBoundaryModeT();
-                tstage.boundaryColor = new float[4];
-                tp.getBorderColor(tstage.boundaryColor);
-                tstage.minFilter = tp.getMinificationFilter();
-                tstage.magFilter = tp.getMagnificationFilter();
-            }
-
-            // Texture Type specific
-            int type = vrmlTexs[i].getTextureType();
-
-            switch (type) {
-                case TextureConstants.TYPE_MULTI:
-                    errorReporter.warningReport(NESTED_MULTITEXTURE_ERR, null);
-                    break;
-
-                case TextureConstants.TYPE_SINGLE_2D:
-                    type = vrmlTexs[i].getTextureType();
-
-                    if (tstage.images == null || tstage.images.length == 0) {
-                        NIOBufferImage img = ((VRMLTexture2DNodeType) vrmlTexs[i]).getImage();
-                        if (img != null) {
-                            tstage.images = processImage(0, img, null);
-                            setIgnoreDiffuse(img);
-                        }
-                    }
-
-                    tstage.mode = modes[i];
-                    if (vfTextureProperties == null) {
-                        VRMLTexture2DNodeType sn
-                                = (VRMLTexture2DNodeType) vrmlTexs[i];
-
-                        tstage.boundaryModeS = sn.getRepeatS()
-                                ? TextureConstants.BM_WRAP
-                                : DEFAULT_CLAMP_MODE;
-
-                        tstage.boundaryModeT = sn.getRepeatT()
-                                ? TextureConstants.BM_WRAP
-                                : DEFAULT_CLAMP_MODE;
-                    }
-
-                    String modeString
-                            = texGenMap.get(currStage);
-
-                    if (modeString != null) {
-                        Integer mode = texGenModeMap.get(modeString);
-
-                        if (mode != null) {
-                            tcg = new TexCoordGeneration();
-
-                            tcg.setParameter(TexCoordGeneration.TEXTURE_S,
-                                    TexCoordGeneration.MODE_GENERIC, mode,
-                                    null);
-                            tcg.setParameter(TexCoordGeneration.TEXTURE_T,
-                                    TexCoordGeneration.MODE_GENERIC, mode,
-                                    null);
-
-                            tstage.texCoordGeneration = tcg;
-                        } else {
-                            System.out.println("TexCoordGen mode not found: " + mode);
-                            tstage.texCoordGeneration = null;
-                        }
-                    }
-                    break;
-
-                case TextureConstants.TYPE_SINGLE_3D:
-
-                    tstage.mode = modes[i];
-                    // TODO: need to switch to 3D properties
-                    if (vfTextureProperties != null) {
-                        VRMLTextureProperties2DNodeType tp
-                                = vfTextureProperties;
-                        //tstage.boundaryModeR = tp.getBoundaryModeR();
-                    } else {
-                        VRMLTexture3DNodeType sn
-                                = (VRMLTexture3DNodeType) vfTexture;
-
-                        tstage.boundaryModeS = sn.getRepeatS()
-                                ? TextureConstants.BM_WRAP
-                                : DEFAULT_CLAMP_MODE;
-
-                        tstage.boundaryModeT = sn.getRepeatT()
-                                ? TextureConstants.BM_WRAP
-                                : DEFAULT_CLAMP_MODE;
-
-                        tstage.boundaryModeR = sn.getRepeatR()
-                                ? TextureConstants.BM_WRAP
-                                : DEFAULT_CLAMP_MODE;
-
-                        tstage.depth = sn.getDepth();
-                    }
-
-                    modeString = texGenMap.get(currStage);
-
-                    if (modeString != null) {
-                        Integer mode = texGenModeMap.get(modeString);
-
-                        if (mode != null) {
-                            tcg = new TexCoordGeneration();
-
-                            tcg.setParameter(TexCoordGeneration.TEXTURE_S,
-                                    TexCoordGeneration.MODE_GENERIC, mode,
-                                    null);
-                            tcg.setParameter(TexCoordGeneration.TEXTURE_T,
-                                    TexCoordGeneration.MODE_GENERIC, mode,
-                                    null);
-
-                            tcg.setParameter(TexCoordGeneration.TEXTURE_R,
-                                    TexCoordGeneration.MODE_GENERIC, mode,
-                                    null);
-
-                            tstage.texCoordGeneration = tcg;
-                        } else {
-                            System.out.println("TexCoordGen mode not found: " + mode);
-                            tstage.texCoordGeneration = null;
-                        }
-                    }
-                    break;
-
-                case TextureConstants.TYPE_PBUFFER:
-                    have_texture = true;
-                    OGLVRMLNode o_tex = (OGLVRMLNode) vfTexture;
-                    texObjs[i] = (Texture) o_tex.getSceneGraphObject();
-                    break;
-
-                case TextureConstants.TYPE_CUBIC_ENVIRONMAP:
-                    break;
-            }
-
-            if (!have_texture) {
-                texObjs[i] = createTexture(tstage, urls[i], type);
-                ((OGLTextureNodeType) vfTexture).setTexture(i, texObjs[i]);
-            }
-
-            texAttrs[i] = createTextureAttributes(i, tstage);
-            texUnits[i] = new TextureUnit(texObjs[i], texAttrs[i], tcg);
-
-            if (tstage.transform != null) {
-                texUnits[i].setTextureTransform((Matrix4f) tstage.transform);
-            }
-        }
-
-        //System.out.println("CTU: end: " + numStages);
-        oglImplNode.setTextureUnits(texUnits, numStages);
-    }
-
-    /**
-     * Create the render specific structures for this field.
-     */
-    private void createTextureTransform() {
-        if (vfTextureTransform != null) {
-            Matrix4f[] tt = ((OGLTextureCoordinateTransformNodeType) vfTextureTransform).getTransformMatrix();
-
-            int cnt = tt.length;
-
-            // Hold all texture transforms, but don't increase valid stages(numStages)
-            insureStageSize(cnt, false);
-
-            for (int i = 0; i < cnt; i++) {
-                stages[i].transform = tt[i];
-            }
-        }
-    }
-
-    /**
-     * Create the Texture object for this stage.
-     *
-     * @param tstage The stage representation for this texture
-     * @param url The url of the image, if there is one
-     * @param type The textureType (SINGLE, MULTI, 3D etc)
-     * @return A Texture object that corresponds to this stage
-     */
-    private Texture createTexture(TextureStage tstage, String url, int type) {
-        Texture ret_val = null;
-
-        // If we have no image in the first place, just return with nothing
-        // created.
-        boolean no_image_data = (tstage.images == null
-                || tstage.images.length < 1
-                || tstage.images[0] == null);
-
-        TextureComponent[] comps;
-        int len;
-        int texType;
-        int width;
-        int height;
-
-        // Setup texture stage variables
-        if (vfTextureProperties != null) {
-            VRMLTextureProperties2DNodeType tps
-                    = vfTextureProperties;
-
-            tstage.generateMipMaps = tps.getGenerateMipMaps();
-            tstage.boundaryModeS = tps.getBoundaryModeS();
-            tstage.boundaryModeT = tps.getBoundaryModeT();
-            tstage.minFilter = tps.getMinificationFilter();
-            tstage.magFilter = tps.getMagnificationFilter();
-            tstage.anisotropicMode = tps.getAnisotropicMode();
-            tstage.anisotropicDegree = tps.getAnisotropicDegree();
-        } else {
-            switch (type) {
-                case TextureConstants.TYPE_SINGLE_2D:
-                    VRMLTexture2DNodeType tex2d
-                            = (VRMLTexture2DNodeType) vrmlTexs[tstage.stageNumber];
-
-                    tstage.boundaryModeS = tex2d.getRepeatS()
-                            ? TextureConstants.BM_WRAP
-                            : DEFAULT_CLAMP_MODE;
-
-                    tstage.boundaryModeT = tex2d.getRepeatT()
-                            ? TextureConstants.BM_WRAP
-                            : DEFAULT_CLAMP_MODE;
-
-                    break;
-
-                case TextureConstants.TYPE_SINGLE_3D:
-                    VRMLTexture3DNodeType tex3d
-                            = (VRMLTexture3DNodeType) vrmlTexs[tstage.stageNumber];
-
-                    tstage.boundaryModeS = tex3d.getRepeatS()
-                            ? TextureConstants.BM_WRAP
-                            : DEFAULT_CLAMP_MODE;
-
-                    tstage.boundaryModeT = tex3d.getRepeatT()
-                            ? TextureConstants.BM_WRAP
-                            : DEFAULT_CLAMP_MODE;
-
-                    tstage.boundaryModeR = tex3d.getRepeatR()
-                            ? TextureConstants.BM_WRAP
-                            : DEFAULT_CLAMP_MODE;
-                    break;
-            }
-
-            if (anisotropicDegree > 1) {
-                tstage.anisotropicMode
-                        = TextureConstants.ANISOTROPIC_MODE_SINGLE;
-                tstage.anisotropicDegree = anisotropicDegree;
-            }
-        }
-
-        // Create the Texture object
-        try {
-            switch (type) {
-                case TextureConstants.TYPE_MULTI:
-                    break;
-
-                case TextureConstants.TYPE_SINGLE_2D:
-                    ret_val = new Texture2D();
-
-                    int val = OGLTextureConstConverter.convertAnisotropicMode(tstage.anisotropicMode);
-                    ret_val.setAnisotropicFilterMode(val);
-                    ret_val.setAnisotropicFilterDegree(tstage.anisotropicDegree);
-
-                    val = OGLTextureConstConverter.convertBoundary(tstage.boundaryModeS);
-                    ret_val.setBoundaryModeS(val);
-
-                    val = OGLTextureConstConverter.convertBoundary(tstage.boundaryModeT);
-                    ((Texture2D) ret_val).setBoundaryModeT(val);
-
-                    val = OGLTextureConstConverter.convertMinFilter(tstage.minFilter);
-                    ret_val.setMinFilter(val);
-
-                    val = OGLTextureConstConverter.convertMagFilter(tstage.magFilter);
-                    ret_val.setMagFilter(val);
-
-                    if (!no_image_data) {
-                        NIOBufferImage image = tstage.images[0];
-                        int format = getFormat(image);
-                        comps = new TextureComponent2D[1];
-
-                        comps[0] = new ByteBufferTextureComponent2D(
-                                format,
-                                image.getWidth(),
-                                image.getHeight(),
-                                image.getBuffer(null));
-                        texType = getTextureFormat(comps[0]);
-
-                        len = tstage.images.length;
-
-                        // Release reference to save memory
-                        for (int i = 0; i < len; i++) {
-                            tstage.images[i] = null;
-                        }
-
-                        tstage.images = null;
-
-                        // rem /////////////////////////////////////////////////
-                        // new image handling - just because mipmap generation
-                        // is enabled - does not mean we have mipmaps available.
-                        //if (tstage.generateMipMaps == false &&
-                        //  useMipMaps == false) {
-                        if (image.getLevels() == 1) {
-                            ////////////////////////////////////////////////////
-                            ret_val.setSources(Texture2D.MODE_BASE_LEVEL,
-                                    texType,
-                                    comps,
-                                    1);
-                        } else {
-                            ret_val.setSources(Texture2D.MODE_MIPMAP,
-                                    texType,
-                                    comps,
-                                    1);
-                        }
-
-                        comps[0].clearLocalData();
-                    }
-
-                    break;
-
-                case TextureConstants.TYPE_SINGLE_3D:
-                    ret_val = new Texture3D();
-
-                    //                val = convertAnisotropicMode(tstage.anisotropicMode);
-                    ret_val.setAnisotropicFilterMode(Texture.ANISOTROPIC_MODE_SINGLE);
-                    ret_val.setAnisotropicFilterDegree(tstage.anisotropicDegree);
-
-                    val = OGLTextureConstConverter.convertBoundary(tstage.boundaryModeS);
-                    ret_val.setBoundaryModeS(val);
-
-                    val = OGLTextureConstConverter.convertBoundary(tstage.boundaryModeT);
-                    ((Texture3D) ret_val).setBoundaryModeT(val);
-
-                    val = OGLTextureConstConverter.convertBoundary(tstage.boundaryModeR);
-                    ((Texture3D) ret_val).setBoundaryModeR(val);
-
-                    val = OGLTextureConstConverter.convertMinFilter(tstage.minFilter);
-                    ret_val.setMinFilter(val);
-
-                    val = OGLTextureConstConverter.convertMagFilter(tstage.magFilter);
-                    ret_val.setMagFilter(val);
-
-                    // Do a couple more checks on the texture object
-                    // and whether we should load the image information.
-                    // Not enough images in the array yet.
-                    if (tstage.images.length < tstage.depth) {
-                        no_image_data = true;
-                    }
-
-                    // Don't create a texture until we have all the images
-                    // specified.
-                    if (!no_image_data) {
-                        int format = getFormat(tstage.images[0]);
-                        for (int i = 0; i < tstage.depth; i++) {
-                            if (tstage.images[i] == null) {
-                                no_image_data = true;
-                            }
-
-                            if (getFormat(tstage.images[i]) != format) {
-                                no_image_data = true;
-                            }
-                        }
-                    }
-
-                    if (!no_image_data) {
-                        int format = getFormat(tstage.images[0]);
-                        width = tstage.images[0].getWidth();
-                        height = tstage.images[0].getHeight();
-
-                        TextureComponent3D[] comp_3
-                                = new TextureComponent3D[1];
-
-                        int num_img = tstage.images.length;
-                        ByteBuffer[] img_buffer = new ByteBuffer[num_img];
-                        for (int i = 0; i < num_img; i++) {
-                            img_buffer[i] = tstage.images[i].getBuffer();
-                        }
-                        comp_3[0] = new ByteBufferTextureComponent3D(
-                                width,
-                                height,
-                                format,
-                                img_buffer);
-
-                        texType = getTextureFormat(comp_3[0]);
-                        ret_val.setSources(Texture3D.MODE_BASE_LEVEL,
-                                texType,
-                                comp_3,
-                                1);
-
-                        tstage.images = null;
-                    }
-
-                    break;
-            }
-        } catch (InvalidWriteTimingException e) {
-            errorReporter.errorReport(TEXTURE_CREATE_FAIL_MSG + url, e);
-            return ret_val;
-        }
-
-        // rem //////////////////////////////////////////////////////////////////////
-        // the following is a legacy comment from the previous caching system.
-        // preserved as there will probably still be an issue with 3D textures
-        // using the new texture cache
-        //////////////////////////////////////////////////////////////////////////////
-        // TODO:
-        // There's an implementation issue here with 3D textures, particularly for
-        // textures that use multiple separate images. Only the last loaded image is
-        // actually cached. If the image is reloaded, then if one of the other URLs is
-        // the last to load, it will return null for the texture as it says it has the
-        // texture pre-loaded, but doesn't have it cached. This is.... unfortunate.
-        /*
-         if (useTextureCache && url != null) {
-         ((AVTextureCache)textureCache).registerTexture(ret_val, url);
-         }
-         */
-        //
-        //////////////////////////////////////////////////////////////////////////////
-        if (useTextureCache) {
-            ret_val = textureCache.register(url, ret_val);
-        }
-
-        return ret_val;
-    }
-
-    /**
-     * Create the textureAttributes for a texture stage.
-     */
-    private TextureAttributes createTextureAttributes(int stage,
-            TextureStage tstage) {
-
-        TextureAttributes ret_val = new TextureAttributes();
-
-        // this MUST stay here, before the vfPointProperties check !
-        setTextureMode(stage, tstage, ret_val);
-
-        if (pointSpritesSupported && vfPointProperties != null) {
-            ret_val.setPointSpriteCoordEnabled(true);
-            ret_val.setTextureMode(TextureAttributes.MODE_COMBINE);
-            ret_val.setCombineMode(true, TextureAttributes.COMBINE_MODULATE);
-
-            switch (vfPointProperties.getColorMode()) {
-                case VRMLPointPropertiesNodeType.POINT_COLOR_MODE:
-                    // use point color only
-                    ret_val.setCombineSource(false, 0, TextureAttributes.SOURCE_BASE_COLOR);
-                    ret_val.setCombineMode(false, TextureAttributes.COMBINE_REPLACE);
-                    break;
-                case VRMLPointPropertiesNodeType.TEXTURE_AND_POINT_COLOR_MODE:
-                    // use both point color and texture color
-                    ret_val.setCombineMode(false, TextureAttributes.COMBINE_ADD);
-                    break;
-                default:
-                    ret_val.setCombineMode(false, TextureAttributes.COMBINE_REPLACE);
-                    break;
-            }
-        } else {
-            ret_val.setPointSpriteCoordEnabled(false);
-        }
-
-        /*
-         if (tstage.transform != null)
-         ret_val.setTextureTransform((Transform3D)tstage.transform);
-         */
-        return ret_val;
-    }
-
-    /**
-     * Set the texture mode based on stage information.
-     */
-    private void setTextureMode(int stage,
-            TextureStage tstage,
-            TextureAttributes atts) {
-
-        switch (tstage.mode) {
-            case TextureConstants.MODE_REPLACE:
-                atts.setTextureMode(TextureAttributes.MODE_REPLACE);
-                break;
-            case TextureConstants.MODE_MODULATE:
-                atts.setTextureMode(TextureAttributes.MODE_MODULATE);
-                break;
-            case TextureConstants.MODE_MODULATE_2X:
-                atts.setTextureMode(TextureAttributes.MODE_MODULATE);
-                atts.setCombineScale(false, 2);
-                break;
-            case TextureConstants.MODE_MODULATE_4X:
-                atts.setTextureMode(TextureAttributes.MODE_MODULATE);
-                atts.setCombineScale(false, 4);
-                break;
-            case TextureConstants.MODE_DOTPRODUCT3:
-                atts.setTextureMode(TextureAttributes.MODE_COMBINE);
-                atts.setCombineMode(false, TextureAttributes.COMBINE_DOT3_RGB);
-                atts.setCombineMode(true, TextureAttributes.COMBINE_REPLACE);
-                atts.setCombineSource(false, 0, TextureAttributes.SOURCE_CURRENT_TEXTURE);
-
-            //                atts.setBlendColor(0.5f, 0, 0, 1);
-                //                atts.setCombineSource(true, 0, TextureAttributes.SOURCE_CONSTANT_COLOR);
-                break;
-            case TextureConstants.MODE_ADD:
-                atts.setTextureMode(TextureAttributes.MODE_COMBINE);
-                atts.setCombineMode(false, TextureAttributes.COMBINE_ADD);
-                atts.setCombineMode(true, TextureAttributes.MODE_REPLACE);
-                break;
-            case TextureConstants.MODE_ADD_SIGNED:
-                atts.setTextureMode(TextureAttributes.MODE_COMBINE);
-                atts.setCombineMode(false, TextureAttributes.COMBINE_ADD_SIGNED);
-                break;
-            case TextureConstants.MODE_ADD_SIGNED_2X:
-                atts.setTextureMode(TextureAttributes.MODE_COMBINE);
-                atts.setCombineMode(false, TextureAttributes.COMBINE_ADD_SIGNED);
-                atts.setCombineScale(false, 2);
-                break;
-            case TextureConstants.MODE_SUBTRACT:
-                atts.setTextureMode(TextureAttributes.MODE_COMBINE);
-                atts.setCombineMode(false, TextureAttributes.COMBINE_SUBTRACT);
-                break;
-            case TextureConstants.MODE_OFF:
-                if (texUnits[stage] != null) {
-                    texUnits[stage].setTexture(null);
-                }
-                break;
-
-            default:
-                System.err.println("Unknown TextureConstants.Mode: " + tstage.mode);
-        }
-    }
-
-    /**
-     * From the image component format, generate the appropriate texture format.
-     *
-     * @param comp The image component to get the value from
-     * @return The appropriate corresponding texture format value
-     */
-    protected int getTextureFormat(TextureComponent comp) {
-
-        int ret_val = Texture.FORMAT_RGB;
-
-        switch (comp.getFormat(0)) {
-            case TextureComponent.FORMAT_SINGLE_COMPONENT:
-
-                // could also be alpha, but we'll punt for now. We really need
-                // the user to pass in this information. Need to think of a
-                // good way of doing this.
-                ret_val = Texture.FORMAT_LUMINANCE;
-                break;
-
-            case TextureComponent.FORMAT_INTENSITY_ALPHA:
-                ret_val = Texture.FORMAT_LUMINANCE_ALPHA;
-                break;
-
-            case TextureComponent.FORMAT_RGB:
-                ret_val = Texture.FORMAT_RGB;
-                break;
-
-            case TextureComponent.FORMAT_RGBA:
-                ret_val = Texture.FORMAT_RGBA;
-                break;
-        }
-
-        return ret_val;
-    }
-
-    /**
-     * From the image information, generate the appropriate TextureComponent
-     * type.
-     *
-     * @param image The image component to get the value from
-     * @return The appropriate corresponding texture format value
-     */
-    protected int getFormat(NIOBufferImage image) {
-
-        int format = 0;
-        NIOBufferImageType type = image.getType();
-
-        if (type == NIOBufferImageType.INTENSITY) {
-
-            format = TextureComponent.FORMAT_SINGLE_COMPONENT;
-
-        } else if (type == NIOBufferImageType.INTENSITY_ALPHA) {
-
-            format = TextureComponent.FORMAT_INTENSITY_ALPHA;
-
-        } else if (type == NIOBufferImageType.RGB) {
-
-            format = TextureComponent.FORMAT_RGB;
-
-        } else if (type == NIOBufferImageType.RGBA) {
-
-            format = TextureComponent.FORMAT_RGBA;
-
-        } else {
-
-            System.err.println("Unknown NIOBufferImageType: " + type.name);
-        }
-
-        return format;
-    }
-
-    /**
-     * Given the image format return the texturing mode to use. For the X3D
-     * lighting model, whether to use MODULATE or REPLACE.
-     *
-     * @param image The image component to get the value from
-     * @param configMaterial Should this affect the material
-     * @return the texturing mode to use
-     */
-    private int getMode(NIOBufferImage image, boolean configMaterial) {
-
-        int mode = TextureConstants.MODE_MODULATE;
-        if (configMaterial) {
-            setIgnoreDiffuse(image);
-        }
-        return mode;
-    }
-
-    /**
-     * Configure the ignoreDiffuse property of the material based on the image.
-     */
-    private void setIgnoreDiffuse(NIOBufferImage image) {
-
-        boolean ignoreDiffuse = true;
-        if (image != null) {
-
-            // TODO: Why would we care to ignore diffuse color if the single
-            // image texture is not gray scale?  Flipping the boolean doesn't 
-            // seem right. (TDN)
-//            ignoreDiffuse = !image.isGrayScale();
-            ignoreDiffuse = image.isGrayScale();
-        }
-
-        if (vfMaterial != null) {
-            vfMaterial.setIgnoreDiffuse(ignoreDiffuse);
-        }
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2003 - 2007
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.renderer.ogl.nodes.shape;
+
+// External imports
+import java.nio.ByteBuffer;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import javax.vecmath.Matrix4f;
+
+import org.j3d.aviatrix3d.*;
+
+// Local imports
+import org.web3d.image.NIOBufferImage;
+import org.web3d.image.NIOBufferImageType;
+
+import org.web3d.vrml.lang.*;
+
+import org.web3d.vrml.nodes.*;
+
+import org.web3d.vrml.renderer.common.nodes.shape.BaseAppearance;
+import org.web3d.vrml.renderer.common.nodes.shape.TextureStage;
+
+import org.web3d.vrml.renderer.ogl.nodes.*;
+import org.web3d.vrml.renderer.ogl.nodes.TextureCache;
+
+/**
+ * OpenGL implementation of an Appearance node.
+ * <p>
+ *
+ * MultiTexture Notes: function and source not mapped
+ *
+ * 3D Texture Notes: Getting a rescale problem, not working.
+ *
+ * Cubic Environment Notes: Not implemented.
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.70 $
+ */
+public class OGLAppearance extends BaseAppearance
+        implements OGLAppearanceNodeType,
+        OGLTextureTransformListener,
+        NodeUpdateListener,
+        FrameStateListener {
+
+    /**
+     * Error message when something goes wrong in createTexture()
+     */
+    private static final String TEXTURE_CREATE_FAIL_MSG
+            = "Failed for an unknown reason during the creation of the base "
+            + "texture image in OGLAppearance.createTexture(). URL is: ";
+
+    /**
+     * The texture field contains a Multitexture with a nested multitexture
+     * instance as a child. This is baaaaad and not legal by the spec. Hopefully
+     * the parsing or scene building has picked this up, but we'll do another
+     * check anyway. This is the error message for that redundant check as we're
+     * building the scene graph.
+     */
+    private static final String NESTED_MULTITEXTURE_ERR
+            = "Discovered a nested MultiTexture node while processing a "
+            + "MultiTexture node. This is not legal. See 19775-1 18.4.3 "
+            + "paragraph 2 for more information";
+
+    /**
+     * The default mode to use for CLAMP. X3D spec is silent right now
+     */
+    private static final int DEFAULT_CLAMP_MODE = TextureConstants.BM_CLAMP_EDGE;
+
+    /**
+     * A map between TexCoordGen modes and AV3D modes
+     */
+    private static final Map<String, Integer> texGenModeMap;
+
+    /**
+     * The OpenGL Implementation node for the appearance
+     */
+    private Appearance oglImplNode;
+
+    /**
+     * The OpenGL Implementation node for the solid flag handling
+     */
+    private PolygonAttributes implPA;
+
+    /**
+     * The current Texture attribute information
+     */
+    private TextureAttributes[] texAttrs;
+
+    /**
+     * The TextureUnitStates used for multitexturing
+     */
+    private TextureUnit[] texUnits;
+
+    /**
+     * A map between texture unit and texture gen mode
+     */
+    private Map<Integer, String> texGenMap;
+
+    /**
+     * The OGL texture objects
+     */
+    private Texture[] texObjs;
+
+    /**
+     * The vrml texture objects
+     */
+    private VRMLTextureNodeType[] vrmlTexs;
+
+    /**
+     * The mode for each stage
+     */
+    private int[] modes;
+
+    /**
+     * The function for each stage
+     */
+    private int[] functions;
+
+    /**
+     * The source for each stage
+     */
+    private int[] sources;
+
+    /**
+     * Flag to indicate a textureUnit has changed off thread
+     */
+    private boolean threadedUnitChanged;
+
+    /**
+     * Flag indicating that the material has changed
+     */
+    private boolean materialChanged;
+
+    /**
+     * Flag indicating that the fill properties changed
+     */
+    private boolean fillPropsChanged;
+
+    /**
+     * Flag indicating that the line properties changed
+     */
+    private boolean linePropsChanged;
+
+    /**
+     * Flag indicating that the point properties changed
+     */
+    private boolean pointPropsChanged;
+
+    /**
+     * Did all the texture units get changed
+     */
+    private boolean textureUnitsChanged;
+
+    /**
+     * Flag indicating that the texture transform node has changed
+     */
+    private boolean textureTransformChanged;
+
+    /**
+     * Maps the AV3D TextureUnit to the TextureStage that has changed.
+     */
+    private Map<TextureUnit, TextureStage> changedTransforms;
+
+    /**
+     * Maps the AV3D TextureUnit to the TextureStage that has changed.
+     */
+    private Map<TextureUnit, TextureStage> changedTexCoordGeneration;
+
+    /**
+     * Flag indicating that the texture changed
+     */
+    private boolean textureChanged;
+
+    /**
+     * Solid state passed in from the geometry flags
+     */
+    private boolean savedSolidState;
+
+    /**
+     * Solid state passed in from the geometry flags
+     */
+    private boolean savedCCWState;
+
+    /**
+     * A double buffered list of tex units changed
+     */
+    private ConcurrentLinkedQueue<SceneGraphObject> texUnitsChanged;
+
+    /**
+     * The current lighting state
+     */
+    private boolean lightingState;
+
+    /**
+     * Whether to override diffuse color with local colors
+     */
+    private boolean localColor;
+
+    /**
+     * Whether the local color also includes alpha values
+     */
+    private boolean localColorAlpha;
+
+    /**
+     * Should we force lighting off
+     */
+    boolean lightingOverride;
+
+    /**
+     * The local texture cache for AV3D textures
+     */
+    private TextureCache textureCache;
+
+    /**
+     * Should we query for point sprites
+     */
+    private boolean queryPointSprites;
+
+    /**
+     * PointSprites supported
+     */
+    private static boolean pointSpritesSupported;
+
+    static {
+        texGenModeMap = new HashMap<>(3);
+        texGenModeMap.put("SPHERE", TexCoordGeneration.MAP_SPHERICAL);
+        texGenModeMap.put("CAMERASPACENORMAL", TexCoordGeneration.MAP_NORMALS);
+        texGenModeMap.put("CAMERASPACEREFLECTIONVECTOR", TexCoordGeneration.MAP_REFLECTIONS);
+
+        // TODO: Not positive this is the correct mapping from spec language
+        texGenModeMap.put("CAMERASPACEPOSITION", TexCoordGeneration.MAP_EYE_LINEAR);
+    }
+
+    /**
+     * Empty constructor
+     */
+    public OGLAppearance() {
+        init();
+    }
+
+    /**
+     * Construct a new instance of this node based on the details from the given
+     * node. If the node is not a Appearance node, an exception will be thrown.
+     *
+     * @param node The node to copy
+     * @throws IllegalArgumentException The node is not a Group node
+     */
+    public OGLAppearance(VRMLNodeType node) {
+        super(node);
+
+        init();
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by FrameStateListener
+    //----------------------------------------------------------
+
+    /**
+     * Notification that the rendering of the event model is complete and that
+     * rendering is about to begin.
+     */
+    @Override
+    public void allEventsComplete() {
+
+        if (materialChanged || linePropsChanged || pointPropsChanged
+                || fillPropsChanged) {
+            oglImplNode.dataChanged(this);
+        } else if (threadedUnitChanged) {
+
+            while (!texUnitsChanged.isEmpty()) {
+
+                SceneGraphObject unit
+                        = texUnitsChanged.poll();
+
+                if (unit.isLive()) {
+                    unit.dataChanged(this);
+                } else {
+                    updateNodeDataChanges(unit);
+                }
+
+                threadedUnitChanged = false;
+            }
+        } else if (queryPointSprites) {
+            queryPointSprites = false;
+
+            if (vfPointProperties != null) {
+                OGLVRMLNode o_n = (OGLVRMLNode) vfPointProperties;
+                PointAttributes pa = (PointAttributes) o_n.getSceneGraphObject();
+
+                pointSpritesSupported = pa.isPointSpriteAllowed();
+
+                if (!pointSpritesSupported) {
+                    System.out.println("OGL Point sprites not supported, unroll");
+                    pa.setPointSpriteEnabled(false);
+                    pa.setAntiAliased(true);
+
+                    // TODO: Disable texturing.  This is not exactly right if someone provided
+                    // PointProperties for a non pointset
+                    vfTexture = null;
+
+                    textureChanged = true;
+
+                    if (oglImplNode.isLive()) {
+                        oglImplNode.dataChanged(this);
+                    } else {
+                        updateNodeDataChanges(oglImplNode);
+                    }
+                }
+            }
+        }
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by VRMLAppearanceNodeType
+    //----------------------------------------------------------
+    
+    /**
+     * Set the material that should be used for this appearance. Setting a value
+     * of null will clear the current material.
+     *
+     * @param newMaterial The new material instance to be used.
+     * @throws InvalidFieldValueException The node does not match the required
+     * type.
+     */
+    @Override
+    public void setMaterial(VRMLNodeType newMaterial)
+            throws InvalidFieldValueException {
+
+        super.setMaterial(newMaterial);
+
+        if (inSetup) {
+            return;
+        }
+
+        if (vfMaterial != null && !lightingOverride) {
+            ((OGLMaterialNodeType) vfMaterial).setLightingEnable(lightingState);
+        }
+
+        materialChanged = true;
+        if (oglImplNode.isLive()) {
+            oglImplNode.dataChanged(this);
+        } else {
+            updateNodeDataChanges(oglImplNode);
+        }
+    }
+
+    /**
+     * Set the texture that should be used for this appearance. Setting a value
+     * of null will clear the current texture.
+     *
+     * @param newTexture The new texture instance to be used.
+     * @throws InvalidFieldValueException The node does not match the required
+     * type.
+     */
+    @Override
+    public void setTexture(VRMLNodeType newTexture)
+            throws InvalidFieldValueException {
+
+        VRMLTextureNodeType old_node = vfTexture;
+
+        super.setTexture(newTexture);
+
+        if (old_node != null) {
+            old_node.removeTextureListener(this);
+        }
+
+        if (vfTexture != null) {
+            vfTexture.addTextureListener(this);
+        }
+
+        if (inSetup) {
+            return;
+        }
+
+        textureChanged = true;
+
+        if (oglImplNode.isLive()) {
+            oglImplNode.dataChanged(this);
+        } else {
+            updateNodeDataChanges(oglImplNode);
+        }
+    }
+
+    /**
+     * Set the texture transform that should be used for this appearance.
+     * Setting a value of null will clear the current texture transform.
+     *
+     * @param newTransform The new texture transform instance to be used.
+     * @throws InvalidFieldValueException The node does not match the required
+     * type.
+     */
+    @Override
+    public void setTextureTransform(VRMLNodeType newTransform)
+            throws InvalidFieldValueException {
+
+        OGLTextureCoordinateTransformNodeType old_node
+                = (OGLTextureCoordinateTransformNodeType) vfTextureTransform;
+
+        super.setTextureTransform(newTransform);
+
+        OGLTextureCoordinateTransformNodeType node
+                = (OGLTextureCoordinateTransformNodeType) vfTextureTransform;
+
+        if (node != null) {
+            node.addTransformListener(this);
+        }
+
+        if (old_node != null) {
+            old_node.removeTransformListener(this);
+        }
+
+        if (inSetup) {
+            return;
+        }
+
+        textureTransformChanged = true;
+        if (oglImplNode.isLive()) {
+            oglImplNode.dataChanged(this);
+        } else {
+            updateNodeDataChanges(oglImplNode);
+        }
+    }
+
+    /**
+     * Set the line properties that should be used for this appearance. Setting
+     * a value of null will clear the current property.
+     *
+     * @param prop The new property instance instance to be used.
+     * @throws InvalidFieldValueException The node does not match the required
+     * type.
+     */
+    @Override
+    public void setLineProperties(VRMLNodeType prop)
+            throws InvalidFieldValueException {
+
+        super.setLineProperties(prop);
+
+        if (inSetup) {
+            return;
+        }
+
+        linePropsChanged = true;
+        if (oglImplNode.isLive()) {
+            oglImplNode.dataChanged(this);
+        } else {
+            updateNodeDataChanges(oglImplNode);
+        }
+    }
+
+    /**
+     * Set the point properties that should be used for this appearance. Setting
+     * a value of null will clear the current property.
+     *
+     * @param prop The new property instance instance to be used.
+     * @throws InvalidFieldValueException The node does not match the required
+     * type.
+     */
+    @Override
+    public void setPointProperties(VRMLNodeType prop)
+            throws InvalidFieldValueException {
+
+        super.setPointProperties(prop);
+
+        if (inSetup) {
+            return;
+        }
+
+        pointPropsChanged = true;
+        if (oglImplNode.isLive()) {
+            oglImplNode.dataChanged(this);
+        } else {
+            updateNodeDataChanges(oglImplNode);
+        }
+    }
+
+    /**
+     * Set the fillProperties that should be used for this appearance. Setting a
+     * value of null will clear the current property.
+     *
+     * @param prop The new fillProperties instance to be used.
+     * @throws InvalidFieldValueException The node does not match the required
+     * type.
+     */
+    @Override
+    public void setFillProperties(VRMLNodeType prop)
+            throws InvalidFieldValueException {
+
+        super.setFillProperties(prop);
+
+        if (inSetup) {
+            return;
+        }
+
+        fillPropsChanged = true;
+        if (oglImplNode.isLive()) {
+            oglImplNode.dataChanged(this);
+        } else {
+            updateNodeDataChanges(oglImplNode);
+        }
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by OGLAppearanceNodeType
+    //----------------------------------------------------------
+
+    /**
+     * Get the appearance instance used to represent this object.
+     *
+     * @return The appearance instance
+     */
+    @Override
+    public Appearance getAppearance() {
+        return oglImplNode;
+    }
+
+    /**
+     * Set the texture coordinate generation mode for a texture set. If its not
+     * set then texture coordinates will be used. A value of null will clear the
+     * setting.
+     *
+     * @param setNum The set which this tex gen mode refers
+     * @param mode The mode to use. Straight VRML field value
+     */
+    @Override
+    public void setTexCoordGenMode(int setNum, String mode) {
+        texGenMap.put(setNum, mode);
+
+        if (inSetup) {
+            return;
+        }
+
+        Integer imode = texGenModeMap.get(mode);
+
+        if (imode != null) {
+            TexCoordGeneration newtcg = new TexCoordGeneration();
+
+            newtcg.setParameter(TexCoordGeneration.TEXTURE_S,
+                    TexCoordGeneration.MODE_GENERIC, imode,
+                    null);
+            newtcg.setParameter(TexCoordGeneration.TEXTURE_T,
+                    TexCoordGeneration.MODE_GENERIC, imode,
+                    null);
+
+            if (vfTexture != null
+                    && vfTexture.getTextureType() == TextureConstants.TYPE_SINGLE_3D) {
+
+                newtcg.setParameter(TexCoordGeneration.TEXTURE_R,
+                        TexCoordGeneration.MODE_GENERIC, imode,
+                        null);
+            }
+
+            stages[setNum].texCoordGeneration = newtcg;
+
+            changedTexCoordGeneration.put(texUnits[setNum], stages[setNum]);
+
+            if (texUnits[setNum].isLive()) {
+                texUnits[setNum].dataChanged(this);
+            } else {
+                updateNodeDataChanges(texUnits[setNum]);
+            }
+
+        } else {
+            // Clear
+
+            stages[setNum].texCoordGeneration = null;
+
+            changedTexCoordGeneration.put(texUnits[setNum], stages[setNum]);
+
+            if (texUnits[setNum].isLive()) {
+                texUnits[setNum].dataChanged(this);
+            } else {
+                updateNodeDataChanges(texUnits[setNum]);
+            }
+        }
+    }
+
+    /**
+     * Specify whether an object is solid. The default is true. This will
+     * determine if we do backface culling and flip backface normals. Can only
+     * be set during setup
+     *
+     * @param solid Whether the object is solid
+     */
+    @Override
+    public void setSolid(boolean solid) {
+        savedSolidState = solid;
+        if (implPA.isLive()) {
+            implPA.dataChanged(this);
+        } else {
+            updateNodeDataChanges(implPA);
+        }
+
+        // May need to add or remove the polyAttr from the appearance
+        // depending on the combined state of this and CCW
+        fillPropsChanged = true;
+        if (oglImplNode.isLive()) {
+            oglImplNode.dataChanged(this);
+        } else {
+            updateNodeDataChanges(oglImplNode);
+        }
+    }
+
+    /**
+     * Set whether lighting will be used for this appearance. In general you
+     * should let the material node decide this. Needed to handle
+     * IndexedLineSets or other geometry that specifically declares lighting be
+     * turned off. This method will notify the related Material node for this
+     * Appearance.
+     *
+     * @param enable Whether lighting is enabled
+     */
+    @Override
+    public void setLightingEnabled(boolean enable) {
+        lightingState = enable;
+
+        if (vfMaterial != null && !lightingOverride) {
+            ((OGLMaterialNodeType) vfMaterial).setLightingEnable(enable);
+        }
+    }
+
+    /**
+     * Set whether the geometry has local colors to override the diffuse color.
+     *
+     * @param enable Whether local color is enabled
+     * @param hasAlpha true with the local color also contains alpha values
+     */
+    @Override
+    public void setLocalColor(boolean enable, boolean hasAlpha) {
+        localColor = enable;
+        localColorAlpha = hasAlpha;
+
+        if (vfMaterial != null) {
+            ((OGLMaterialNodeType) vfMaterial).setLocalColor(enable, hasAlpha);
+        }
+    }
+
+    /**
+     * Specify whether the geometry's triangles are in counter clockwise order
+     * (the default) or clockwise. The default is true. This will determine if
+     * we do backface culling and flip backface normals. Can only be set during
+     * setup
+     *
+     * @param ccw True for counter-clockwise ordering
+     */
+    @Override
+    public void setCCW(boolean ccw) {
+        savedCCWState = ccw;
+        if (implPA.isLive()) {
+            implPA.dataChanged(this);
+        } else {
+            updateNodeDataChanges(implPA);
+        }
+
+        // May need to add or remove the polyAttr from the appearance
+        // depending on the combined state of this and solid
+        fillPropsChanged = true;
+        if (oglImplNode.isLive()) {
+            oglImplNode.dataChanged(this);
+        } else {
+            updateNodeDataChanges(oglImplNode);
+        }
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by OGLTextureTransformListener
+    //----------------------------------------------------------
+
+    /**
+     * Invoked when a textureTransform has changed.
+     *
+     * @param src The node instance that was the source of this change
+     * @param tmatrix The new TransformMatrix array
+     * @param updated Flag for each index illustrating whether it has been
+     * updated or not.
+     */
+    @Override
+    public void textureTransformChanged(OGLVRMLNode src,
+            Matrix4f[] tmatrix,
+            boolean[] updated) {
+
+        int cnt = tmatrix.length;
+
+        insureStageSize(cnt, false);
+
+        for (int i = 0; i < cnt; i++) {
+            if (!updated[i]) {
+                continue;
+            }
+
+            changedTransforms.put(texUnits[i], stages[i]);
+
+            stages[i].transform = tmatrix[i];
+
+            if (texUnits[i].isLive()) {
+                texUnits[i].dataChanged(this);
+            } else {
+                updateNodeDataChanges(texUnits[i]);
+            }
+        }
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by VRMLTextureListener
+    //----------------------------------------------------------
+
+    /**
+     * Invoked when an underlying image has changed. Synchronized due to
+     * competition for the image arrays.
+     *
+     * @param idx The image idx which changed.
+     * @param node The texture which changed.
+     * @param image The image for this texture.
+     * @param url The url used to load this image.
+     */
+    @Override
+    public synchronized void textureImageChanged(
+            int idx,
+            VRMLNodeType node,
+            NIOBufferImage image,
+            String url) {
+
+        super.textureImageChanged(idx, node, image, url);
+
+        if (idx < numStages && vrmlTexs != null) {
+            int type = vfTexture.getTextureType();
+            switch (type) {
+                case TextureConstants.TYPE_SINGLE_2D:
+                    // rem /////////////////////////////////////////////////////
+                    // set ignore diffuse on the material node in the
+                    // case of a single texture, but not a multi-texture
+                    TextureStage tstage = stages[idx];
+                    if ((tstage.images != null) && (tstage.images.length > 0)) {
+                        setIgnoreDiffuse(tstage.images[0]);
+                    }
+                    // TDN 02 APR 2013 /////////////////////////////////////////
+                    // A break statement here WILL break texturing, therefore a
+                    // deliberate fallthrough is permitted here.
+                    ////////////////////////////////////////////////////////////
+                case TextureConstants.TYPE_MULTI:
+                    texObjs[idx] = createTexture(stages[idx],
+                            url,
+                            vrmlTexs[idx].getTextureType());
+                    /*
+                     System.out.println("Forcing call to texture atts");
+                     texAttrs[idx] = createTextureAttributes(idx,stages[idx]);
+                     */
+                    texUnitsChanged.add(texUnits[idx]);
+
+                    ((OGLTextureNodeType) vfTexture).setTexture(idx,
+                            texObjs[idx]);
+                    threadedUnitChanged = true;
+                    stateManager.addEndOfThisFrameListener(this);
+                    break;
+
+                case TextureConstants.TYPE_SINGLE_3D:
+                    texObjs[0] = createTexture(stages[0], url, type);
+                    texUnitsChanged.add(texUnits[0]);
+                    ((OGLTextureNodeType) vfTexture).setTexture(0, texObjs[0]);
+                    threadedUnitChanged = true;
+                    stateManager.addEndOfThisFrameListener(this);
+                    break;
+            }
+        } else {
+            //System.out.println("** Create TU: " + url);
+            createTextureUnits();
+        }
+    }
+
+    /**
+     * Invoked when all of the underlying images have changed.
+     *
+     * @param len The number of valid entries in the image array.
+     * @param node The textures which changed.
+     * @param image The images for this texture.
+     * @param url The urls used to load these images.
+     */
+    @Override
+    public void textureImageChanged(int len,
+            VRMLNodeType[] node,
+            NIOBufferImage[] image,
+            String[] url) {
+
+        super.textureImageChanged(len, node, image, url);
+
+        // rem //////////////////////////////////////////////////////////////////
+        // this has not been tested - doesn't look right
+        if (len <= numStages) {
+            int type = vfTexture.getTextureType();
+
+            if (type == TextureConstants.TYPE_SINGLE_3D) {
+                stages[0].mode = getMode(image[0], true);
+                texObjs[0] = createTexture(stages[0], null, type);
+                texUnits[0].setTexture(texObjs[0]);
+                ((OGLTextureNodeType) vfTexture).setTexture(0, texObjs[0]);
+
+            } else {
+                for (int idx = 0; idx < len; idx++) {
+                    stages[idx].mode = getMode(image[idx], (idx == 0));
+                    texObjs[idx] = createTexture(stages[idx],
+                            url[idx],
+                            vrmlTexs[idx].getTextureType());
+                    // TODO: shouldn't this call dataChanged?
+                    texUnits[idx].setTexture(texObjs[idx]);
+                    ((OGLTextureNodeType) vfTexture).setTexture(idx, texObjs[idx]);
+                }
+            }
+        } else {
+            createTextureUnits();
+        }
+        //////////////////////////////////////////////////////////////////////////
+    }
+
+    /**
+     * Invoked when the texture parameters have changed. The most efficient
+     * route is to set the parameters before the image.
+     *
+     * @param idx The texture index which changed.
+     * @param mode The mode for the stage.
+     * @param source The source for the stage.
+     * @param function The function to apply to the stage values.
+     * @param alpha The alpha value to use for modes requiring it.
+     * @param color The color to use for modes requiring it. 3 Component color.
+     */
+    @Override
+    public void textureParamsChanged(int idx, int mode,
+            int source, int function, float alpha, float[] color) {
+
+        super.textureParamsChanged(idx, mode, source, function, alpha, color);
+    }
+
+    /**
+     * Invoked when the texture parameters have changed. The most efficient
+     * route is to set the parameters before the image.
+     *
+     * @param len The number of valid entries in the arrays.
+     * @param mode The mode for the stage.
+     * @param source The source for the stage.
+     * @param function The function to apply to the stage values.
+     * @param alpha The alpha value to use for modes requiring it.
+     * @param color The color to use for modes requiring it. An array of 3
+     * component colors.
+     */
+    @Override
+    public void textureParamsChanged(int len,
+            int mode[],
+            int[] source,
+            int[] function,
+            float alpha,
+            float[] color) {
+
+        super.textureParamsChanged(len, mode, source, function, alpha, color);
+
+        if (len <= numStages) {
+            for (int idx = 0; idx < len; idx++) {
+                stages[idx].mode = mode[idx];
+                setTextureMode(idx, stages[idx], texAttrs[idx]);
+            }
+        } else {
+            createTextureUnits();
+        }
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by OGLVRMLNodeType
+    //----------------------------------------------------------
+
+    /**
+     * Get the scene graph object representation of this node. This will need to
+     * be cast to the appropriate parent type when being used.
+     *
+     * @return The OGL representation.
+     */
+    @Override
+    public SceneGraphObject getSceneGraphObject() {
+        return oglImplNode;
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by VRMLNodeType
+    //----------------------------------------------------------
+
+    /**
+     * Notification that the construction phase of this node has finished. If
+     * the node would like to do any internal processing, such as setting up
+     * geometry, then go for it now.
+     */
+    @Override
+    public void setupFinished() {
+
+        if (!inSetup) {
+            return;
+        }
+
+        super.setupFinished();
+
+        OGLMaterialNodeType node = (OGLMaterialNodeType) vfMaterial;
+        if (vfMaterial != null) {
+            node.setLightingEnable(lightingState);
+            node.setLocalColor(localColor, localColorAlpha);
+        }
+
+        Material mat = (node == null) ? null : node.getMaterial();
+        oglImplNode.setMaterial(mat);
+
+        if (vfLineProperties != null) {
+            OGLVRMLNode o_n = (OGLVRMLNode) vfLineProperties;
+            LineAttributes la = (LineAttributes) o_n.getSceneGraphObject();
+            oglImplNode.setLineAttributes(la);
+        }
+
+        if (vfPointProperties != null) {
+            queryPointSprites = true;
+            // Find out whether we have point sprite support
+            stateManager.addEndOfThisFrameListener(this);
+
+            OGLVRMLNode o_n = (OGLVRMLNode) vfPointProperties;
+            PointAttributes pa = (PointAttributes) o_n.getSceneGraphObject();
+
+            if (pointSpritesSupported && vfTexture != null) {
+                pa.setAntiAliased(false);
+                pa.setPointSpriteEnabled(true);
+            } else {
+                pa.setPointSpriteEnabled(false);
+                pa.setAntiAliased(true);
+
+                // TODO: Disable texturing.  This is not exactly right if
+                // someone provided PointProperties for a non pointset
+                vfTexture = null;
+            }
+
+            oglImplNode.setPointAttributes(pa);
+        }
+
+        createTextureTransform();
+        createTextureUnits();
+
+        materialChanged = false;
+        fillPropsChanged = false;
+        linePropsChanged = false;
+        pointPropsChanged = false;
+        textureUnitsChanged = false;
+        textureTransformChanged = false;
+        textureChanged = false;
+        threadedUnitChanged = false;
+    }
+
+    @Override
+    public synchronized void notifyExternProtoLoaded(int index, VRMLNodeType node)
+            throws InvalidFieldValueException {
+
+        if (inSetup) {
+            return;
+        }
+
+        super.notifyExternProtoLoaded(index, node);
+
+        OGLVRMLNode kid = (OGLVRMLNode) node;
+
+        switch (index) {
+            case FIELD_MATERIAL:
+                if (oglImplNode.isLive()) {
+                    materialChanged = true;
+                    stateManager.addEndOfThisFrameListener(this);
+                } else {
+                    Material mat = (Material) kid.getSceneGraphObject();
+                    oglImplNode.setMaterial(mat);
+                }
+                break;
+
+            case FIELD_TEXTURE:
+                createTextureUnits();
+                break;
+
+            case FIELD_TEXTURE_TRANSFORM:
+                createTextureTransform();
+                break;
+
+            case FIELD_LINE_PROPERTIES:
+                if (oglImplNode.isLive()) {
+                    linePropsChanged = true;
+                    stateManager.addEndOfThisFrameListener(this);
+                } else {
+                    LineAttributes la = (LineAttributes) kid.getSceneGraphObject();
+                    oglImplNode.setLineAttributes(la);
+                }
+                break;
+            case FIELD_POINT_PROPERTIES:
+                if (oglImplNode.isLive()) {
+                    linePropsChanged = true;
+                    stateManager.addEndOfThisFrameListener(this);
+                } else {
+                    PointAttributes pa = (PointAttributes) kid.getSceneGraphObject();
+                    oglImplNode.setPointAttributes(pa);
+                }
+                break;
+
+            case FIELD_FILL_PROPERTIES:
+                if (oglImplNode.isLive()) {
+                    fillPropsChanged = true;
+                    stateManager.addEndOfThisFrameListener(this);
+                } else {
+                //                    PolygonAttributes pa =
+                    //                        (PolygonAttributes)kid.getSceneGraphObject();
+                    //                    oglImplNode.setPolygonAttributes(pa);
+                }
+                break;
+        }
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by NodeUpdateListener
+    //----------------------------------------------------------
+
+    /**
+     * Notification that its safe to update the node now with any operations
+     * that could potentially effect the node's bounds.
+     *
+     * @param src The node or Node Component that is to be updated.
+     */
+    @Override
+    public void updateNodeBoundsChanges(Object src) {
+    }
+
+    /**
+     * Notification that its safe to update the node now with any operations
+     * that only change the node's properties, but do not change the bounds.
+     *
+     * @param src The node or Node Component that is to be updated.
+     */
+    @Override
+    public void updateNodeDataChanges(Object src) {
+        if (src == oglImplNode) {
+            if (materialChanged) {
+                materialChanged = false;
+
+                OGLMaterialNodeType node = (OGLMaterialNodeType) vfMaterial;
+                Material mat = (node == null) ? null : node.getMaterial();
+                oglImplNode.setMaterial(mat);
+            }
+
+            if (textureChanged) {
+                textureChanged = false;
+
+                // TODO: Can we optimize this?
+                createTextureUnits();
+            }
+
+            if (textureTransformChanged) {
+                textureTransformChanged = false;
+
+                // TODO: Can we optimize this?
+                createTextureTransform();
+            }
+
+            if (textureUnitsChanged) {
+                textureUnitsChanged = false;
+                oglImplNode.setTextureUnits(texUnits, numStages);
+            }
+
+            if (linePropsChanged) {
+                linePropsChanged = false;
+
+                LineAttributes la = null;
+
+                if (vfLineProperties != null) {
+                    OGLVRMLNode o_n = (OGLVRMLNode) vfLineProperties;
+                    la = (LineAttributes) o_n.getSceneGraphObject();
+                }
+
+                oglImplNode.setLineAttributes(la);
+            }
+
+            if (pointPropsChanged) {
+                pointPropsChanged = false;
+
+                PointAttributes pa = null;
+
+                if (vfPointProperties != null) {
+                    OGLVRMLNode o_n = (OGLVRMLNode) vfPointProperties;
+                    pa = (PointAttributes) o_n.getSceneGraphObject();
+                }
+
+                oglImplNode.setPointAttributes(pa);
+            }
+
+            if (fillPropsChanged) {
+                fillPropsChanged = false;
+
+                if (!savedSolidState || !savedCCWState) {
+                    oglImplNode.setPolygonAttributes(implPA);
+                } else {
+                    oglImplNode.setPolygonAttributes(null);
+                }
+
+                /*
+                 PolygonAttributes pa = null;
+
+                 if(vfFillProperties != null) {
+                 OGLVRMLNode o_n = (OGLVRMLNode)vfFillProperties;
+                 pa = (PolygonAttributes)o_n.getSceneGraphObject();
+                 }
+
+                 oglImplNode.setPolygonAttributes(pa);
+                 */
+            }
+
+        } else if (src == implPA) {
+            if (savedSolidState) {
+                implPA.setCulledFace(PolygonAttributes.CULL_BACK);
+                implPA.setTwoSidedLighting(false);
+            } else {
+                implPA.setCulledFace(PolygonAttributes.CULL_NONE);
+                implPA.setTwoSidedLighting(true);
+            }
+
+            implPA.setCCW(savedCCWState);
+        } else if (src instanceof TextureUnit) {
+            // Check for textureUnit
+            for (int i = 0; i < numStages; i++) {
+                if (texUnits[i] == src) {
+                    if (stages[i].mode != TextureConstants.MODE_OFF) {
+                        texUnits[i].setTexture(texObjs[i]);
+                    } else {
+                        // rem: for the multi-texture mode OFF
+                        // null out the Texture in the TextureUnit
+                        texUnits[i].setTexture(null);
+                    }
+                    break;
+                }
+            }
+
+            // Remove the processed unit
+            texUnitsChanged.remove((SceneGraphObject) src);
+
+            TextureStage ts = changedTransforms.get((TextureUnit) src);
+
+            if (ts != null) {
+                TextureUnit tu = (TextureUnit) src;
+                tu.setTextureTransform((Matrix4f) ts.transform);
+                changedTransforms.remove(tu);
+            }
+
+            ts = changedTexCoordGeneration.get((TextureUnit) src);
+
+            if (ts != null) {
+                TextureUnit tu = (TextureUnit) src;
+                tu.setTexCoordGeneration((TexCoordGeneration) ts.texCoordGeneration);
+                changedTexCoordGeneration.remove(tu);
+            }
+        }
+    }
+
+    //----------------------------------------------------------
+    // Private methods
+    //----------------------------------------------------------
+
+    /**
+     * Internal convenient method to do common initialization.
+     */
+    private void init() {
+        lightingState = true;
+        localColor = false;
+        localColorAlpha = false;
+        savedSolidState = true;
+        savedCCWState = true;
+        lightingOverride = false;
+        queryPointSprites = false;
+
+        oglImplNode = new Appearance();
+
+        implPA = new PolygonAttributes();
+        texGenMap = new HashMap<>(2);
+
+        changedTransforms = new HashMap<>();
+        changedTexCoordGeneration = new HashMap<>();
+
+        if (!savedCCWState || !savedSolidState) {
+            oglImplNode.setPolygonAttributes(implPA);
+        }
+
+        if (useTextureCache) {
+            textureCache = TextureCache.getInstance();
+        }
+
+        numStages = 0;
+
+        texUnitsChanged = new ConcurrentLinkedQueue<>();
+    }
+
+    /**
+     * Create the render specific structures for this field.
+     */
+    private void createTextureUnits() {
+        // Find out how many stages to setup
+        numStages = 0;
+
+        if (vfTexture != null) {
+            switch (vfTexture.getTextureType()) {
+                case TextureConstants.TYPE_SINGLE_2D:
+                    numStages++;
+                    vrmlTexs = new VRMLTextureNodeType[numStages];
+                    modes = new int[numStages];
+                    sources = new int[numStages];
+                    functions = new int[numStages];
+                    vrmlTexs[numStages - 1] = vfTexture;
+
+                    modes[numStages - 1]
+                            = getMode(((VRMLTexture2DNodeType) vfTexture).getImage(),
+                                    true);
+
+                    if (modes[numStages - 1] == TextureConstants.MODE_REPLACE) {
+                        OGLMaterialNodeType node = (OGLMaterialNodeType) vfMaterial;
+                        Material mat = (node == null) ? null : node.getMaterial();
+
+                        if (mat != null && vfMaterial.getTransparency() == 0) {
+                            mat.setLightingEnabled(false);
+                            lightingOverride = true;
+                        } else {
+                            if (mat != null && lightingState) {
+                                mat.setLightingEnabled(true);
+                            }
+                            lightingOverride = false;
+                        }
+                    }
+                    // TODO: Fill in source and function
+                    break;
+
+                case TextureConstants.TYPE_MULTI:
+                    VRMLMultiTextureNodeType mtex
+                            = ((VRMLMultiTextureNodeType) vfTexture);
+
+                    numStages += mtex.getNumberTextures();
+
+                    vrmlTexs = new VRMLTextureNodeType[numStages];
+                    modes = new int[numStages];
+                    sources = new int[numStages];
+                    functions = new int[numStages];
+
+                    mtex.getTextures(0, vrmlTexs);
+                    mtex.getTextureParams(0, modes, functions, sources);
+                    break;
+
+                case TextureConstants.TYPE_SINGLE_3D:
+                    VRMLComposedTextureNodeType ctex
+                            = ((VRMLComposedTextureNodeType) vfTexture);
+
+                    vrmlTexs = new VRMLTextureNodeType[numStages
+                            + ctex.getNumberTextures()];
+                    numStages++;
+                    modes = new int[numStages];
+                    sources = new int[numStages];
+                    functions = new int[numStages];
+
+                    ctex.getTextures(0, vrmlTexs);
+                    modes[numStages - 1] = TextureConstants.MODE_REPLACE;
+                    break;
+
+                case TextureConstants.TYPE_PBUFFER:
+                    numStages++;
+                    vrmlTexs = new VRMLTextureNodeType[numStages];
+                    modes = new int[numStages];
+                    sources = new int[numStages];
+                    functions = new int[numStages];
+
+                    vrmlTexs[numStages - 1] = vfTexture;
+                    modes[numStages - 1] = TextureConstants.MODE_REPLACE;
+                    break;
+
+                case TextureConstants.TYPE_CUBIC_ENVIRONMAP:
+                    break;
+            }
+        }
+
+        texObjs = new Texture[numStages];
+        texUnits = new TextureUnit[numStages];
+        texAttrs = new TextureAttributes[numStages];
+
+        insureStageSize(numStages, true);
+
+        int currStage = 0;
+
+        // Setup the TextureStage variables
+        for (int i = currStage; i < numStages; i++) {
+            TextureStage tstage = stages[i];
+            TexCoordGeneration tcg = null;
+            boolean have_texture = false;
+
+            // Common variables
+            if (vfTextureProperties != null) {
+                // Only use 2D properties
+                VRMLTextureProperties2DNodeType tp
+                        = vfTextureProperties;
+
+                tstage.boundaryModeS = tp.getBoundaryModeS();
+                tstage.boundaryModeT = tp.getBoundaryModeT();
+                tstage.boundaryColor = new float[4];
+                tp.getBorderColor(tstage.boundaryColor);
+                tstage.minFilter = tp.getMinificationFilter();
+                tstage.magFilter = tp.getMagnificationFilter();
+            }
+
+            // Texture Type specific
+            int type = vrmlTexs[i].getTextureType();
+
+            switch (type) {
+                case TextureConstants.TYPE_MULTI:
+                    errorReporter.warningReport(NESTED_MULTITEXTURE_ERR, null);
+                    break;
+
+                case TextureConstants.TYPE_SINGLE_2D:
+                    type = vrmlTexs[i].getTextureType();
+
+                    if (tstage.images == null || tstage.images.length == 0) {
+                        NIOBufferImage img = ((VRMLTexture2DNodeType) vrmlTexs[i]).getImage();
+                        if (img != null) {
+                            tstage.images = processImage(0, img, null);
+                            setIgnoreDiffuse(img);
+                        }
+                    }
+
+                    tstage.mode = modes[i];
+                    if (vfTextureProperties == null) {
+                        VRMLTexture2DNodeType sn
+                                = (VRMLTexture2DNodeType) vrmlTexs[i];
+
+                        tstage.boundaryModeS = sn.getRepeatS()
+                                ? TextureConstants.BM_WRAP
+                                : DEFAULT_CLAMP_MODE;
+
+                        tstage.boundaryModeT = sn.getRepeatT()
+                                ? TextureConstants.BM_WRAP
+                                : DEFAULT_CLAMP_MODE;
+                    }
+
+                    String modeString
+                            = texGenMap.get(currStage);
+
+                    if (modeString != null) {
+                        Integer mode = texGenModeMap.get(modeString);
+
+                        if (mode != null) {
+                            tcg = new TexCoordGeneration();
+
+                            tcg.setParameter(TexCoordGeneration.TEXTURE_S,
+                                    TexCoordGeneration.MODE_GENERIC, mode,
+                                    null);
+                            tcg.setParameter(TexCoordGeneration.TEXTURE_T,
+                                    TexCoordGeneration.MODE_GENERIC, mode,
+                                    null);
+
+                            tstage.texCoordGeneration = tcg;
+                        } else {
+                            System.out.println("TexCoordGen mode not found: " + mode);
+                            tstage.texCoordGeneration = null;
+                        }
+                    }
+                    break;
+
+                case TextureConstants.TYPE_SINGLE_3D:
+
+                    tstage.mode = modes[i];
+                    // TODO: need to switch to 3D properties
+                    if (vfTextureProperties != null) {
+                        VRMLTextureProperties2DNodeType tp
+                                = vfTextureProperties;
+                        //tstage.boundaryModeR = tp.getBoundaryModeR();
+                    } else {
+                        VRMLTexture3DNodeType sn
+                                = (VRMLTexture3DNodeType) vfTexture;
+
+                        tstage.boundaryModeS = sn.getRepeatS()
+                                ? TextureConstants.BM_WRAP
+                                : DEFAULT_CLAMP_MODE;
+
+                        tstage.boundaryModeT = sn.getRepeatT()
+                                ? TextureConstants.BM_WRAP
+                                : DEFAULT_CLAMP_MODE;
+
+                        tstage.boundaryModeR = sn.getRepeatR()
+                                ? TextureConstants.BM_WRAP
+                                : DEFAULT_CLAMP_MODE;
+
+                        tstage.depth = sn.getDepth();
+                    }
+
+                    modeString = texGenMap.get(currStage);
+
+                    if (modeString != null) {
+                        Integer mode = texGenModeMap.get(modeString);
+
+                        if (mode != null) {
+                            tcg = new TexCoordGeneration();
+
+                            tcg.setParameter(TexCoordGeneration.TEXTURE_S,
+                                    TexCoordGeneration.MODE_GENERIC, mode,
+                                    null);
+                            tcg.setParameter(TexCoordGeneration.TEXTURE_T,
+                                    TexCoordGeneration.MODE_GENERIC, mode,
+                                    null);
+
+                            tcg.setParameter(TexCoordGeneration.TEXTURE_R,
+                                    TexCoordGeneration.MODE_GENERIC, mode,
+                                    null);
+
+                            tstage.texCoordGeneration = tcg;
+                        } else {
+                            System.out.println("TexCoordGen mode not found: " + mode);
+                            tstage.texCoordGeneration = null;
+                        }
+                    }
+                    break;
+
+                case TextureConstants.TYPE_PBUFFER:
+                    have_texture = true;
+                    OGLVRMLNode o_tex = (OGLVRMLNode) vfTexture;
+                    texObjs[i] = (Texture) o_tex.getSceneGraphObject();
+                    break;
+
+                case TextureConstants.TYPE_CUBIC_ENVIRONMAP:
+                    break;
+            }
+
+            if (!have_texture) {
+                texObjs[i] = createTexture(tstage, urls[i], type);
+                ((OGLTextureNodeType) vfTexture).setTexture(i, texObjs[i]);
+            }
+
+            texAttrs[i] = createTextureAttributes(i, tstage);
+            texUnits[i] = new TextureUnit(texObjs[i], texAttrs[i], tcg);
+
+            if (tstage.transform != null) {
+                texUnits[i].setTextureTransform((Matrix4f) tstage.transform);
+            }
+        }
+
+        //System.out.println("CTU: end: " + numStages);
+        oglImplNode.setTextureUnits(texUnits, numStages);
+    }
+
+    /**
+     * Create the render specific structures for this field.
+     */
+    private void createTextureTransform() {
+        if (vfTextureTransform != null) {
+            Matrix4f[] tt = ((OGLTextureCoordinateTransformNodeType) vfTextureTransform).getTransformMatrix();
+
+            int cnt = tt.length;
+
+            // Hold all texture transforms, but don't increase valid stages(numStages)
+            insureStageSize(cnt, false);
+
+            for (int i = 0; i < cnt; i++) {
+                stages[i].transform = tt[i];
+            }
+        }
+    }
+
+    /**
+     * Create the Texture object for this stage.
+     *
+     * @param tstage The stage representation for this texture
+     * @param url The url of the image, if there is one
+     * @param type The textureType (SINGLE, MULTI, 3D etc)
+     * @return A Texture object that corresponds to this stage
+     */
+    private Texture createTexture(TextureStage tstage, String url, int type) {
+        Texture ret_val = null;
+
+        // If we have no image in the first place, just return with nothing
+        // created.
+        boolean no_image_data = (tstage.images == null
+                || tstage.images.length < 1
+                || tstage.images[0] == null);
+
+        TextureComponent[] comps;
+        int len;
+        int texType;
+        int width;
+        int height;
+
+        // Setup texture stage variables
+        if (vfTextureProperties != null) {
+            VRMLTextureProperties2DNodeType tps
+                    = vfTextureProperties;
+
+            tstage.generateMipMaps = tps.getGenerateMipMaps();
+            tstage.boundaryModeS = tps.getBoundaryModeS();
+            tstage.boundaryModeT = tps.getBoundaryModeT();
+            tstage.minFilter = tps.getMinificationFilter();
+            tstage.magFilter = tps.getMagnificationFilter();
+            tstage.anisotropicMode = tps.getAnisotropicMode();
+            tstage.anisotropicDegree = tps.getAnisotropicDegree();
+        } else {
+            switch (type) {
+                case TextureConstants.TYPE_SINGLE_2D:
+                    VRMLTexture2DNodeType tex2d
+                            = (VRMLTexture2DNodeType) vrmlTexs[tstage.stageNumber];
+
+                    tstage.boundaryModeS = tex2d.getRepeatS()
+                            ? TextureConstants.BM_WRAP
+                            : DEFAULT_CLAMP_MODE;
+
+                    tstage.boundaryModeT = tex2d.getRepeatT()
+                            ? TextureConstants.BM_WRAP
+                            : DEFAULT_CLAMP_MODE;
+
+                    break;
+
+                case TextureConstants.TYPE_SINGLE_3D:
+                    VRMLTexture3DNodeType tex3d
+                            = (VRMLTexture3DNodeType) vrmlTexs[tstage.stageNumber];
+
+                    tstage.boundaryModeS = tex3d.getRepeatS()
+                            ? TextureConstants.BM_WRAP
+                            : DEFAULT_CLAMP_MODE;
+
+                    tstage.boundaryModeT = tex3d.getRepeatT()
+                            ? TextureConstants.BM_WRAP
+                            : DEFAULT_CLAMP_MODE;
+
+                    tstage.boundaryModeR = tex3d.getRepeatR()
+                            ? TextureConstants.BM_WRAP
+                            : DEFAULT_CLAMP_MODE;
+                    break;
+            }
+
+            if (anisotropicDegree > 1) {
+                tstage.anisotropicMode
+                        = TextureConstants.ANISOTROPIC_MODE_SINGLE;
+                tstage.anisotropicDegree = anisotropicDegree;
+            }
+        }
+
+        // Create the Texture object
+        try {
+            switch (type) {
+                case TextureConstants.TYPE_MULTI:
+                    break;
+
+                case TextureConstants.TYPE_SINGLE_2D:
+                    ret_val = new Texture2D();
+
+                    int val = OGLTextureConstConverter.convertAnisotropicMode(tstage.anisotropicMode);
+                    ret_val.setAnisotropicFilterMode(val);
+                    ret_val.setAnisotropicFilterDegree(tstage.anisotropicDegree);
+
+                    val = OGLTextureConstConverter.convertBoundary(tstage.boundaryModeS);
+                    ret_val.setBoundaryModeS(val);
+
+                    val = OGLTextureConstConverter.convertBoundary(tstage.boundaryModeT);
+                    ((Texture2D) ret_val).setBoundaryModeT(val);
+
+                    val = OGLTextureConstConverter.convertMinFilter(tstage.minFilter);
+                    ret_val.setMinFilter(val);
+
+                    val = OGLTextureConstConverter.convertMagFilter(tstage.magFilter);
+                    ret_val.setMagFilter(val);
+
+                    if (!no_image_data) {
+                        NIOBufferImage image = tstage.images[0];
+                        int format = getFormat(image);
+                        comps = new TextureComponent2D[1];
+
+                        comps[0] = new ByteBufferTextureComponent2D(
+                                format,
+                                image.getWidth(),
+                                image.getHeight(),
+                                image.getBuffer(null));
+                        texType = getTextureFormat(comps[0]);
+
+                        len = tstage.images.length;
+
+                        // Release reference to save memory
+                        for (int i = 0; i < len; i++) {
+                            tstage.images[i] = null;
+                        }
+
+                        tstage.images = null;
+
+                        // rem /////////////////////////////////////////////////
+                        // new image handling - just because mipmap generation
+                        // is enabled - does not mean we have mipmaps available.
+                        //if (tstage.generateMipMaps == false &&
+                        //  useMipMaps == false) {
+                        if (image.getLevels() == 1) {
+                            ////////////////////////////////////////////////////
+                            ret_val.setSources(Texture2D.MODE_BASE_LEVEL,
+                                    texType,
+                                    comps,
+                                    1);
+                        } else {
+                            ret_val.setSources(Texture2D.MODE_MIPMAP,
+                                    texType,
+                                    comps,
+                                    1);
+                        }
+
+                        comps[0].clearLocalData();
+                    }
+
+                    break;
+
+                case TextureConstants.TYPE_SINGLE_3D:
+                    ret_val = new Texture3D();
+
+                    //                val = convertAnisotropicMode(tstage.anisotropicMode);
+                    ret_val.setAnisotropicFilterMode(Texture.ANISOTROPIC_MODE_SINGLE);
+                    ret_val.setAnisotropicFilterDegree(tstage.anisotropicDegree);
+
+                    val = OGLTextureConstConverter.convertBoundary(tstage.boundaryModeS);
+                    ret_val.setBoundaryModeS(val);
+
+                    val = OGLTextureConstConverter.convertBoundary(tstage.boundaryModeT);
+                    ((Texture3D) ret_val).setBoundaryModeT(val);
+
+                    val = OGLTextureConstConverter.convertBoundary(tstage.boundaryModeR);
+                    ((Texture3D) ret_val).setBoundaryModeR(val);
+
+                    val = OGLTextureConstConverter.convertMinFilter(tstage.minFilter);
+                    ret_val.setMinFilter(val);
+
+                    val = OGLTextureConstConverter.convertMagFilter(tstage.magFilter);
+                    ret_val.setMagFilter(val);
+
+                    // Do a couple more checks on the texture object
+                    // and whether we should load the image information.
+                    // Not enough images in the array yet.
+                    if (tstage.images.length < tstage.depth) {
+                        no_image_data = true;
+                    }
+
+                    // Don't create a texture until we have all the images
+                    // specified.
+                    if (!no_image_data) {
+                        int format = getFormat(tstage.images[0]);
+                        for (int i = 0; i < tstage.depth; i++) {
+                            if (tstage.images[i] == null) {
+                                no_image_data = true;
+                            }
+
+                            if (getFormat(tstage.images[i]) != format) {
+                                no_image_data = true;
+                            }
+                        }
+                    }
+
+                    if (!no_image_data) {
+                        int format = getFormat(tstage.images[0]);
+                        width = tstage.images[0].getWidth();
+                        height = tstage.images[0].getHeight();
+
+                        TextureComponent3D[] comp_3
+                                = new TextureComponent3D[1];
+
+                        int num_img = tstage.images.length;
+                        ByteBuffer[] img_buffer = new ByteBuffer[num_img];
+                        for (int i = 0; i < num_img; i++) {
+                            img_buffer[i] = tstage.images[i].getBuffer();
+                        }
+                        comp_3[0] = new ByteBufferTextureComponent3D(
+                                width,
+                                height,
+                                format,
+                                img_buffer);
+
+                        texType = getTextureFormat(comp_3[0]);
+                        ret_val.setSources(Texture3D.MODE_BASE_LEVEL,
+                                texType,
+                                comp_3,
+                                1);
+
+                        tstage.images = null;
+                    }
+
+                    break;
+            }
+        } catch (InvalidWriteTimingException e) {
+            errorReporter.errorReport(TEXTURE_CREATE_FAIL_MSG + url, e);
+            return ret_val;
+        }
+
+        // rem //////////////////////////////////////////////////////////////////////
+        // the following is a legacy comment from the previous caching system.
+        // preserved as there will probably still be an issue with 3D textures
+        // using the new texture cache
+        //////////////////////////////////////////////////////////////////////////////
+        // TODO:
+        // There's an implementation issue here with 3D textures, particularly for
+        // textures that use multiple separate images. Only the last loaded image is
+        // actually cached. If the image is reloaded, then if one of the other URLs is
+        // the last to load, it will return null for the texture as it says it has the
+        // texture pre-loaded, but doesn't have it cached. This is.... unfortunate.
+        /*
+         if (useTextureCache && url != null) {
+         ((AVTextureCache)textureCache).registerTexture(ret_val, url);
+         }
+         */
+        //
+        //////////////////////////////////////////////////////////////////////////////
+        if (useTextureCache) {
+            ret_val = textureCache.register(url, ret_val);
+        }
+
+        return ret_val;
+    }
+
+    /**
+     * Create the textureAttributes for a texture stage.
+     */
+    private TextureAttributes createTextureAttributes(int stage,
+            TextureStage tstage) {
+
+        TextureAttributes ret_val = new TextureAttributes();
+
+        // this MUST stay here, before the vfPointProperties check !
+        setTextureMode(stage, tstage, ret_val);
+
+        if (pointSpritesSupported && vfPointProperties != null) {
+            ret_val.setPointSpriteCoordEnabled(true);
+            ret_val.setTextureMode(TextureAttributes.MODE_COMBINE);
+            ret_val.setCombineMode(true, TextureAttributes.COMBINE_MODULATE);
+
+            switch (vfPointProperties.getColorMode()) {
+                case VRMLPointPropertiesNodeType.POINT_COLOR_MODE:
+                    // use point color only
+                    ret_val.setCombineSource(false, 0, TextureAttributes.SOURCE_BASE_COLOR);
+                    ret_val.setCombineMode(false, TextureAttributes.COMBINE_REPLACE);
+                    break;
+                case VRMLPointPropertiesNodeType.TEXTURE_AND_POINT_COLOR_MODE:
+                    // use both point color and texture color
+                    ret_val.setCombineMode(false, TextureAttributes.COMBINE_ADD);
+                    break;
+                default:
+                    ret_val.setCombineMode(false, TextureAttributes.COMBINE_REPLACE);
+                    break;
+            }
+        } else {
+            ret_val.setPointSpriteCoordEnabled(false);
+        }
+
+        /*
+         if (tstage.transform != null)
+         ret_val.setTextureTransform((Transform3D)tstage.transform);
+         */
+        return ret_val;
+    }
+
+    /**
+     * Set the texture mode based on stage information.
+     */
+    private void setTextureMode(int stage,
+            TextureStage tstage,
+            TextureAttributes atts) {
+
+        switch (tstage.mode) {
+            case TextureConstants.MODE_REPLACE:
+                atts.setTextureMode(TextureAttributes.MODE_REPLACE);
+                break;
+            case TextureConstants.MODE_MODULATE:
+                atts.setTextureMode(TextureAttributes.MODE_MODULATE);
+                break;
+            case TextureConstants.MODE_MODULATE_2X:
+                atts.setTextureMode(TextureAttributes.MODE_MODULATE);
+                atts.setCombineScale(false, 2);
+                break;
+            case TextureConstants.MODE_MODULATE_4X:
+                atts.setTextureMode(TextureAttributes.MODE_MODULATE);
+                atts.setCombineScale(false, 4);
+                break;
+            case TextureConstants.MODE_DOTPRODUCT3:
+                atts.setTextureMode(TextureAttributes.MODE_COMBINE);
+                atts.setCombineMode(false, TextureAttributes.COMBINE_DOT3_RGB);
+                atts.setCombineMode(true, TextureAttributes.COMBINE_REPLACE);
+                atts.setCombineSource(false, 0, TextureAttributes.SOURCE_CURRENT_TEXTURE);
+
+            //                atts.setBlendColor(0.5f, 0, 0, 1);
+                //                atts.setCombineSource(true, 0, TextureAttributes.SOURCE_CONSTANT_COLOR);
+                break;
+            case TextureConstants.MODE_ADD:
+                atts.setTextureMode(TextureAttributes.MODE_COMBINE);
+                atts.setCombineMode(false, TextureAttributes.COMBINE_ADD);
+                atts.setCombineMode(true, TextureAttributes.MODE_REPLACE);
+                break;
+            case TextureConstants.MODE_ADD_SIGNED:
+                atts.setTextureMode(TextureAttributes.MODE_COMBINE);
+                atts.setCombineMode(false, TextureAttributes.COMBINE_ADD_SIGNED);
+                break;
+            case TextureConstants.MODE_ADD_SIGNED_2X:
+                atts.setTextureMode(TextureAttributes.MODE_COMBINE);
+                atts.setCombineMode(false, TextureAttributes.COMBINE_ADD_SIGNED);
+                atts.setCombineScale(false, 2);
+                break;
+            case TextureConstants.MODE_SUBTRACT:
+                atts.setTextureMode(TextureAttributes.MODE_COMBINE);
+                atts.setCombineMode(false, TextureAttributes.COMBINE_SUBTRACT);
+                break;
+            case TextureConstants.MODE_OFF:
+                if (texUnits[stage] != null) {
+                    texUnits[stage].setTexture(null);
+                }
+                break;
+
+            default:
+                System.err.println("Unknown TextureConstants.Mode: " + tstage.mode);
+        }
+    }
+
+    /**
+     * From the image component format, generate the appropriate texture format.
+     *
+     * @param comp The image component to get the value from
+     * @return The appropriate corresponding texture format value
+     */
+    protected int getTextureFormat(TextureComponent comp) {
+
+        int ret_val = Texture.FORMAT_RGB;
+
+        switch (comp.getFormat(0)) {
+            case TextureComponent.FORMAT_SINGLE_COMPONENT:
+
+                // could also be alpha, but we'll punt for now. We really need
+                // the user to pass in this information. Need to think of a
+                // good way of doing this.
+                ret_val = Texture.FORMAT_LUMINANCE;
+                break;
+
+            case TextureComponent.FORMAT_INTENSITY_ALPHA:
+                ret_val = Texture.FORMAT_LUMINANCE_ALPHA;
+                break;
+
+            case TextureComponent.FORMAT_RGB:
+                ret_val = Texture.FORMAT_RGB;
+                break;
+
+            case TextureComponent.FORMAT_RGBA:
+                ret_val = Texture.FORMAT_RGBA;
+                break;
+        }
+
+        return ret_val;
+    }
+
+    /**
+     * From the image information, generate the appropriate TextureComponent
+     * type.
+     *
+     * @param image The image component to get the value from
+     * @return The appropriate corresponding texture format value
+     */
+    protected int getFormat(NIOBufferImage image) {
+
+        int format = 0;
+        NIOBufferImageType type = image.getType();
+
+        if (type == NIOBufferImageType.INTENSITY) {
+
+            format = TextureComponent.FORMAT_SINGLE_COMPONENT;
+
+        } else if (type == NIOBufferImageType.INTENSITY_ALPHA) {
+
+            format = TextureComponent.FORMAT_INTENSITY_ALPHA;
+
+        } else if (type == NIOBufferImageType.RGB) {
+
+            format = TextureComponent.FORMAT_RGB;
+
+        } else if (type == NIOBufferImageType.RGBA) {
+
+            format = TextureComponent.FORMAT_RGBA;
+
+        } else {
+
+            System.err.println("Unknown NIOBufferImageType: " + type.name);
+        }
+
+        return format;
+    }
+
+    /**
+     * Given the image format return the texturing mode to use. For the X3D
+     * lighting model, whether to use MODULATE or REPLACE.
+     *
+     * @param image The image component to get the value from
+     * @param configMaterial Should this affect the material
+     * @return the texturing mode to use
+     */
+    private int getMode(NIOBufferImage image, boolean configMaterial) {
+
+        int mode = TextureConstants.MODE_MODULATE;
+        if (configMaterial) {
+            setIgnoreDiffuse(image);
+        }
+        return mode;
+    }
+
+    /**
+     * Configure the ignoreDiffuse property of the material based on the image.
+     */
+    private void setIgnoreDiffuse(NIOBufferImage image) {
+
+        boolean ignoreDiffuse = true;
+        if (image != null) {
+
+            // TODO: Why would we care to ignore diffuse color if the single
+            // image texture is not gray scale?  Flipping the boolean doesn't 
+            // seem right. (TDN)
+//            ignoreDiffuse = !image.isGrayScale();
+            ignoreDiffuse = image.isGrayScale();
+        }
+
+        if (vfMaterial != null) {
+            vfMaterial.setIgnoreDiffuse(ignoreDiffuse);
+        }
+    }
+}
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLLineProperties.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLLineProperties.java
index da4434ffb6d646823549dd2012e288ed6bf354bd..7311dcb1325afa557fb15e49c286ca64c8361db6 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLLineProperties.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLLineProperties.java
@@ -25,6 +25,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * Aviatrix3D renderer implementation of an LineProperties node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.6 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLMaterial.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLMaterial.java
index a2f829a54375d1ef516ca951b2148e4ca8e2d75f..76301687d0285e0eb6c6cc154ee0fbb61f8a6830 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLMaterial.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLMaterial.java
@@ -27,7 +27,8 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLMaterialNodeType;
 
 /**
  * OpenGL implementation of a material node.
- * 
+ * <p>
+ *
  * @author Justin Couch
  * @version $Revision: 1.18 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLPointProperties.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLPointProperties.java
index b7259c45f56411004c49fe5c1a7fcfcad9eb3940..55b54946d413739781c412c6911c399b3163d95e 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLPointProperties.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLPointProperties.java
@@ -1,259 +1,260 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001-2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.renderer.ogl.nodes.shape;
-
-// External imports
-import org.j3d.aviatrix3d.PointAttributes;
-import org.j3d.aviatrix3d.NodeUpdateListener;
-import org.j3d.aviatrix3d.SceneGraphObject;
-
-// Local imports
-import org.web3d.vrml.lang.InvalidFieldValueException;
-import org.web3d.vrml.nodes.VRMLNodeType;
-import org.web3d.vrml.renderer.common.nodes.shape.BasePointProperties;
-import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
-
-
-/**
- * Aviatrix3D renderer implementation of an PointProperties node.
- *
- * @author Justin Couch
- * @version $Revision: 1.2 $
- */
-public class OGLPointProperties extends BasePointProperties
-    implements OGLVRMLNode, NodeUpdateListener {
-
-    /** Aviatrix3D point attribute handling */
-    private PointAttributes oglAttribs;
-
-
-    /** Default value of pointSize */
-    private float defPointSize;
-
-    /** Default value of minSize */
-    private float defMinPointSize;
-
-    /** Default value of maxSize */
-    private float defMaxPointSize;
-
-    /** Default values of attenuation */
-    private float[] defAttenuationFactors;
-
-    /** Default value of colorMode */
-    public int defColorMode;
-
-    /**
-     * Default constructor.
-     */
-    public OGLPointProperties() {
-        init();
-    }
-
-    /**
-     * Construct a new instance of this node based on the details from the
-     * given node. If the node is not a PointAttributes node, an exception will be
-     * thrown.
-     *
-     * @param node The node to copy
-     * @throws IllegalArgumentException The node is not a Group node
-     */
-    public OGLPointProperties(VRMLNodeType node) {
-        super(node);
-        init();
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by OGLVRMLNode
-    //----------------------------------------------------------
-
-    /**
-     * Get the OpenGL scene graph object representation of this node. Scripts
-     * always return null.
-     *
-     * @return null
-     */
-    @Override
-    public SceneGraphObject getSceneGraphObject() {
-        return oglAttribs;
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by VRMLNodeType
-    //----------------------------------------------------------
-
-    /**
-     * Notification that the construction phase of this node has finished.
-     * If the node would like to do any internal processing, such as setting
-     * up geometry, then go for it now.
-     */
-
-    @Override
-    public void setupFinished() {
-        if(!inSetup)
-            return;
-
-        super.setupFinished();
-
-        updateNodeDataChanges(oglAttribs);
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by NodeUpdateListener
-    //----------------------------------------------------------
-
-    /**
-     * Notification that its safe to update the node now with any operations
-     * that could potentially effect the node's bounds.
-     *
-     * @param src The node or Node Component that is to be updated.
-     */
-    @Override
-    public void updateNodeBoundsChanges(Object src) {
-    }
-
-    /**
-     * Notification that its safe to update the node now with any operations
-     * that only change the node's properties, but do not change the bounds.
-     *
-     * @param src The node or Node Component that is to be updated.
-     */
-    @Override
-    public void updateNodeDataChanges(Object src) {
-
-        if (vfPointsizeScaleFactor <= 0)
-            oglAttribs.setPointSize(1);
-        else
-            oglAttribs.setPointSize(vfPointsizeScaleFactor);
-
-        if (vfPointsizeMinValue >= 0)
-            oglAttribs.setMinPointSize(vfPointsizeMinValue);
-
-        if (vfPointsizeMaxValue >= 0)
-            oglAttribs.setMaxPointSize(vfPointsizeMaxValue);
-
-        oglAttribs.setAttenuationFactors(vfPointsizeAttenuation[0],
-                                         vfPointsizeAttenuation[1],
-                                         vfPointsizeAttenuation[2]);
-
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by BasePointProperties
-    //----------------------------------------------------------
-
-    /**
-     * Override the base setting to update the Java3D representation of
-     * the point style.
-     *
-     * @param value The scale value to check
-     * @throws InvalidFieldValueException One of the colour components are out
-     *     of range
-     */
-    @Override
-    protected void setPointSizeScale(float value)
-        throws InvalidFieldValueException {
-
-        super.setPointSizeScale(value);
-
-        if (inSetup)
-            return;
-
-        if (oglAttribs.isLive())
-            oglAttribs.dataChanged(this);
-        else
-            updateNodeDataChanges(oglAttribs);
-    }
-
-    @Override
-    protected void setPointSizeMin(float value)
-        throws InvalidFieldValueException {
-
-        super.setPointSizeMin(value);
-
-        if (inSetup)
-            return;
-
-        if (oglAttribs.isLive())
-            oglAttribs.dataChanged(this);
-        else
-            updateNodeDataChanges(oglAttribs);
-    }
-
-    @Override
-    protected void setPointSizeMax(float value)
-        throws InvalidFieldValueException {
-
-        super.setPointSizeMax(value);
-
-        if (inSetup)
-            return;
-
-        if (oglAttribs.isLive())
-            oglAttribs.dataChanged(this);
-        else
-            updateNodeDataChanges(oglAttribs);
-    }
-
-    @Override
-    protected void setPointSizeAttenuation(float[] factor)
-        throws InvalidFieldValueException {
-
-        super.setPointSizeAttenuation(factor);
-
-        if (inSetup)
-            return;
-
-        if (oglAttribs.isLive())
-            oglAttribs.dataChanged(this);
-        else
-            updateNodeDataChanges(oglAttribs);
-    }
-
-    @Override
-    public void setColorMode(String value)
-        throws InvalidFieldValueException {
-
-        super.setColorMode(value);
-
-        if (inSetup)
-            return;
-
-        if (oglAttribs.isLive())
-            oglAttribs.dataChanged(this);
-        else
-            updateNodeDataChanges(oglAttribs);
-    }
-
-    //----------------------------------------------------------
-    // Local methods
-    //----------------------------------------------------------
-
-    /**
-     * Common initialization routines for the OpenGL code.
-     */
-    private void init() {
-
-        oglAttribs = new PointAttributes();
-
-        // TODO: Should this be an x3d param?
-        oglAttribs.setAntiAliased(true);
-
-        // TODO: These fields are never used?
-        defPointSize = oglAttribs.getPointSize();
-        defMinPointSize = oglAttribs.getMinPointSize();
-        defMaxPointSize = oglAttribs.getMaxPointSize();
-        oglAttribs.getAttenuationFactors(defAttenuationFactors);
-        defColorMode = TEXTURE_COLOR_MODE;
-
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001-2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.renderer.ogl.nodes.shape;
+
+// External imports
+import org.j3d.aviatrix3d.PointAttributes;
+import org.j3d.aviatrix3d.NodeUpdateListener;
+import org.j3d.aviatrix3d.SceneGraphObject;
+
+// Local imports
+import org.web3d.vrml.lang.InvalidFieldValueException;
+import org.web3d.vrml.nodes.VRMLNodeType;
+import org.web3d.vrml.renderer.common.nodes.shape.BasePointProperties;
+import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
+
+
+/**
+ * Aviatrix3D renderer implementation of an PointProperties node.
+ * <p>
+ *
+ * @author Justin Couch
+ * @version $Revision: 1.2 $
+ */
+public class OGLPointProperties extends BasePointProperties
+    implements OGLVRMLNode, NodeUpdateListener {
+
+    /** Aviatrix3D point attribute handling */
+    private PointAttributes oglAttribs;
+
+
+    /** Default value of pointSize */
+    private float defPointSize;
+
+    /** Default value of minSize */
+    private float defMinPointSize;
+
+    /** Default value of maxSize */
+    private float defMaxPointSize;
+
+    /** Default values of attenuation */
+    private float[] defAttenuationFactors;
+
+    /** Default value of colorMode */
+    public int defColorMode;
+
+    /**
+     * Default constructor.
+     */
+    public OGLPointProperties() {
+        init();
+    }
+
+    /**
+     * Construct a new instance of this node based on the details from the
+     * given node. If the node is not a PointAttributes node, an exception will be
+     * thrown.
+     *
+     * @param node The node to copy
+     * @throws IllegalArgumentException The node is not a Group node
+     */
+    public OGLPointProperties(VRMLNodeType node) {
+        super(node);
+        init();
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by OGLVRMLNode
+    //----------------------------------------------------------
+
+    /**
+     * Get the OpenGL scene graph object representation of this node. Scripts
+     * always return null.
+     *
+     * @return null
+     */
+    @Override
+    public SceneGraphObject getSceneGraphObject() {
+        return oglAttribs;
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by VRMLNodeType
+    //----------------------------------------------------------
+
+    /**
+     * Notification that the construction phase of this node has finished.
+     * If the node would like to do any internal processing, such as setting
+     * up geometry, then go for it now.
+     */
+
+    @Override
+    public void setupFinished() {
+        if(!inSetup)
+            return;
+
+        super.setupFinished();
+
+        updateNodeDataChanges(oglAttribs);
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by NodeUpdateListener
+    //----------------------------------------------------------
+
+    /**
+     * Notification that its safe to update the node now with any operations
+     * that could potentially effect the node's bounds.
+     *
+     * @param src The node or Node Component that is to be updated.
+     */
+    @Override
+    public void updateNodeBoundsChanges(Object src) {
+    }
+
+    /**
+     * Notification that its safe to update the node now with any operations
+     * that only change the node's properties, but do not change the bounds.
+     *
+     * @param src The node or Node Component that is to be updated.
+     */
+    @Override
+    public void updateNodeDataChanges(Object src) {
+
+        if (vfPointsizeScaleFactor <= 0)
+            oglAttribs.setPointSize(1);
+        else
+            oglAttribs.setPointSize(vfPointsizeScaleFactor);
+
+        if (vfPointsizeMinValue >= 0)
+            oglAttribs.setMinPointSize(vfPointsizeMinValue);
+
+        if (vfPointsizeMaxValue >= 0)
+            oglAttribs.setMaxPointSize(vfPointsizeMaxValue);
+
+        oglAttribs.setAttenuationFactors(vfPointsizeAttenuation[0],
+                                         vfPointsizeAttenuation[1],
+                                         vfPointsizeAttenuation[2]);
+
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by BasePointProperties
+    //----------------------------------------------------------
+
+    /**
+     * Override the base setting to update the Java3D representation of
+     * the point style.
+     *
+     * @param value The scale value to check
+     * @throws InvalidFieldValueException One of the colour components are out
+     *     of range
+     */
+    @Override
+    protected void setPointSizeScale(float value)
+        throws InvalidFieldValueException {
+
+        super.setPointSizeScale(value);
+
+        if (inSetup)
+            return;
+
+        if (oglAttribs.isLive())
+            oglAttribs.dataChanged(this);
+        else
+            updateNodeDataChanges(oglAttribs);
+    }
+
+    @Override
+    protected void setPointSizeMin(float value)
+        throws InvalidFieldValueException {
+
+        super.setPointSizeMin(value);
+
+        if (inSetup)
+            return;
+
+        if (oglAttribs.isLive())
+            oglAttribs.dataChanged(this);
+        else
+            updateNodeDataChanges(oglAttribs);
+    }
+
+    @Override
+    protected void setPointSizeMax(float value)
+        throws InvalidFieldValueException {
+
+        super.setPointSizeMax(value);
+
+        if (inSetup)
+            return;
+
+        if (oglAttribs.isLive())
+            oglAttribs.dataChanged(this);
+        else
+            updateNodeDataChanges(oglAttribs);
+    }
+
+    @Override
+    protected void setPointSizeAttenuation(float[] factor)
+        throws InvalidFieldValueException {
+
+        super.setPointSizeAttenuation(factor);
+
+        if (inSetup)
+            return;
+
+        if (oglAttribs.isLive())
+            oglAttribs.dataChanged(this);
+        else
+            updateNodeDataChanges(oglAttribs);
+    }
+
+    @Override
+    public void setColorMode(String value)
+        throws InvalidFieldValueException {
+
+        super.setColorMode(value);
+
+        if (inSetup)
+            return;
+
+        if (oglAttribs.isLive())
+            oglAttribs.dataChanged(this);
+        else
+            updateNodeDataChanges(oglAttribs);
+    }
+
+    //----------------------------------------------------------
+    // Local methods
+    //----------------------------------------------------------
+
+    /**
+     * Common initialization routines for the OpenGL code.
+     */
+    private void init() {
+
+        oglAttribs = new PointAttributes();
+
+        // TODO: Should this be an x3d param?
+        oglAttribs.setAntiAliased(true);
+
+        // TODO: These fields are never used?
+        defPointSize = oglAttribs.getPointSize();
+        defMinPointSize = oglAttribs.getMinPointSize();
+        defMaxPointSize = oglAttribs.getMaxPointSize();
+        oglAttribs.getAttenuationFactors(defAttenuationFactors);
+        defColorMode = TEXTURE_COLOR_MODE;
+
+    }
+}
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLShape.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLShape.java
index cc1ffcaa5cf27865bd0cad4056b0277f640b3ded..0865efd7df1e1edc3f1dd2ba92d2713d61aaec4b 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLShape.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLShape.java
@@ -29,6 +29,7 @@ import org.web3d.vrml.renderer.common.nodes.shape.BaseShape;
 
 /**
  * OGL implementation of a shape node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.29 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLTwoSidedMaterial.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLTwoSidedMaterial.java
index 71942387fa44985f07691dd023d52bf6df236501..4814548a7fd284918b853af99b5c3fcd5de1e8d0 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLTwoSidedMaterial.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/shape/OGLTwoSidedMaterial.java
@@ -27,6 +27,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLMaterialNodeType;
 
 /**
  * OpenGL implementation of a material node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/sound/OGLAudioClip.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/sound/OGLAudioClip.java
index eef86ed95964514b2750974ebb97df468c0c6374..f082d389a88a2bb1dbbbb4a04e056f7660a17d34 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/sound/OGLAudioClip.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/sound/OGLAudioClip.java
@@ -31,6 +31,8 @@ import org.xj3d.io.StreamContentContainer;
 
 /**
  * AudioClip node implementation for OpenGL.
+ * <p>
+ *
  *
  * @author Alan Hudson
  * @version $Revision: 1.4 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/sound/OGLMidiSource.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/sound/OGLMidiSource.java
index 9897a80ac8a6c90dc3777c4caeec95e8687f79d9..130aec323be2431a6c9629f2d19f5dd04eee0f82 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/sound/OGLMidiSource.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/sound/OGLMidiSource.java
@@ -24,6 +24,7 @@ import org.j3d.aviatrix3d.SceneGraphObject;
 
 /**
  * OpenGL implementation of a Midi Source.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/sound/OGLSound.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/sound/OGLSound.java
index 232b51a8ab32777cfc7a60dcf42d219fa7c8422b..1def889d6dc88cd1ec1099731db2fecac9a701ab 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/sound/OGLSound.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/sound/OGLSound.java
@@ -24,6 +24,8 @@ import org.web3d.vrml.nodes.VRMLSingleExternalNodeType;
 
 /**
  * Sound node implementation.
+ * <p>
+ *
  *
  * @author Alan Hudson
  * @version $Revision: 1.4 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/text/OGLFontStyle.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/text/OGLFontStyle.java
index c0fae4327a8291c7106392162e94dc4713c3dec7..ae0be632291f64669d2eb3f1a0e8e1e507ab6965 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/text/OGLFontStyle.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/text/OGLFontStyle.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * OpenGL implementation of a FontStyle
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/text/OGLText.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/text/OGLText.java
index 89b31787066cc276f47a533dc574370a6b548877..216d55dcc4f1c2d1ff9d63381733eb0baa264822 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/text/OGLText.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/text/OGLText.java
@@ -33,6 +33,7 @@ import org.web3d.vrml.renderer.common.nodes.text.DefaultFontStyle;
 
 /**
  * NoRender implementation of a Text
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.8 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLComposedTexture3D.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLComposedTexture3D.java
index f2a544171f4e9be295b2f29c9ff093b2286d105b..8200c16e1af77cff2c80a349ed4c5436f399a341 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLComposedTexture3D.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLComposedTexture3D.java
@@ -26,6 +26,7 @@ import org.web3d.vrml.renderer.common.nodes.texture.BaseComposedTexture3D;
 
 /**
  * OpenGL implementation of a ComposedTexture3D node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLImageTexture.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLImageTexture.java
index e318fcf3b9fedeccf4cab0792189d892307ddc5b..a902a1badad99099fa420af62cb55da5c136e3ff 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLImageTexture.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLImageTexture.java
@@ -25,6 +25,7 @@ import org.web3d.vrml.renderer.common.nodes.texture.BaseImageTexture;
 
 /**
  * OGL implementation of a ImageTexture node.
+ * <p>
  *
  * @author Alan Hudson, Justin Couch
  * @version $Revision: 2.5 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLMultiTexture.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLMultiTexture.java
index c8d173d432e0cee97053a0b3cf9e0d0b96381f89..57d990e8ff9dc3751cbb577e4ee9e1a318a27b14 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLMultiTexture.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLMultiTexture.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLTextureNodeType;
 
 /**
  * OpenGL implementation of a MultiTexture node.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLMultiTextureCoordinate.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLMultiTextureCoordinate.java
index 4b2e10ecf462aa863ca421490e7de47ee9eaf8e8..7752376c0443e765359ce318d2b3afe920b8559e 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLMultiTextureCoordinate.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLMultiTextureCoordinate.java
@@ -23,6 +23,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * OpenGL implementation of a multi texture coordinate.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLMultiTextureTransform.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLMultiTextureTransform.java
index 2bceca9d78420c8098ee704235aad6432838de1e..37e3be9180d078967b45c0c5065cc80912cec64a 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLMultiTextureTransform.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLMultiTextureTransform.java
@@ -30,6 +30,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLTextureTransformListener;
 
 /**
  * Java3D implementation of a multi texture transform.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLRenderedTexture.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLRenderedTexture.java
index 88feb611b80ef18e4f109109b5fd35a85513f38d..e36353cc8e305bc954ba2d6c14b4f9fd86cb4817 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLRenderedTexture.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLRenderedTexture.java
@@ -32,7 +32,9 @@ import org.web3d.vrml.renderer.ogl.nodes.*;
 
 /**
  * RenderedTexture node implementation for OpenGL.
- * 
+ * <p>
+ *
+ *
  * @author Justin Couch
  * @version $Revision: 1.15 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLTextureCoordinate.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLTextureCoordinate.java
index 46e6b665da69b7cdd5a5c4b222970d27b1f4c988..3c357242eb09058c184fbe03a128b0150f0bbba7 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLTextureCoordinate.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLTextureCoordinate.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * OpenGL renderer implementation of a texture coordinate node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLTextureCoordinateGenerator.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLTextureCoordinateGenerator.java
index 5f6936fab2b3f4ebdf0e084096cee1935e3e6fb2..561f56cf727e499d1804a4be24a3cfe3fa6d0c81 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLTextureCoordinateGenerator.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLTextureCoordinateGenerator.java
@@ -21,7 +21,8 @@ import org.web3d.vrml.renderer.common.nodes.texture.BaseTextureCoordinateGenerat
 import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
- * OpenGL implementation of the TextureCoordinateGenerator.
+ * OpenGL implementation of the TextureCoordinateGenerator
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLTextureProperties.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLTextureProperties.java
index 1fe1b506596528f2b319a9b28c5fbe5a79da6a1e..47625f70342ec88b40b984920324a65a69fcf0d6 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLTextureProperties.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLTextureProperties.java
@@ -29,6 +29,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode;
 
 /**
  * OpenGL implementation of a texture properties.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLTextureTransform.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLTextureTransform.java
index b5180de5e0fd1a69829b3d5037f4310e969d76fa..b72d0e8670e8921f0cd3a40818d904ce579852b0 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLTextureTransform.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLTextureTransform.java
@@ -32,7 +32,8 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLTextureTransformListener;
 
 /**
  * OpenGL renderer implementation of a texture transform.
- * 
+ * <p>
+ *
  * @author Alan Hudson
  * @version $Revision: 1.9 $
  */
diff --git a/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLTextureTransform3D.java b/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLTextureTransform3D.java
index 62d27985ba07864ac76a8fef5e922282dbe7af46..8fcd11f7264ef0d299738c093d01319f0db9fdbf 100644
--- a/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLTextureTransform3D.java
+++ b/src/java/org/web3d/vrml/renderer/ogl/nodes/texture/OGLTextureTransform3D.java
@@ -32,6 +32,7 @@ import org.web3d.vrml.renderer.ogl.nodes.OGLTextureTransformListener;
 
 /**
  * Java3D implementation of a texture transform.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/sav/BinaryContentHandler.java b/src/java/org/web3d/vrml/sav/BinaryContentHandler.java
index afe3c10dc55de6043400fdf892b7494b237f200f..2cdb637f73c5a3b8f6052bef67c44948f7cb43e4 100644
--- a/src/java/org/web3d/vrml/sav/BinaryContentHandler.java
+++ b/src/java/org/web3d/vrml/sav/BinaryContentHandler.java
@@ -21,6 +21,7 @@ import org.web3d.vrml.lang.VRMLException;
 /**
  * Receiver of notifications from the VRML document about node declaration
  * information.  All field values are sent as binary bits.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/sav/ContentHandler.java b/src/java/org/web3d/vrml/sav/ContentHandler.java
index 9d86a2eb639919dd93ebaa67ec9b8f0075393a09..dd02db98890641941b228860eabce8f5806b3ba0 100644
--- a/src/java/org/web3d/vrml/sav/ContentHandler.java
+++ b/src/java/org/web3d/vrml/sav/ContentHandler.java
@@ -21,6 +21,7 @@ import org.web3d.vrml.lang.VRMLException;
 /**
  * Receiver of notifications from the VRML document about node declaration
  * information.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.14 $
diff --git a/src/java/org/web3d/vrml/sav/InputSource.java b/src/java/org/web3d/vrml/sav/InputSource.java
index fb6b0e749d8ea8ebe9010d000a4a293f0febb534..bb250f4bc934e68c52664c4976d100c4ae59be8b 100644
--- a/src/java/org/web3d/vrml/sav/InputSource.java
+++ b/src/java/org/web3d/vrml/sav/InputSource.java
@@ -13,20 +13,17 @@ package org.web3d.vrml.sav;
 
 // External imports
 import java.io.File;
-import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.io.IOException;
 import java.io.Reader;
 import java.io.UnsupportedEncodingException;
-
 import java.net.MalformedURLException;
-import java.net.URLDecoder;
-
 import java.security.AccessController;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
-
 import java.util.zip.GZIPInputStream;
+import java.net.URLDecoder;
 
 import org.ietf.uri.ResourceConnection;
 import org.ietf.uri.URIUtils;
@@ -43,7 +40,8 @@ import org.xj3d.io.ReportableReader;
 
 /**
  * Representation of an input stream of bytes to the reader.
- * 
+ * <p>
+ *
  * @author Justin Couch
  * @version $Revision: 1.19 $
  */
diff --git a/src/java/org/web3d/vrml/sav/RouteHandler.java b/src/java/org/web3d/vrml/sav/RouteHandler.java
index 16b2d98ac0609e916de4f263a390125095a69182..477616d4d4fa935093fe20688dbc6bfe249e5873 100644
--- a/src/java/org/web3d/vrml/sav/RouteHandler.java
+++ b/src/java/org/web3d/vrml/sav/RouteHandler.java
@@ -21,6 +21,7 @@ import org.web3d.vrml.lang.VRMLException;
 /**
  * Receiver of notifications from the VRML document about node declaration
  * information.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/sav/SAVException.java b/src/java/org/web3d/vrml/sav/SAVException.java
index 8e29b13bdaf44bb8e30c904002104ee48334f7b0..601bf2facf095095e7a93635b703272b90231d15 100644
--- a/src/java/org/web3d/vrml/sav/SAVException.java
+++ b/src/java/org/web3d/vrml/sav/SAVException.java
@@ -20,6 +20,7 @@ import org.web3d.vrml.lang.VRMLException;
 
 /**
  * Superclass of all exceptions used by the Simple API for VRML parsing.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/sav/SAVNotSupportedException.java b/src/java/org/web3d/vrml/sav/SAVNotSupportedException.java
index a375493a256be522a9297e01315eb7cd45aefd90..695a6fdb5a7aa190a7a4bdc52fd5a0b745255b90 100644
--- a/src/java/org/web3d/vrml/sav/SAVNotSupportedException.java
+++ b/src/java/org/web3d/vrml/sav/SAVNotSupportedException.java
@@ -21,6 +21,7 @@ package org.web3d.vrml.sav;
 /**
  * Exception indicating that a feature is not supported by the Simple API for
  * VRML.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/sav/ScriptHandler.java b/src/java/org/web3d/vrml/sav/ScriptHandler.java
index 1abfde5c609f87808bec21e713a6afc44a37fdde..bd89d4452e3ecb01a8d303768ab9726062d4ec51 100644
--- a/src/java/org/web3d/vrml/sav/ScriptHandler.java
+++ b/src/java/org/web3d/vrml/sav/ScriptHandler.java
@@ -21,6 +21,7 @@ import org.web3d.vrml.lang.VRMLException;
 /**
  * Receiver of notifications from the VRML document about script declaration
  * information.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.6 $
diff --git a/src/java/org/web3d/vrml/sav/StringContentHandler.java b/src/java/org/web3d/vrml/sav/StringContentHandler.java
index 46c305797191abbe40527f52760d768cb6acfa9b..8c25dca4804b18387b5c1de6168d13e7a8e6b603 100644
--- a/src/java/org/web3d/vrml/sav/StringContentHandler.java
+++ b/src/java/org/web3d/vrml/sav/StringContentHandler.java
@@ -21,6 +21,7 @@ import org.web3d.vrml.lang.VRMLException;
 /**
  * Receiver of notifications from the VRML document about node declaration
  * information.  All field values are sent as strings.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/scripting/ScriptWrapper.java b/src/java/org/web3d/vrml/scripting/ScriptWrapper.java
index b751a7374f6920fcc6592de5a0850b9309abb8f1..8328d630e01112f382ff20d2f8e1ef4bf35bf1c3 100644
--- a/src/java/org/web3d/vrml/scripting/ScriptWrapper.java
+++ b/src/java/org/web3d/vrml/scripting/ScriptWrapper.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.nodes.VRMLScriptNodeType;
 /**
  * A wrapper abstract interface used to convert between the Xj3D
  * implementation specific details and the spec requirements for a script.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/Global.java b/src/java/org/web3d/vrml/scripting/ecmascript/Global.java
index d643f13a4f45d36f9b8ebcc62aca208d0e5ce6fb..29379afc4f7b0c2f3b0d628b0dd142ee6fa5ba3f 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/Global.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/Global.java
@@ -1,101 +1,101 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.scripting.ecmascript;
-
-// Standard imports
-import org.mozilla.javascript.Context;
-import org.mozilla.javascript.Scriptable;
-import org.mozilla.javascript.ScriptableObject;
-import org.mozilla.javascript.Function;
-
-import org.j3d.util.DefaultErrorReporter;
-import org.j3d.util.ErrorReporter;
-
-// Application specific imports
-
-/**
- * The global object for ECMAScript.  Used to implement the print function.
- *
- * @author Alan Hudson
- */
-public class Global extends ScriptableObject {
-    /** Class that represents the external reporter */
-    private static ErrorReporter errorReporter;
-
-    /**
-     * Return name of this class, the global object.
-     *
-     * This method must be implemented in all concrete classes
-     * extending ScriptableObject.
-     *
-     * @return the name of this class
-     * @see org.mozilla.javascript.Scriptable#getClassName
-     */
-    @Override
-     public String getClassName() {
-         return "global";
-     }
-
-    /**
-     * Print the string values of its arguments.
-     *
-     * This method is defined as a JavaScript function.
-     * Note that its arguments are of the "varargs" form, which
-     * allows it to handle an arbitrary number of arguments
-     * supplied to the JavaScript function.
-     *
-     * @param cx
-     * @param thisObj
-     * @param args
-     * @param funObj
-     */
-     public static void print(Context cx, Scriptable thisObj,
-                              Object[] args, Function funObj) {
-
-        if (errorReporter == null)
-            errorReporter = DefaultErrorReporter.getDefaultReporter();
-
-        StringBuilder sb = new StringBuilder();
-
-         for (int i=0; i < args.length; i++) {
-             if (i > 0)
-                 sb.append(" ");
-
-             // Convert the arbitrary JavaScript value into a string form.
-             String s = Context.toString(args[i]);
-
-             sb.append(s);
-         }
-
-        if(errorReporter != null)
-            errorReporter.messageReport(sb.toString());
-        else
-            System.out.println(sb.toString());
-     }
-
-    /**
-     * Register an error reporter with the engine so that any errors generated
-     * by the script code can be reported in a nice, pretty fashion. Setting a
-     * value of null will clear the currently set reporter. If one is already
-     * set, the new value replaces the old.
-     *
-     * @param reporter The instance to use or null
-     */
-    public void setErrorReporter(ErrorReporter reporter) {
-        errorReporter = reporter;
-
-        // Reset the default only if we are not shutting down the system.
-        if(reporter == null)
-            errorReporter = DefaultErrorReporter.getDefaultReporter();
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.scripting.ecmascript;
+
+// Standard imports
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.ScriptableObject;
+import org.mozilla.javascript.Function;
+
+import org.j3d.util.DefaultErrorReporter;
+import org.j3d.util.ErrorReporter;
+
+// Application specific imports
+
+/**
+ * The global object for ECMAScript.  Used to implement the print function.
+ *
+ * @author Alan Hudson
+ */
+public class Global extends ScriptableObject {
+    /** Class that represents the external reporter */
+    private static ErrorReporter errorReporter;
+
+    /**
+     * Return name of this class, the global object.
+     *
+     * This method must be implemented in all concrete classes
+     * extending ScriptableObject.
+     *
+     * @return the name of this class
+     * @see org.mozilla.javascript.Scriptable#getClassName
+     */
+    @Override
+     public String getClassName() {
+         return "global";
+     }
+
+    /**
+     * Print the string values of its arguments.
+     *
+     * This method is defined as a JavaScript function.
+     * Note that its arguments are of the "varargs" form, which
+     * allows it to handle an arbitrary number of arguments
+     * supplied to the JavaScript function.
+     *
+     * @param cx
+     * @param thisObj
+     * @param args
+     * @param funObj
+     */
+     public static void print(Context cx, Scriptable thisObj,
+                              Object[] args, Function funObj) {
+
+        if (errorReporter == null)
+            errorReporter = DefaultErrorReporter.getDefaultReporter();
+
+        StringBuilder sb = new StringBuilder();
+
+         for (int i=0; i < args.length; i++) {
+             if (i > 0)
+                 sb.append(" ");
+
+             // Convert the arbitrary JavaScript value into a string form.
+             String s = Context.toString(args[i]);
+
+             sb.append(s);
+         }
+
+        if(errorReporter != null)
+            errorReporter.messageReport(sb.toString());
+        else
+            System.out.println(sb.toString());
+     }
+
+    /**
+     * Register an error reporter with the engine so that any errors generated
+     * by the script code can be reported in a nice, pretty fashion. Setting a
+     * value of null will clear the currently set reporter. If one is already
+     * set, the new value replaces the old.
+     *
+     * @param reporter The instance to use or null
+     */
+    public void setErrorReporter(ErrorReporter reporter) {
+        errorReporter = reporter;
+
+        // Reset the default only if we are not shutting down the system.
+        if(reporter == null)
+            errorReporter = DefaultErrorReporter.getDefaultReporter();
+    }
+}
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/ReportAdapter.java b/src/java/org/web3d/vrml/scripting/ecmascript/ReportAdapter.java
index c5d28ac5380a7874711f7942ce5bc110d911f5b5..9a743863487992a6c4770ad6be519ade7a508fb3 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/ReportAdapter.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/ReportAdapter.java
@@ -1,189 +1,189 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.scripting.ecmascript;
-
-// Standard imports
-import org.mozilla.javascript.EvaluatorException;
-
-// Application specific imports
-import org.j3d.util.ErrorReporter;
-
-/**
- * An adapter between the Rhino reporting system and the system reporting
- * mechanisms provided by this codebase.
- * <p>
- *
- * If no system reporter is registered, the adapter will write the message
- * to <code>System.out</code>. Currently the messages are giving line numbers
- * according to the script they came from. It would be a nice thing to have
- * this generate line numbers according to the source VRML file so that it
- * makes locating the script error much easier for the end user.
- *
- * @author Justin Couch
- * @version $Revision: 1.3 $
- */
-class ReportAdapter implements org.mozilla.javascript.ErrorReporter {
-
-    /** Who we munge the messages for and pass details on to */
-    private ErrorReporter upstreamReporter;
-
-    /**
-     * Empty, default constructor.
-     */
-    ReportAdapter() {
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by the Rhino ErrorReporter interface
-    //----------------------------------------------------------
-
-    /**
-     * Report a warning.
-     *
-     * @param message a String describing the warning
-     * @param sourceName a String describing the JavaScript source
-     *     where the warning occurred; typically a filename or URL
-     * @param line the line number associated with the warning
-     * @param lineSource the text of the line (may be null)
-     * @param lineOffset the offset into lineSource where problem was detected
-     */
-    @Override
-    public void warning(String message,
-                        String sourceName,
-                        int line,
-                        String lineSource,
-                        int lineOffset) {
-        String msg =
-            formatMessage(message, sourceName, line, lineSource, lineOffset);
-
-        if(upstreamReporter != null)
-            upstreamReporter.warningReport(msg, null);
-        else
-            System.out.println("ECMA.Warning: " + msg);
-    }
-
-    /**
-     * Report an error. If execution has not yet begun, the JavaScript
-     * engine is free to find additional errors rather than terminating
-     * the translation. It will not execute a script that had errors, however.
-     *
-     * @param message a String describing the error
-     * @param sourceName a String describing the JavaScript source
-     *     where the error occurred; typically a filename or URL
-     * @param line the line number associated with the error
-     * @param lineSource the text of the line (may be null)
-     * @param lineOffset the offset into lineSource where problem was detected
-     */
-    @Override
-    public void error(String message,
-                      String sourceName,
-                      int line,
-                      String lineSource,
-                      int lineOffset) {
-        String msg =
-            formatMessage(message, sourceName, line, lineSource, lineOffset);
-
-        if(upstreamReporter != null)
-            upstreamReporter.errorReport(msg, null);
-        else
-            System.out.println("ECMA.Error: " + msg);
-    }
-
-    /**
-     * Creates an EvaluatorException that may be thrown.
-     * runtimeErrors, unlike errors, will always terminate the
-     * current script.
-     *
-     * @param message a String describing the error
-     * @param sourceName a String describing the JavaScript source
-     *     where the error occurred; typically a filename or URL
-     * @param line the line number associated with the error
-     * @param lineSource the text of the line (may be null)
-     * @param lineOffset the offset into lineSource where problem was detected
-     * @return an EvaluatorException that will be thrown.
-     */
-    @Override
-    public EvaluatorException runtimeError(String message,
-                                           String sourceName,
-                                           int line,
-                                           String lineSource,
-                                           int lineOffset) {
-        String msg =
-            formatMessage(message, sourceName, line, lineSource, lineOffset);
-
-        if(upstreamReporter != null)
-            upstreamReporter.errorReport(msg, null);
-        else
-            System.out.println("ECMA.RuntimeError: " + msg);
-
-        return new EvaluatorException(msg);
-    }
-
-    //----------------------------------------------------------
-    // Local methods
-    //----------------------------------------------------------
-
-    /**
-     * Set the system reporter used to pass messages to.
-     *
-     * @param rep The new reporter to use
-     */
-    void setReporter(ErrorReporter rep) {
-        upstreamReporter = rep;
-    }
-
-    /**
-     * Get the current system reporter
-     *
-     * @return The reporter in use
-     */
-    ErrorReporter getErrorReporter() {
-        return upstreamReporter;
-    }
-
-    /**
-     * Convenience method to format the message into a string.
-     *
-     * @param message a String describing the error
-     * @param sourceName a String describing the JavaScript source
-     *     where the error occurred; typically a filename or URL
-     * @param line the line number associated with the error
-     * @param lineSource the text of the line (may be null)
-     * @param lineOffset the offset into lineSource where problem was detected
-     * @return The formatted message string.
-     */
-    private String formatMessage(String message,
-                                 String sourceName,
-                                 int line,
-                                 String lineSource,
-                                 int lineOffset) {
-        StringBuilder buf = new StringBuilder();
-        buf.append("ECMAScript evaluation error on line ");
-        buf.append(line);
-        buf.append(" column ");
-        buf.append(lineOffset);
-
-        if(lineSource != null) {
-            buf.append("\n\"");
-            buf.append(lineSource);
-            buf.append('\"');
-        }
-
-        buf.append("\n");
-        buf.append(message);
-        buf.append("\nThe script came from: ");
-        buf.append(sourceName);
-
-        return buf.toString();
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.scripting.ecmascript;
+
+// Standard imports
+import org.mozilla.javascript.EvaluatorException;
+
+// Application specific imports
+import org.j3d.util.ErrorReporter;
+
+/**
+ * An adapter between the Rhino reporting system and the system reporting
+ * mechanisms provided by this codebase.
+ * <p>
+ *
+ * If no system reporter is registered, the adapter will write the message
+ * to <code>System.out</code>. Currently the messages are giving line numbers
+ * according to the script they came from. It would be a nice thing to have
+ * this generate line numbers according to the source VRML file so that it
+ * makes locating the script error much easier for the end user.
+ *
+ * @author Justin Couch
+ * @version $Revision: 1.3 $
+ */
+class ReportAdapter implements org.mozilla.javascript.ErrorReporter {
+
+    /** Who we munge the messages for and pass details on to */
+    private ErrorReporter upstreamReporter;
+
+    /**
+     * Empty, default constructor.
+     */
+    ReportAdapter() {
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by the Rhino ErrorReporter interface
+    //----------------------------------------------------------
+
+    /**
+     * Report a warning.
+     *
+     * @param message a String describing the warning
+     * @param sourceName a String describing the JavaScript source
+     *     where the warning occurred; typically a filename or URL
+     * @param line the line number associated with the warning
+     * @param lineSource the text of the line (may be null)
+     * @param lineOffset the offset into lineSource where problem was detected
+     */
+    @Override
+    public void warning(String message,
+                        String sourceName,
+                        int line,
+                        String lineSource,
+                        int lineOffset) {
+        String msg =
+            formatMessage(message, sourceName, line, lineSource, lineOffset);
+
+        if(upstreamReporter != null)
+            upstreamReporter.warningReport(msg, null);
+        else
+            System.out.println("ECMA.Warning: " + msg);
+    }
+
+    /**
+     * Report an error. If execution has not yet begun, the JavaScript
+     * engine is free to find additional errors rather than terminating
+     * the translation. It will not execute a script that had errors, however.
+     *
+     * @param message a String describing the error
+     * @param sourceName a String describing the JavaScript source
+     *     where the error occurred; typically a filename or URL
+     * @param line the line number associated with the error
+     * @param lineSource the text of the line (may be null)
+     * @param lineOffset the offset into lineSource where problem was detected
+     */
+    @Override
+    public void error(String message,
+                      String sourceName,
+                      int line,
+                      String lineSource,
+                      int lineOffset) {
+        String msg =
+            formatMessage(message, sourceName, line, lineSource, lineOffset);
+
+        if(upstreamReporter != null)
+            upstreamReporter.errorReport(msg, null);
+        else
+            System.out.println("ECMA.Error: " + msg);
+    }
+
+    /**
+     * Creates an EvaluatorException that may be thrown.
+     * runtimeErrors, unlike errors, will always terminate the
+     * current script.
+     *
+     * @param message a String describing the error
+     * @param sourceName a String describing the JavaScript source
+     *     where the error occurred; typically a filename or URL
+     * @param line the line number associated with the error
+     * @param lineSource the text of the line (may be null)
+     * @param lineOffset the offset into lineSource where problem was detected
+     * @return an EvaluatorException that will be thrown.
+     */
+    @Override
+    public EvaluatorException runtimeError(String message,
+                                           String sourceName,
+                                           int line,
+                                           String lineSource,
+                                           int lineOffset) {
+        String msg =
+            formatMessage(message, sourceName, line, lineSource, lineOffset);
+
+        if(upstreamReporter != null)
+            upstreamReporter.errorReport(msg, null);
+        else
+            System.out.println("ECMA.RuntimeError: " + msg);
+
+        return new EvaluatorException(msg);
+    }
+
+    //----------------------------------------------------------
+    // Local methods
+    //----------------------------------------------------------
+
+    /**
+     * Set the system reporter used to pass messages to.
+     *
+     * @param rep The new reporter to use
+     */
+    void setReporter(ErrorReporter rep) {
+        upstreamReporter = rep;
+    }
+
+    /**
+     * Get the current system reporter
+     *
+     * @return The reporter in use
+     */
+    ErrorReporter getErrorReporter() {
+        return upstreamReporter;
+    }
+
+    /**
+     * Convenience method to format the message into a string.
+     *
+     * @param message a String describing the error
+     * @param sourceName a String describing the JavaScript source
+     *     where the error occurred; typically a filename or URL
+     * @param line the line number associated with the error
+     * @param lineSource the text of the line (may be null)
+     * @param lineOffset the offset into lineSource where problem was detected
+     * @return The formatted message string.
+     */
+    private String formatMessage(String message,
+                                 String sourceName,
+                                 int line,
+                                 String lineSource,
+                                 int lineOffset) {
+        StringBuilder buf = new StringBuilder();
+        buf.append("ECMAScript evaluation error on line ");
+        buf.append(line);
+        buf.append(" column ");
+        buf.append(lineOffset);
+
+        if(lineSource != null) {
+            buf.append("\n\"");
+            buf.append(lineSource);
+            buf.append('\"');
+        }
+
+        buf.append("\n");
+        buf.append(message);
+        buf.append("\nThe script came from: ");
+        buf.append(sourceName);
+
+        return buf.toString();
+    }
+}
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/FieldDefinitionArray.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/FieldDefinitionArray.java
index 90bfb1d7a03fe800109a494afd3be8b041f48e3a..354ee3133112ef8b20d51b3beb21e9d262c61f6c 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/FieldDefinitionArray.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/FieldDefinitionArray.java
@@ -20,6 +20,7 @@ import org.j3d.util.HashSet;
 
 /**
  * ProfileInfo miscellaneous object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFBool.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFBool.java
index d3e74d461dafba837079020532a9152110af5a27..cecb301c8c15582334b0d3031e746913428cd627 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFBool.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFBool.java
@@ -25,6 +25,7 @@ import org.j3d.util.HashSet;
 
 /**
  * MFBool field object wrapper.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFColor.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFColor.java
index 42543bd7a6b4a1c65733f02aaf84a02e8cda1f30..f2b42bc4dd4cab7448d8ea6e37576e74e6cde17a 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFColor.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFColor.java
@@ -24,6 +24,7 @@ import org.j3d.util.HashSet;
 
 /**
  * MFColor field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.13 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFColorRGBA.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFColorRGBA.java
index 669090ee163c0648da801c1c5b5f23b6ab4f757b..784ca6d0ae0ff03785a8aa420ac0315dca7bb716 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFColorRGBA.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFColorRGBA.java
@@ -24,6 +24,7 @@ import org.j3d.util.HashSet;
 
 /**
  * MFColor field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.7 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFDouble.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFDouble.java
index bbb9f13f17fae2738b88e6134b1bccf6982372a4..e5ffd411bdbd102732042a5b1f0c22d97bbc4d84 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFDouble.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFDouble.java
@@ -25,6 +25,7 @@ import org.j3d.util.HashSet;
 
 /**
  * MFDouble field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFFloat.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFFloat.java
index 972f1433b8801c14208c747e552b3f8389083a6f..eb165e9fc6cb4b756c389ccd3485af84671d833c 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFFloat.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFFloat.java
@@ -25,6 +25,7 @@ import org.j3d.util.HashSet;
 
 /**
  * MFFloat field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.13 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFImage.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFImage.java
index ef1f1dc54bfbfd63f777df27326262615bf85600..6d6fb78321bd2abf5b4752f73736daab87e062c0 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFImage.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFImage.java
@@ -24,6 +24,7 @@ import org.j3d.util.HashSet;
 
 /**
  * MFImage field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.7 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFInt32.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFInt32.java
index fffa89faf4cc8a3fc71ded59c035096c00fd2793..0df97800358160ca4c902433364f05c69ac4ccfe 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFInt32.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFInt32.java
@@ -25,6 +25,7 @@ import org.j3d.util.HashSet;
 
 /**
  * MFInt field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.14 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFNode.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFNode.java
index 893bfcf7aa41a2b0a98ec86415ae0c3e4385ddc8..c7498f3a0246cef1df5422c26f64900f008d8e4e 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFNode.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFNode.java
@@ -27,6 +27,7 @@ import org.web3d.vrml.nodes.VRMLNodeType;
 
 /**
  * MFNode field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.28 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFRotation.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFRotation.java
index 3b020d6aaa1b37317a6e2f00469f99e66bea240d..71ac39c5a2b291ff237cf50e0b73230ae5fd72a4 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFRotation.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFRotation.java
@@ -24,6 +24,7 @@ import org.j3d.util.HashSet;
 
 /**
  * MFRotation field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.15 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFString.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFString.java
index 17e6f454ddb8739def1c700d2b25415c4e3ea56a..ff73c289cc33b4558ecf12251293cc1b3e05c4a3 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFString.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFString.java
@@ -24,6 +24,7 @@ import org.j3d.util.HashSet;
 
 /**
  * MFString field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.20 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFTime.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFTime.java
index 550a2c4872778a04f6056f192e055944884f0536..be4586bc40271f778150af20d8efc8d149a5aaf7 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFTime.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFTime.java
@@ -24,6 +24,7 @@ import org.j3d.util.HashSet;
 
 /**
  * MFTime field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.13 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec2d.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec2d.java
index 7ef48f88ebd8f0a2ae95d602d04b08ad0da77d2c..25cf50ac90da6c4720ac81e88d98a6c93c49c076 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec2d.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec2d.java
@@ -24,6 +24,7 @@ import org.j3d.util.HashSet;
 
 /**
  * MFVec2d field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.7 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec2f.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec2f.java
index 4f46ea3d17693f225de8d7694a40ddc04970aaaa..1b393127cb1874dee79da0e37eeb534398f8a8d3 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec2f.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec2f.java
@@ -24,6 +24,7 @@ import org.j3d.util.HashSet;
 
 /**
  * MFVec2f field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.13 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec3d.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec3d.java
index 83c8ac9a6d68c1f0da92c6888cb5631f30b769b1..d4797deb0ea70111e76b88cbdf05731f7a9d12b0 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec3d.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec3d.java
@@ -24,6 +24,7 @@ import org.j3d.util.HashSet;
 
 /**
  * MFVec3d field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.7 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec3f.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec3f.java
index 7012730bbe72ff284a777e0859d18c9a6eb49b87..50a06fc20ed42614f54620bc5c7f0a03879c9234 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec3f.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec3f.java
@@ -24,6 +24,7 @@ import org.j3d.util.HashSet;
 
 /**
  * MFVec3f field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.14 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec4d.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec4d.java
index 7042db9edca1d0d47718fa4f16580bca789762d0..ddc0100a467ddea0ef0a1379134a616ddbe06700 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec4d.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec4d.java
@@ -24,6 +24,7 @@ import org.j3d.util.HashSet;
 
 /**
  * MFVec4d field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec4f.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec4f.java
index f16c2ff18140bcb2c34c55f9632c81d41cfba82d..c621e460c4c90c69211b34788faba2f401ca43bd 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec4f.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/MFVec4f.java
@@ -24,6 +24,7 @@ import org.j3d.util.HashSet;
 
 /**
  * MFVec4f field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/NodeFieldData.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/NodeFieldData.java
index 8330b8acc53476e77ae6e8a9d35dbae2a7d45fef..019d3bde20083a2779cb98f4de95cca3a04c7873 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/NodeFieldData.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/NodeFieldData.java
@@ -19,6 +19,7 @@ import org.web3d.vrml.nodes.VRMLNodeType;
 
 /**
  * Data holder class for describing a node, field and value that has changed.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFColor.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFColor.java
index 136816bb642e6e51add16160b0721359930c61b2..d1ce5426daa94238ed153d97a06f2cf0c0de48e5 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFColor.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFColor.java
@@ -23,6 +23,7 @@ import org.j3d.util.HashSet;
 
 /**
  * SFColor field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.15 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFColorRGBA.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFColorRGBA.java
index 74f2a81bfe005c05b51d1d0125a6d131f6414f87..88e869ca430068c076583e19dc2c0f06760c785e 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFColorRGBA.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFColorRGBA.java
@@ -23,6 +23,7 @@ import org.j3d.util.HashSet;
 
 /**
  * SFColor field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFImage.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFImage.java
index 906da26c04ef9d9e6bdecefbbdf251c393fd4ecf..5b3c5ddfaa95598cfecec17d038139410f46fb34 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFImage.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFImage.java
@@ -22,6 +22,7 @@ import org.j3d.util.HashSet;
 
 /**
  * MFInt field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.4 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFRotation.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFRotation.java
index 7f730f73bad9890adedc7cabe137fafb7107270b..37e6892714ea9a1d12c8e477ee2939315dff7183 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFRotation.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFRotation.java
@@ -26,6 +26,7 @@ import org.j3d.util.HashSet;
 
 /**
  * SFRotation field object.
+ *  <p>
  *
  * @author Justin Couch, Alan Hudson
  * @version $Revision: 1.22 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec2d.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec2d.java
index 3bd2aa4b3d9d65905e8b6bcc1fb6d4a17ee12c06..50f99c0d2278cafddaa1c59c45574a09e5914a20 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec2d.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec2d.java
@@ -22,6 +22,7 @@ import org.j3d.util.HashSet;
 
 /**
  * SFVec2d field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec2f.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec2f.java
index 6b4f3297a98e5bb0385a049cbededca7b0a85ced..ee4f6493a6bd2e35355edef947dfa6ab11672219 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec2f.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec2f.java
@@ -22,7 +22,8 @@ import org.j3d.util.HashSet;
 
 /**
  * SFVec2f field object.
- * 
+ *  <p>
+ *
  * @author Justin Couch
  * @version $Revision: 1.16 $
  */
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec3d.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec3d.java
index 05173520aaa3f38ef8988537eba717aacf779ddc..8b347d416bafc89ab8c9eb0ba14d326da174fc37 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec3d.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec3d.java
@@ -22,6 +22,7 @@ import org.j3d.util.HashSet;
 
 /**
  * SFVec3d field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec3f.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec3f.java
index 1a9ac7b63216958a07c3e1f28bd4ba488a4441ea..68011ebfca1abdc92cf5f72066af7d548d67b5b1 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec3f.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec3f.java
@@ -22,6 +22,7 @@ import org.j3d.util.HashSet;
 
 /**
  * SFVec3f field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.17 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec4d.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec4d.java
index 05e6f6f7b5d62221d123d9d8ad9a390a23bb69e0..28e74ca8d3887999691734083898a05673a31c59 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec4d.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec4d.java
@@ -22,6 +22,7 @@ import org.j3d.util.HashSet;
 
 /**
  * SFVec4d field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec4f.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec4f.java
index f5c307eab25dccc0ead29947c8a1d1d10b8e9222..78390a04fad056d2f3a650f02c3b409d6bcb2ce4 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec4f.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/SFVec4f.java
@@ -22,6 +22,7 @@ import org.j3d.util.HashSet;
 
 /**
  * SFVec4f field object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/X3DFieldDefinition.java b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/X3DFieldDefinition.java
index d7e992b6a21dd833e81d0d2eb789285821747de3..efa953287a5aa5ad33d7cbfe79d617ee205556d2 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/builtin/X3DFieldDefinition.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/builtin/X3DFieldDefinition.java
@@ -20,6 +20,7 @@ import org.j3d.util.HashSet;
 
 /**
  * ProfileInfo miscellaneous object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ComponentInfo.java b/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ComponentInfo.java
index aa6551192fe586613d10ea5758a2f718820f8f1d..5fe9b6098695ecd22bb8e252c620d2caa460fc8c 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ComponentInfo.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ComponentInfo.java
@@ -21,6 +21,7 @@ import org.web3d.vrml.scripting.ecmascript.builtin.AbstractScriptableObject;
 
 /**
  * ProfileInfo miscellaneous object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ComponentInfoArray.java b/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ComponentInfoArray.java
index 40bf4c3e0bf3965a4abc6fb8ea9f9dd81def3c91..69a306e29c6a287e06553172f6ec69d43838b4ad 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ComponentInfoArray.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ComponentInfoArray.java
@@ -21,6 +21,7 @@ import org.web3d.vrml.scripting.ecmascript.builtin.AbstractScriptableObject;
 
 /**
  * ProfileInfo miscellaneous object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ExternProtoDeclaration.java b/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ExternProtoDeclaration.java
index 15f2f325f4f779d0cec7756cc9c998c82bc1348a..17582527e4a8d2f64aa3c0aacf81478832d069b8 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ExternProtoDeclaration.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ExternProtoDeclaration.java
@@ -36,6 +36,7 @@ import org.web3d.vrml.scripting.ecmascript.builtin.*;
 
 /**
  * ExternProtoDeclaration prototype object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.4 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ExternProtoDeclarationArray.java b/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ExternProtoDeclarationArray.java
index 339d7065c22d57437411ad248f9625089bbb6025..462310d29fcae7b5000a4e7306464e901a0bf477 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ExternProtoDeclarationArray.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ExternProtoDeclarationArray.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.scripting.ecmascript.builtin.AbstractScriptableObject;
 
 /**
  * ExternProtoDeclaration miscellaneous object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ProfileInfo.java b/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ProfileInfo.java
index 5d90fd761161df5d86395a389d68549a9c2d142e..f9972522de961e942a22fe7d9d14009e076a5905 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ProfileInfo.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ProfileInfo.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.scripting.ecmascript.builtin.AbstractScriptableObject;
 
 /**
  * ProfileInfo miscellaneous object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ProfileInfoArray.java b/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ProfileInfoArray.java
index 9228be2a30e871d307aa4c1b7da2c9a33be937f6..81d5a8f9c7b2f567fe69627ae1280b0d61611ae2 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ProfileInfoArray.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ProfileInfoArray.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.scripting.ecmascript.builtin.AbstractScriptableObject;
 
 /**
  * ProfileInfo miscellaneous object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ProtoDeclaration.java b/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ProtoDeclaration.java
index d7e6c4b0504d16829d1de93eccf8243bc6302275..bde7be612b8e36f39205abf224356b850620aca1 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ProtoDeclaration.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ProtoDeclaration.java
@@ -35,7 +35,8 @@ import org.web3d.vrml.scripting.ecmascript.builtin.*;
 
 /**
  * ProtoDeclaration prototype object.
- * 
+ *  <p>
+ *
  * @author Justin Couch
  * @version $Revision: 1.5 $
  */
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ProtoDeclarationArray.java b/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ProtoDeclarationArray.java
index ad5336b9f5bd104e044175dd4da4da24d3ee7031..78d6babfd44b027d2c88001637e448a61c31da2d 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ProtoDeclarationArray.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/x3d/ProtoDeclarationArray.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.scripting.ecmascript.builtin.AbstractScriptableObject;
 
 /**
  * ProtoDeclaration miscellaneous object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/x3d/Route.java b/src/java/org/web3d/vrml/scripting/ecmascript/x3d/Route.java
index 285335533be32d199ad0f03c479c6d175c4751b0..05c25e2eb045802941783834cf4e679532ac4142 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/x3d/Route.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/x3d/Route.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.scripting.ecmascript.builtin.AbstractScriptableObject;
 
 /**
  * Route object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/vrml/scripting/ecmascript/x3d/RouteArray.java b/src/java/org/web3d/vrml/scripting/ecmascript/x3d/RouteArray.java
index e4f2828fce8286d47caf1e2cae7451973f7a4cc0..06825f61dfa5144782f5990dfd46508d7596655a 100644
--- a/src/java/org/web3d/vrml/scripting/ecmascript/x3d/RouteArray.java
+++ b/src/java/org/web3d/vrml/scripting/ecmascript/x3d/RouteArray.java
@@ -22,6 +22,7 @@ import org.web3d.vrml.scripting.ecmascript.builtin.AbstractScriptableObject;
 
 /**
  * Route miscellaneous object.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/vrml/scripting/external/eai/EAINode.java b/src/java/org/web3d/vrml/scripting/external/eai/EAINode.java
index d21d5f94029e49680653743f28615d0b898875bf..eb5edfba4ba8a83e3847d6eef1bfeadc7b34f0ee 100644
--- a/src/java/org/web3d/vrml/scripting/external/eai/EAINode.java
+++ b/src/java/org/web3d/vrml/scripting/external/eai/EAINode.java
@@ -24,7 +24,7 @@ import org.web3d.vrml.nodes.VRMLNodeType;
  * It serves simply as a wrapper around the VRMLNodeType implementation,
  * although that task does include producing wrappers around the various
  * EventIn and EventOut classes.
- * 
+ *  <p>
  * @author Brad Vender
  * @version 1.0
  */
diff --git a/src/java/org/web3d/vrml/scripting/external/neteai/NetEAINode.java b/src/java/org/web3d/vrml/scripting/external/neteai/NetEAINode.java
index 54067ae462193be95607fd1e13cda3d8b90355c4..8205485b1ee94958efb273079d937d7e81507a69 100644
--- a/src/java/org/web3d/vrml/scripting/external/neteai/NetEAINode.java
+++ b/src/java/org/web3d/vrml/scripting/external/neteai/NetEAINode.java
@@ -21,7 +21,6 @@ import vrml.eai.field.InvalidEventInException;
 import vrml.eai.field.InvalidEventOutException;
 
 /**
- * Networked EAI node
  * @author vender
  * NetEAINode is the node wrapper for the networked version of the EAI classes.
  */
diff --git a/src/java/org/web3d/vrml/scripting/external/sai/BrowserListenerMulticaster.java b/src/java/org/web3d/vrml/scripting/external/sai/BrowserListenerMulticaster.java
index 6e0f479feec37a025969ed1abd7e203a87c14feb..c124f73d627889b612bc9a6d34149703bcfe52f5 100644
--- a/src/java/org/web3d/vrml/scripting/external/sai/BrowserListenerMulticaster.java
+++ b/src/java/org/web3d/vrml/scripting/external/sai/BrowserListenerMulticaster.java
@@ -1,236 +1,236 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.scripting.external.sai;
-
-// External imports
-// none
-
-// Local imports
-import org.j3d.util.DefaultErrorReporter;
-import org.j3d.util.ErrorReporter;
-
-import org.web3d.x3d.sai.BrowserEvent;
-import org.web3d.x3d.sai.BrowserListener;
-
-/**
- * A class which implements efficient and thread-safe multi-cast event
- * dispatching for the events defined in this package.
- * <p>
- *
- * This class will manage an immutable structure consisting of a chain of
- * event listeners and will dispatch events to those listeners.  Because
- * the structure is immutable, it is safe to use this API to add/remove
- * listeners during the process of an event dispatch operation.
- * <p>
- *
- * An example of how this class could be used to implement a new
- * component which fires "action" events:
- *
- * <pre><code>
- * public myComponent extends Component {
- *   BrowserListener listener = null;
- *
- *   public void addNodeListener(BrowserListener l) {
- *     listener = BrowserListenerMulticaster.add(listener, l);
- *   }
- *
- *   public void removeNodeListener(BrowserListener l) {
- *     listener = BrowserListenerMulticaster.remove(listener, l);
- *   }
- *
- *   public void browerChanged(BrowserEvent evt) {
- *     if(listener != null) {
- *       listener.browserChanged(evt);
- *   }
- * }
- * </code></pre>
- *
- * @author  Justin Couch
- * @version $Revision: 1.1 $
- */
-class BrowserListenerMulticaster
-    implements BrowserListener {
-
-    /** Error message when the user code barfs */
-    private static final String CHANGE_ERROR_MSG =
-        "Error sending emissive changed notification to: ";
-
-    private static final String DEFAULT_ERR_MSG =
-        "Unknown error sending browser change event: ";
-
-    /** The node listeners in use by this class */
-    private final BrowserListener a;
-
-    /** The node listeners in use by this class */
-    private final BrowserListener b;
-
-    /** Reporter instance for handing out errors */
-    private static ErrorReporter errorReporter =
-        DefaultErrorReporter.getDefaultReporter();
-
-    /**
-     * Creates an event multicaster instance which chains listener-a
-     * with listener-b. Input parameters <code>a</code> and <code>b</code>
-     * should not be <code>null</code>, though implementations may vary in
-     * choosing whether or not to throw <code>NullPointerException</code>
-     * in that case.
-     * @param a listener-a
-     * @param b listener-b
-     */
-    BrowserListenerMulticaster(BrowserListener a, BrowserListener b) {
-        this.a = a;
-        this.b = b;
-    }
-
-    /**
-     * Removes a listener from this multicaster and returns the
-     * resulting multicast listener.
-     * @param oldl the listener to be removed
-     */
-    BrowserListener remove(BrowserListener oldl) {
-
-        if(oldl == a)
-            return b;
-
-        if(oldl == b)
-            return a;
-
-        BrowserListener a2 = removeInternal(a, oldl);
-        BrowserListener b2 = removeInternal(b, oldl);
-
-        if (a2 == a && b2 == b) {
-            return this;  // it's not here
-        }
-
-        return addInternal(a2, b2);
-    }
-
-    /**
-     * Register an error reporter with the engine so that any errors generated
-     * by the loading of script code can be reported in a nice, pretty fashion.
-     * Setting a value of null will clear the currently set reporter. If one
-     * is already set, the new value replaces the old.
-     *
-     * @param reporter The instance to use or null
-     */
-    static void setErrorReporter(ErrorReporter reporter) {
-        errorReporter = reporter;
-
-        // Reset the default only if we are not shutting down the system.
-        if(reporter == null)
-            errorReporter = DefaultErrorReporter.getDefaultReporter();
-    }
-
-    /**
-     * Adds input-method-listener-a with input-method-listener-b and
-     * returns the resulting multicast listener.
-     * @param a input-method-listener-a
-     * @param b input-method-listener-b
-     */
-    static BrowserListener add(BrowserListener a, BrowserListener b) {
-        return addInternal(a, b);
-    }
-
-    /**
-     * Removes the old component-listener from component-listener-l and
-     * returns the resulting multicast listener.
-     * @param l component-listener-l
-     * @param oldl the component-listener being removed
-     */
-    static BrowserListener remove(BrowserListener l, BrowserListener oldl) {
-        return removeInternal(l, oldl);
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by BrowserListener
-    //----------------------------------------------------------
-
-    /**
-     * Process an event that has occurred in the VRML browser.
-     *
-     * @param evt The event that caused this method to be called
-     */
-    @Override
-    public void browserChanged(BrowserEvent evt) {
-        try {
-            a.browserChanged(evt);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(CHANGE_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.browserChanged(evt);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(CHANGE_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-
-    //----------------------------------------------------------
-    // Local Methods
-    //----------------------------------------------------------
-
-    /**
-     * Returns the resulting multicast listener from adding listener-a
-     * and listener-b together.
-     * If listener-a is null, it returns listener-b;
-     * If listener-b is null, it returns listener-a
-     * If neither are null, then it creates and returns
-     *     a new BrowserMulticaster instance which chains a with b.
-     * @param a event listener-a
-     * @param b event listener-b
-     */
-    private static BrowserListener addInternal(BrowserListener a,
-                                                     BrowserListener b) {
-        if(a == null)
-            return b;
-
-        if(b == null)
-            return a;
-
-        return new BrowserListenerMulticaster(a, b);
-    }
-
-    /**
-     * Returns the resulting multicast listener after removing the
-     * old listener from listener-l.
-     * If listener-l equals the old listener OR listener-l is null,
-     * returns null.
-     * Else if listener-l is an instance of BrowserMulticaster,
-     * then it removes the old listener from it.
-     * Else, returns listener l.
-     * @param l the listener being removed from
-     * @param oldl the listener being removed
-     */
-    private static BrowserListener removeInternal(BrowserListener l,
-                                                        BrowserListener oldl) {
-        if (l == oldl || l == null) {
-            return null;
-        } else if (l instanceof BrowserListenerMulticaster) {
-            return ((BrowserListenerMulticaster)l).remove(oldl);
-        } else {
-            return l;   // it's not here
-        }
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.scripting.external.sai;
+
+// External imports
+// none
+
+// Local imports
+import org.j3d.util.DefaultErrorReporter;
+import org.j3d.util.ErrorReporter;
+
+import org.web3d.x3d.sai.BrowserEvent;
+import org.web3d.x3d.sai.BrowserListener;
+
+/**
+ * A class which implements efficient and thread-safe multi-cast event
+ * dispatching for the events defined in this package.
+ * <p>
+ *
+ * This class will manage an immutable structure consisting of a chain of
+ * event listeners and will dispatch events to those listeners.  Because
+ * the structure is immutable, it is safe to use this API to add/remove
+ * listeners during the process of an event dispatch operation.
+ * <p>
+ *
+ * An example of how this class could be used to implement a new
+ * component which fires "action" events:
+ *
+ * <pre><code>
+ * public myComponent extends Component {
+ *   BrowserListener listener = null;
+ *
+ *   public void addNodeListener(BrowserListener l) {
+ *     listener = BrowserListenerMulticaster.add(listener, l);
+ *   }
+ *
+ *   public void removeNodeListener(BrowserListener l) {
+ *     listener = BrowserListenerMulticaster.remove(listener, l);
+ *   }
+ *
+ *   public void browerChanged(BrowserEvent evt) {
+ *     if(listener != null) {
+ *       listener.browserChanged(evt);
+ *   }
+ * }
+ * </code></pre>
+ *
+ * @author  Justin Couch
+ * @version $Revision: 1.1 $
+ */
+class BrowserListenerMulticaster
+    implements BrowserListener {
+
+    /** Error message when the user code barfs */
+    private static final String CHANGE_ERROR_MSG =
+        "Error sending emissive changed notification to: ";
+
+    private static final String DEFAULT_ERR_MSG =
+        "Unknown error sending browser change event: ";
+
+    /** The node listeners in use by this class */
+    private final BrowserListener a;
+
+    /** The node listeners in use by this class */
+    private final BrowserListener b;
+
+    /** Reporter instance for handing out errors */
+    private static ErrorReporter errorReporter =
+        DefaultErrorReporter.getDefaultReporter();
+
+    /**
+     * Creates an event multicaster instance which chains listener-a
+     * with listener-b. Input parameters <code>a</code> and <code>b</code>
+     * should not be <code>null</code>, though implementations may vary in
+     * choosing whether or not to throw <code>NullPointerException</code>
+     * in that case.
+     * @param a listener-a
+     * @param b listener-b
+     */
+    BrowserListenerMulticaster(BrowserListener a, BrowserListener b) {
+        this.a = a;
+        this.b = b;
+    }
+
+    /**
+     * Removes a listener from this multicaster and returns the
+     * resulting multicast listener.
+     * @param oldl the listener to be removed
+     */
+    BrowserListener remove(BrowserListener oldl) {
+
+        if(oldl == a)
+            return b;
+
+        if(oldl == b)
+            return a;
+
+        BrowserListener a2 = removeInternal(a, oldl);
+        BrowserListener b2 = removeInternal(b, oldl);
+
+        if (a2 == a && b2 == b) {
+            return this;  // it's not here
+        }
+
+        return addInternal(a2, b2);
+    }
+
+    /**
+     * Register an error reporter with the engine so that any errors generated
+     * by the loading of script code can be reported in a nice, pretty fashion.
+     * Setting a value of null will clear the currently set reporter. If one
+     * is already set, the new value replaces the old.
+     *
+     * @param reporter The instance to use or null
+     */
+    static void setErrorReporter(ErrorReporter reporter) {
+        errorReporter = reporter;
+
+        // Reset the default only if we are not shutting down the system.
+        if(reporter == null)
+            errorReporter = DefaultErrorReporter.getDefaultReporter();
+    }
+
+    /**
+     * Adds input-method-listener-a with input-method-listener-b and
+     * returns the resulting multicast listener.
+     * @param a input-method-listener-a
+     * @param b input-method-listener-b
+     */
+    static BrowserListener add(BrowserListener a, BrowserListener b) {
+        return addInternal(a, b);
+    }
+
+    /**
+     * Removes the old component-listener from component-listener-l and
+     * returns the resulting multicast listener.
+     * @param l component-listener-l
+     * @param oldl the component-listener being removed
+     */
+    static BrowserListener remove(BrowserListener l, BrowserListener oldl) {
+        return removeInternal(l, oldl);
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by BrowserListener
+    //----------------------------------------------------------
+
+    /**
+     * Process an event that has occurred in the VRML browser.
+     *
+     * @param evt The event that caused this method to be called
+     */
+    @Override
+    public void browserChanged(BrowserEvent evt) {
+        try {
+            a.browserChanged(evt);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(CHANGE_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.browserChanged(evt);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(CHANGE_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+
+    //----------------------------------------------------------
+    // Local Methods
+    //----------------------------------------------------------
+
+    /**
+     * Returns the resulting multicast listener from adding listener-a
+     * and listener-b together.
+     * If listener-a is null, it returns listener-b;
+     * If listener-b is null, it returns listener-a
+     * If neither are null, then it creates and returns
+     *     a new BrowserMulticaster instance which chains a with b.
+     * @param a event listener-a
+     * @param b event listener-b
+     */
+    private static BrowserListener addInternal(BrowserListener a,
+                                                     BrowserListener b) {
+        if(a == null)
+            return b;
+
+        if(b == null)
+            return a;
+
+        return new BrowserListenerMulticaster(a, b);
+    }
+
+    /**
+     * Returns the resulting multicast listener after removing the
+     * old listener from listener-l.
+     * If listener-l equals the old listener OR listener-l is null,
+     * returns null.
+     * Else if listener-l is an instance of BrowserMulticaster,
+     * then it removes the old listener from it.
+     * Else, returns listener l.
+     * @param l the listener being removed from
+     * @param oldl the listener being removed
+     */
+    private static BrowserListener removeInternal(BrowserListener l,
+                                                        BrowserListener oldl) {
+        if (l == oldl || l == null) {
+            return null;
+        } else if (l instanceof BrowserListenerMulticaster) {
+            return ((BrowserListenerMulticaster)l).remove(oldl);
+        } else {
+            return l;   // it's not here
+        }
+    }
+}
diff --git a/src/java/org/web3d/vrml/scripting/external/sai/CADViewListenerMulticaster.java b/src/java/org/web3d/vrml/scripting/external/sai/CADViewListenerMulticaster.java
index 5445e090735c24d7d2b4af9e3aa610d5aeee5744..d36b078888301fe67d34008a6f45fc9790206f31 100644
--- a/src/java/org/web3d/vrml/scripting/external/sai/CADViewListenerMulticaster.java
+++ b/src/java/org/web3d/vrml/scripting/external/sai/CADViewListenerMulticaster.java
@@ -1,348 +1,348 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.scripting.external.sai;
-
-// External imports
-// none
-
-// Local imports
-import org.web3d.x3d.sai.X3DNode;
-
-import org.j3d.util.DefaultErrorReporter;
-import org.j3d.util.ErrorReporter;
-
-import org.xj3d.sai.Xj3DCADViewListener;
-
-/**
- * A class which implements efficient and thread-safe multi-cast event
- * dispatching for the events defined in this package.
- * <p>
- *
- * This class will manage an immutable structure consisting of a chain of
- * event listeners and will dispatch events to those listeners.  Because
- * the structure is immutable, it is safe to use this API to add/remove
- * listeners during the process of an event dispatch operation.
- * <p>
- *
- * An example of how this class could be used to implement a new
- * component which fires "action" events:
- *
- * <pre><code>
- * public myComponent extends Component {
- *   Xj3DCADViewListener listener = null;
- *
- *   public void addNodeListener(Xj3DCADViewListener l) {
- *     listener = CADViewListenerMulticaster.add(listener, l);
- *   }
- *
- *   public void removeNodeListener(Xj3DCADViewListener l) {
- *     listener = CADViewListenerMulticaster.remove(listener, l);
- *   }
- *
- *   public void browerChanged(Xj3DCADViewEvent evt) {
- *     if(listener != null) {
- *       listener.browserChanged(evt);
- *   }
- * }
- * </code></pre>
- *
- * @author  Justin Couch
- * @version $Revision: 1.1 $
- */
-class CADViewListenerMulticaster
-    implements Xj3DCADViewListener {
-
-    /** Error message when the user code barfs */
-    private static final String LAYER_ADD_ERROR_MSG =
-        "Error sending layer addtition update: ";
-
-    /** Error message when the user code barfs */
-    private static final String LAYER_REMOVE_ERROR_MSG =
-        "Error sending layer removal update: ";
-
-    /** Error message when the user code barfs */
-    private static final String ASS_ADD_ERROR_MSG =
-        "Error sending assembly addtition update: ";
-
-    /** Error message when the user code barfs */
-    private static final String ASS_REMOVE_ERROR_MSG =
-        "Error sending assembly removal update: ";
-
-    /** Default error message when sending the error messsage fails */
-    private static final String DEFAULT_ERR_MSG =
-        "Unknown error sending CAD View listener event: ";
-
-    /** The node listeners in use by this class */
-    private final Xj3DCADViewListener a;
-
-    /** The node listeners in use by this class */
-    private final Xj3DCADViewListener b;
-
-    /** Reporter instance for handing out errors */
-    private static ErrorReporter errorReporter =
-        DefaultErrorReporter.getDefaultReporter();
-
-    /**
-     * Creates an event multicaster instance which chains listener-a
-     * with listener-b. Input parameters <code>a</code> and <code>b</code>
-     * should not be <code>null</code>, though implementations may vary in
-     * choosing whether or not to throw <code>NullPointerException</code>
-     * in that case.
-     * @param a listener-a
-     * @param b listener-b
-     */
-    CADViewListenerMulticaster(Xj3DCADViewListener a, Xj3DCADViewListener b) {
-        this.a = a;
-        this.b = b;
-    }
-
-    /**
-     * Removes a listener from this multicaster and returns the
-     * resulting multicast listener.
-     * @param oldl the listener to be removed
-     */
-    Xj3DCADViewListener remove(Xj3DCADViewListener oldl) {
-
-        if(oldl == a)
-            return b;
-
-        if(oldl == b)
-            return a;
-
-        Xj3DCADViewListener a2 = removeInternal(a, oldl);
-        Xj3DCADViewListener b2 = removeInternal(b, oldl);
-
-        if (a2 == a && b2 == b) {
-            return this;  // it's not here
-        }
-
-        return addInternal(a2, b2);
-    }
-
-    /**
-     * Register an error reporter with the engine so that any errors generated
-     * by the loading of script code can be reported in a nice, pretty fashion.
-     * Setting a value of null will clear the currently set reporter. If one
-     * is already set, the new value replaces the old.
-     *
-     * @param reporter The instance to use or null
-     */
-    static void setErrorReporter(ErrorReporter reporter) {
-        errorReporter = reporter;
-
-        // Reset the default only if we are not shutting down the system.
-        if(reporter == null)
-            errorReporter = DefaultErrorReporter.getDefaultReporter();
-    }
-
-    /**
-     * Adds input-method-listener-a with input-method-listener-b and
-     * returns the resulting multicast listener.
-     * @param a input-method-listener-a
-     * @param b input-method-listener-b
-     */
-    static Xj3DCADViewListener add(Xj3DCADViewListener a,
-                                   Xj3DCADViewListener b) {
-        return addInternal(a, b);
-    }
-
-    /**
-     * Removes the old component-listener from component-listener-l and
-     * returns the resulting multicast listener.
-     * @param l component-listener-l
-     * @param oldl the component-listener being removed
-     */
-    static Xj3DCADViewListener remove(Xj3DCADViewListener l,
-                                      Xj3DCADViewListener oldl) {
-        return removeInternal(l, oldl);
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by Xj3DCADViewListener
-    //----------------------------------------------------------
-
-    /**
-     * Notification that an assembly was added to the root of the world.
-     *
-     * @param assembly The node instance that was added
-     */
-    @Override
-    public void assemblyAdded(X3DNode assembly) {
-        try {
-            a.assemblyAdded(assembly);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(ASS_ADD_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.assemblyAdded(assembly);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(ASS_ADD_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-
-    /**
-     * Notification that an assembly was removed from the root of the world.
-     *
-     * @param assembly The node instance that was removed
-     */
-    @Override
-    public void assemblyRemoved(X3DNode assembly) {
-        try {
-            a.assemblyRemoved(assembly);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(ASS_REMOVE_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.assemblyRemoved(assembly);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(ASS_REMOVE_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-
-    /**
-     * Notification that a CADLayer was added to the root of the world.
-     *
-     * @param assembly The node instance that was added
-     */
-    @Override
-    public void layerAdded(X3DNode layer) {
-        try {
-            a.layerAdded(layer);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(LAYER_ADD_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.layerAdded(layer);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(LAYER_ADD_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-
-    /**
-     * Notification that a CADLayer was added to the root of the world.
-     *
-     * @param assembly The node instance that was removed
-     */
-    @Override
-    public void layerRemoved(X3DNode layer) {
-        try {
-            a.layerRemoved(layer);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(LAYER_REMOVE_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.layerRemoved(layer);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(LAYER_REMOVE_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-
-    //----------------------------------------------------------
-    // Local Methods
-    //----------------------------------------------------------
-
-    /**
-     * Returns the resulting multicast listener from adding listener-a
-     * and listener-b together.
-     * If listener-a is null, it returns listener-b;
-     * If listener-b is null, it returns listener-a
-     * If neither are null, then it creates and returns
-     *     a new Xj3DCADViewMulticaster instance which chains a with b.
-     * @param a event listener-a
-     * @param b event listener-b
-     */
-    private static Xj3DCADViewListener addInternal(Xj3DCADViewListener a,
-                                                     Xj3DCADViewListener b) {
-        if(a == null)
-            return b;
-
-        if(b == null)
-            return a;
-
-        return new CADViewListenerMulticaster(a, b);
-    }
-
-    /**
-     * Returns the resulting multicast listener after removing the
-     * old listener from listener-l.
-     * If listener-l equals the old listener OR listener-l is null,
-     * returns null.
-     * Else if listener-l is an instance of Xj3DCADViewMulticaster,
-     * then it removes the old listener from it.
-     * Else, returns listener l.
-     * @param l the listener being removed from
-     * @param oldl the listener being removed
-     */
-    private static Xj3DCADViewListener removeInternal(Xj3DCADViewListener l,
-                                                        Xj3DCADViewListener oldl) {
-        if (l == oldl || l == null) {
-            return null;
-        } else if (l instanceof CADViewListenerMulticaster) {
-            return ((CADViewListenerMulticaster)l).remove(oldl);
-        } else {
-            return l;   // it's not here
-        }
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.scripting.external.sai;
+
+// External imports
+// none
+
+// Local imports
+import org.web3d.x3d.sai.X3DNode;
+
+import org.j3d.util.DefaultErrorReporter;
+import org.j3d.util.ErrorReporter;
+
+import org.xj3d.sai.Xj3DCADViewListener;
+
+/**
+ * A class which implements efficient and thread-safe multi-cast event
+ * dispatching for the events defined in this package.
+ * <p>
+ *
+ * This class will manage an immutable structure consisting of a chain of
+ * event listeners and will dispatch events to those listeners.  Because
+ * the structure is immutable, it is safe to use this API to add/remove
+ * listeners during the process of an event dispatch operation.
+ * <p>
+ *
+ * An example of how this class could be used to implement a new
+ * component which fires "action" events:
+ *
+ * <pre><code>
+ * public myComponent extends Component {
+ *   Xj3DCADViewListener listener = null;
+ *
+ *   public void addNodeListener(Xj3DCADViewListener l) {
+ *     listener = CADViewListenerMulticaster.add(listener, l);
+ *   }
+ *
+ *   public void removeNodeListener(Xj3DCADViewListener l) {
+ *     listener = CADViewListenerMulticaster.remove(listener, l);
+ *   }
+ *
+ *   public void browerChanged(Xj3DCADViewEvent evt) {
+ *     if(listener != null) {
+ *       listener.browserChanged(evt);
+ *   }
+ * }
+ * </code></pre>
+ *
+ * @author  Justin Couch
+ * @version $Revision: 1.1 $
+ */
+class CADViewListenerMulticaster
+    implements Xj3DCADViewListener {
+
+    /** Error message when the user code barfs */
+    private static final String LAYER_ADD_ERROR_MSG =
+        "Error sending layer addtition update: ";
+
+    /** Error message when the user code barfs */
+    private static final String LAYER_REMOVE_ERROR_MSG =
+        "Error sending layer removal update: ";
+
+    /** Error message when the user code barfs */
+    private static final String ASS_ADD_ERROR_MSG =
+        "Error sending assembly addtition update: ";
+
+    /** Error message when the user code barfs */
+    private static final String ASS_REMOVE_ERROR_MSG =
+        "Error sending assembly removal update: ";
+
+    /** Default error message when sending the error messsage fails */
+    private static final String DEFAULT_ERR_MSG =
+        "Unknown error sending CAD View listener event: ";
+
+    /** The node listeners in use by this class */
+    private final Xj3DCADViewListener a;
+
+    /** The node listeners in use by this class */
+    private final Xj3DCADViewListener b;
+
+    /** Reporter instance for handing out errors */
+    private static ErrorReporter errorReporter =
+        DefaultErrorReporter.getDefaultReporter();
+
+    /**
+     * Creates an event multicaster instance which chains listener-a
+     * with listener-b. Input parameters <code>a</code> and <code>b</code>
+     * should not be <code>null</code>, though implementations may vary in
+     * choosing whether or not to throw <code>NullPointerException</code>
+     * in that case.
+     * @param a listener-a
+     * @param b listener-b
+     */
+    CADViewListenerMulticaster(Xj3DCADViewListener a, Xj3DCADViewListener b) {
+        this.a = a;
+        this.b = b;
+    }
+
+    /**
+     * Removes a listener from this multicaster and returns the
+     * resulting multicast listener.
+     * @param oldl the listener to be removed
+     */
+    Xj3DCADViewListener remove(Xj3DCADViewListener oldl) {
+
+        if(oldl == a)
+            return b;
+
+        if(oldl == b)
+            return a;
+
+        Xj3DCADViewListener a2 = removeInternal(a, oldl);
+        Xj3DCADViewListener b2 = removeInternal(b, oldl);
+
+        if (a2 == a && b2 == b) {
+            return this;  // it's not here
+        }
+
+        return addInternal(a2, b2);
+    }
+
+    /**
+     * Register an error reporter with the engine so that any errors generated
+     * by the loading of script code can be reported in a nice, pretty fashion.
+     * Setting a value of null will clear the currently set reporter. If one
+     * is already set, the new value replaces the old.
+     *
+     * @param reporter The instance to use or null
+     */
+    static void setErrorReporter(ErrorReporter reporter) {
+        errorReporter = reporter;
+
+        // Reset the default only if we are not shutting down the system.
+        if(reporter == null)
+            errorReporter = DefaultErrorReporter.getDefaultReporter();
+    }
+
+    /**
+     * Adds input-method-listener-a with input-method-listener-b and
+     * returns the resulting multicast listener.
+     * @param a input-method-listener-a
+     * @param b input-method-listener-b
+     */
+    static Xj3DCADViewListener add(Xj3DCADViewListener a,
+                                   Xj3DCADViewListener b) {
+        return addInternal(a, b);
+    }
+
+    /**
+     * Removes the old component-listener from component-listener-l and
+     * returns the resulting multicast listener.
+     * @param l component-listener-l
+     * @param oldl the component-listener being removed
+     */
+    static Xj3DCADViewListener remove(Xj3DCADViewListener l,
+                                      Xj3DCADViewListener oldl) {
+        return removeInternal(l, oldl);
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by Xj3DCADViewListener
+    //----------------------------------------------------------
+
+    /**
+     * Notification that an assembly was added to the root of the world.
+     *
+     * @param assembly The node instance that was added
+     */
+    @Override
+    public void assemblyAdded(X3DNode assembly) {
+        try {
+            a.assemblyAdded(assembly);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(ASS_ADD_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.assemblyAdded(assembly);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(ASS_ADD_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+
+    /**
+     * Notification that an assembly was removed from the root of the world.
+     *
+     * @param assembly The node instance that was removed
+     */
+    @Override
+    public void assemblyRemoved(X3DNode assembly) {
+        try {
+            a.assemblyRemoved(assembly);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(ASS_REMOVE_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.assemblyRemoved(assembly);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(ASS_REMOVE_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+
+    /**
+     * Notification that a CADLayer was added to the root of the world.
+     *
+     * @param assembly The node instance that was added
+     */
+    @Override
+    public void layerAdded(X3DNode layer) {
+        try {
+            a.layerAdded(layer);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(LAYER_ADD_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.layerAdded(layer);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(LAYER_ADD_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+
+    /**
+     * Notification that a CADLayer was added to the root of the world.
+     *
+     * @param assembly The node instance that was removed
+     */
+    @Override
+    public void layerRemoved(X3DNode layer) {
+        try {
+            a.layerRemoved(layer);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(LAYER_REMOVE_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.layerRemoved(layer);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(LAYER_REMOVE_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+
+    //----------------------------------------------------------
+    // Local Methods
+    //----------------------------------------------------------
+
+    /**
+     * Returns the resulting multicast listener from adding listener-a
+     * and listener-b together.
+     * If listener-a is null, it returns listener-b;
+     * If listener-b is null, it returns listener-a
+     * If neither are null, then it creates and returns
+     *     a new Xj3DCADViewMulticaster instance which chains a with b.
+     * @param a event listener-a
+     * @param b event listener-b
+     */
+    private static Xj3DCADViewListener addInternal(Xj3DCADViewListener a,
+                                                     Xj3DCADViewListener b) {
+        if(a == null)
+            return b;
+
+        if(b == null)
+            return a;
+
+        return new CADViewListenerMulticaster(a, b);
+    }
+
+    /**
+     * Returns the resulting multicast listener after removing the
+     * old listener from listener-l.
+     * If listener-l equals the old listener OR listener-l is null,
+     * returns null.
+     * Else if listener-l is an instance of Xj3DCADViewMulticaster,
+     * then it removes the old listener from it.
+     * Else, returns listener l.
+     * @param l the listener being removed from
+     * @param oldl the listener being removed
+     */
+    private static Xj3DCADViewListener removeInternal(Xj3DCADViewListener l,
+                                                        Xj3DCADViewListener oldl) {
+        if (l == oldl || l == null) {
+            return null;
+        } else if (l instanceof CADViewListenerMulticaster) {
+            return ((CADViewListenerMulticaster)l).remove(oldl);
+        } else {
+            return l;   // it's not here
+        }
+    }
+}
diff --git a/src/java/org/web3d/vrml/scripting/external/sai/NavigationListenerMulticaster.java b/src/java/org/web3d/vrml/scripting/external/sai/NavigationListenerMulticaster.java
index 020b636be2ad6b7385a0363f50a55e99053651a4..fb96f3cab42200c9c271029969966b7308b06f25 100644
--- a/src/java/org/web3d/vrml/scripting/external/sai/NavigationListenerMulticaster.java
+++ b/src/java/org/web3d/vrml/scripting/external/sai/NavigationListenerMulticaster.java
@@ -1,445 +1,445 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.scripting.external.sai;
-
-// External imports
-// none
-
-// Local imports
-import org.j3d.util.DefaultErrorReporter;
-import org.j3d.util.ErrorReporter;
-
-import org.xj3d.sai.Xj3DNavigationUIListener;
-import org.xj3d.sai.Xj3DViewpoint;
-
-/**
- * A class which implements efficient and thread-safe multi-cast event
- * dispatching for the events defined in this package.
- * <p>
- *
- * This class will manage an immutable structure consisting of a chain of
- * event listeners and will dispatch events to those listeners.  Because
- * the structure is immutable, it is safe to use this API to add/remove
- * listeners during the process of an event dispatch operation.
- * <p>
- *
- * An example of how this class could be used to implement a new
- * component which fires "action" events:
- *
- * <pre><code>
- * public myComponent extends Component {
- *   Xj3DNavigationUIListener listener = null;
- *
- *   public void addNodeListener(Xj3DNavigationUIListener l) {
- *     listener = NavigationListenerMulticaster.add(listener, l);
- *   }
- *
- *   public void removeNodeListener(Xj3DNavigationUIListener l) {
- *     listener = NavigationListenerMulticaster.remove(listener, l);
- *   }
- *
- *   public void browerChanged(Xj3DNavigationUIEvent evt) {
- *     if(listener != null) {
- *       listener.browserChanged(evt);
- *   }
- * }
- * </code></pre>
- *
- * @author  Justin Couch
- * @version $Revision: 1.1 $
- */
-class NavigationListenerMulticaster
-    implements Xj3DNavigationUIListener {
-
-    /** Error message when the user code barfs */
-    private static final String STATUS_ERROR_MSG =
-        "Error sending status message change updates: ";
-
-    /** Error message when the user code barfs */
-    private static final String FPS_ERROR_MSG =
-        "Error sending framerate updates: ";
-
-    /** Error message when the user code barfs */
-    private static final String PROGRESS_ERROR_MSG =
-        "Error sending progress update message: ";
-
-    /** Default error message when sending the error messsage fails */
-    private static final String DEFAULT_ERR_MSG =
-        "Unknown error sending navigation state change event: ";
-
-    /** The node listeners in use by this class */
-    private final Xj3DNavigationUIListener a;
-
-    /** The node listeners in use by this class */
-    private final Xj3DNavigationUIListener b;
-
-    /** Reporter instance for handing out errors */
-    private static ErrorReporter errorReporter =
-        DefaultErrorReporter.getDefaultReporter();
-
-    /**
-     * Creates an event multicaster instance which chains listener-a
-     * with listener-b. Input parameters <code>a</code> and <code>b</code>
-     * should not be <code>null</code>, though implementations may vary in
-     * choosing whether or not to throw <code>NullPointerException</code>
-     * in that case.
-     * @param a listener-a
-     * @param b listener-b
-     */
-    NavigationListenerMulticaster(Xj3DNavigationUIListener a,
-                                  Xj3DNavigationUIListener b) {
-        this.a = a;
-        this.b = b;
-    }
-
-    /**
-     * Removes a listener from this multicaster and returns the
-     * resulting multicast listener.
-     * @param oldl the listener to be removed
-     */
-    Xj3DNavigationUIListener remove(Xj3DNavigationUIListener oldl) {
-
-        if(oldl == a)
-            return b;
-
-        if(oldl == b)
-            return a;
-
-        Xj3DNavigationUIListener a2 = removeInternal(a, oldl);
-        Xj3DNavigationUIListener b2 = removeInternal(b, oldl);
-
-        if (a2 == a && b2 == b) {
-            return this;  // it's not here
-        }
-
-        return addInternal(a2, b2);
-    }
-
-    /**
-     * Register an error reporter with the engine so that any errors generated
-     * by the loading of script code can be reported in a nice, pretty fashion.
-     * Setting a value of null will clear the currently set reporter. If one
-     * is already set, the new value replaces the old.
-     *
-     * @param reporter The instance to use or null
-     */
-    static void setErrorReporter(ErrorReporter reporter) {
-        errorReporter = reporter;
-
-        // Reset the default only if we are not shutting down the system.
-        if(reporter == null)
-            errorReporter = DefaultErrorReporter.getDefaultReporter();
-    }
-
-    /**
-     * Adds input-method-listener-a with input-method-listener-b and
-     * returns the resulting multicast listener.
-     * @param a input-method-listener-a
-     * @param b input-method-listener-b
-     */
-    static Xj3DNavigationUIListener add(Xj3DNavigationUIListener a,
-                                        Xj3DNavigationUIListener b) {
-        return addInternal(a, b);
-    }
-
-    /**
-     * Removes the old component-listener from component-listener-l and
-     * returns the resulting multicast listener.
-     * @param l component-listener-l
-     * @param oldl the component-listener being removed
-     */
-    static Xj3DNavigationUIListener remove(Xj3DNavigationUIListener l,
-                                           Xj3DNavigationUIListener oldl) {
-        return removeInternal(l, oldl);
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by Xj3DNavigationUIListener
-    //----------------------------------------------------------
-
-    /**
-     * The list of active viewpoints have been changed to this new list. A new
-     * list can be given due to either a new world being loaded, or the active
-     * navigation layer has been changed. This method is not called if a single
-     * viewpoint is added or removed from the scene.
-     * <p>
-     *
-     * If the scene contains no viewpoints at all (except the default bindable),
-     * then this will be called with a null parameter.
-     * <p>
-     *
-     * On scene or navigation layer change, it is guaranteed that this method
-     * will be called before the notification of the actual bound viewpoint.
-     *
-     * @param An array of exactly the number of viewpoints in the list
-     */
-    @Override
-    public void availableViewpointsChanged(Xj3DViewpoint[] viewpoints) {
-        try {
-            a.availableViewpointsChanged(viewpoints);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(STATUS_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.availableViewpointsChanged(viewpoints);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(STATUS_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-
-    /**
-     * Notification that the selected viewpoint has been changed to this
-     * new instance. There are many different reasons this could happen -
-     * new node bound, world changed or even active navigation layer has
-     * changed and this is the default in that new layer.
-     * <p>
-     *
-     * If the file contains no viewpoints or the default viewpoint is
-     * bound (due to unbinding all real viewpoints on the stack) then this
-     * will be called with a null parameter.
-     * <p>
-     *
-     * It is guaranteed that this will always contain something from the
-     * currently active viewpoint list. If all change, that callback will be
-     * called before this one, to ensure consistency.
-     *
-     * @param vp The viewpoint instance that is now selected or null
-     */
-    @Override
-    public void selectedViewpointChanged(Xj3DViewpoint vp) {
-        try {
-            a.selectedViewpointChanged(vp);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(STATUS_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.selectedViewpointChanged(vp);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(STATUS_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-
-    /**
-     * Notification that this viewpoint has been appended to the list of
-     * available viewpoints.
-     *
-     * @param vp The viewpoint instance that was added
-     */
-    @Override
-    public void viewpointAdded(Xj3DViewpoint vp) {
-        try {
-            a.viewpointAdded(vp);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(STATUS_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.viewpointAdded(vp);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(STATUS_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-
-    /**
-     * Notification that this viewpoint has been removed from the list of
-     * available viewpoints.
-     *
-     * @param vp The viewpoint instance that was added
-     */
-    @Override
-    public void viewpointRemoved(Xj3DViewpoint vp) {
-        try {
-            a.viewpointRemoved(vp);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(STATUS_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.viewpointRemoved(vp);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(STATUS_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-
-
-    /**
-     * The list of available navigation states has changed to this new list.
-     * The list of states corresponds to the X3D-specification defined list
-     * and any additional browser-specific state names. If a state is not
-     * listed in this array, then the ability to activate it should be
-     * disabled (eg greying out the button that represents it). If no states
-     * are currently defined, this will contain the default string "NONE",
-     * which corresponds to disabling all user selection of navigation and
-     * even the ability to navigate.
-     *
-     * @param states An array of the available state strings.
-     */
-    @Override
-    public void availableNavigationStatesChanged(String[] states) {
-        try {
-            a.availableNavigationStatesChanged(states);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(STATUS_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.availableNavigationStatesChanged(states);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(STATUS_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-
-    /**
-     * Notification that the currently selected navigation state has changed
-     * to this new value. Selection may be due to the UI interaction,
-     * courtesy of a node being bound or the active navigation layer has
-     * changed.
-     *
-     * @param state The name of the state that is now the active state
-     */
-    @Override
-    public void selectedNavigationStateChanged(String state) {
-        try {
-            a.selectedNavigationStateChanged(state);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(STATUS_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.selectedNavigationStateChanged(state);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(STATUS_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-
-    //----------------------------------------------------------
-    // Local Methods
-    //----------------------------------------------------------
-
-    /**
-     * Returns the resulting multicast listener from adding listener-a
-     * and listener-b together.
-     * If listener-a is null, it returns listener-b;
-     * If listener-b is null, it returns listener-a
-     * If neither are null, then it creates and returns
-     *     a new Xj3DNavigationUIMulticaster instance which chains a with b.
-     * @param a event listener-a
-     * @param b event listener-b
-     */
-    private static Xj3DNavigationUIListener addInternal(Xj3DNavigationUIListener a,
-                                                     Xj3DNavigationUIListener b) {
-        if(a == null)
-            return b;
-
-        if(b == null)
-            return a;
-
-        return new NavigationListenerMulticaster(a, b);
-    }
-
-    /**
-     * Returns the resulting multicast listener after removing the
-     * old listener from listener-l.
-     * If listener-l equals the old listener OR listener-l is null,
-     * returns null.
-     * Else if listener-l is an instance of Xj3DNavigationUIMulticaster,
-     * then it removes the old listener from it.
-     * Else, returns listener l.
-     * @param l the listener being removed from
-     * @param oldl the listener being removed
-     */
-    private static Xj3DNavigationUIListener removeInternal(Xj3DNavigationUIListener l,
-                                                        Xj3DNavigationUIListener oldl) {
-        if (l == oldl || l == null) {
-            return null;
-        } else if (l instanceof NavigationListenerMulticaster) {
-            return ((NavigationListenerMulticaster)l).remove(oldl);
-        } else {
-            return l;   // it's not here
-        }
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.scripting.external.sai;
+
+// External imports
+// none
+
+// Local imports
+import org.j3d.util.DefaultErrorReporter;
+import org.j3d.util.ErrorReporter;
+
+import org.xj3d.sai.Xj3DNavigationUIListener;
+import org.xj3d.sai.Xj3DViewpoint;
+
+/**
+ * A class which implements efficient and thread-safe multi-cast event
+ * dispatching for the events defined in this package.
+ * <p>
+ *
+ * This class will manage an immutable structure consisting of a chain of
+ * event listeners and will dispatch events to those listeners.  Because
+ * the structure is immutable, it is safe to use this API to add/remove
+ * listeners during the process of an event dispatch operation.
+ * <p>
+ *
+ * An example of how this class could be used to implement a new
+ * component which fires "action" events:
+ *
+ * <pre><code>
+ * public myComponent extends Component {
+ *   Xj3DNavigationUIListener listener = null;
+ *
+ *   public void addNodeListener(Xj3DNavigationUIListener l) {
+ *     listener = NavigationListenerMulticaster.add(listener, l);
+ *   }
+ *
+ *   public void removeNodeListener(Xj3DNavigationUIListener l) {
+ *     listener = NavigationListenerMulticaster.remove(listener, l);
+ *   }
+ *
+ *   public void browerChanged(Xj3DNavigationUIEvent evt) {
+ *     if(listener != null) {
+ *       listener.browserChanged(evt);
+ *   }
+ * }
+ * </code></pre>
+ *
+ * @author  Justin Couch
+ * @version $Revision: 1.1 $
+ */
+class NavigationListenerMulticaster
+    implements Xj3DNavigationUIListener {
+
+    /** Error message when the user code barfs */
+    private static final String STATUS_ERROR_MSG =
+        "Error sending status message change updates: ";
+
+    /** Error message when the user code barfs */
+    private static final String FPS_ERROR_MSG =
+        "Error sending framerate updates: ";
+
+    /** Error message when the user code barfs */
+    private static final String PROGRESS_ERROR_MSG =
+        "Error sending progress update message: ";
+
+    /** Default error message when sending the error messsage fails */
+    private static final String DEFAULT_ERR_MSG =
+        "Unknown error sending navigation state change event: ";
+
+    /** The node listeners in use by this class */
+    private final Xj3DNavigationUIListener a;
+
+    /** The node listeners in use by this class */
+    private final Xj3DNavigationUIListener b;
+
+    /** Reporter instance for handing out errors */
+    private static ErrorReporter errorReporter =
+        DefaultErrorReporter.getDefaultReporter();
+
+    /**
+     * Creates an event multicaster instance which chains listener-a
+     * with listener-b. Input parameters <code>a</code> and <code>b</code>
+     * should not be <code>null</code>, though implementations may vary in
+     * choosing whether or not to throw <code>NullPointerException</code>
+     * in that case.
+     * @param a listener-a
+     * @param b listener-b
+     */
+    NavigationListenerMulticaster(Xj3DNavigationUIListener a,
+                                  Xj3DNavigationUIListener b) {
+        this.a = a;
+        this.b = b;
+    }
+
+    /**
+     * Removes a listener from this multicaster and returns the
+     * resulting multicast listener.
+     * @param oldl the listener to be removed
+     */
+    Xj3DNavigationUIListener remove(Xj3DNavigationUIListener oldl) {
+
+        if(oldl == a)
+            return b;
+
+        if(oldl == b)
+            return a;
+
+        Xj3DNavigationUIListener a2 = removeInternal(a, oldl);
+        Xj3DNavigationUIListener b2 = removeInternal(b, oldl);
+
+        if (a2 == a && b2 == b) {
+            return this;  // it's not here
+        }
+
+        return addInternal(a2, b2);
+    }
+
+    /**
+     * Register an error reporter with the engine so that any errors generated
+     * by the loading of script code can be reported in a nice, pretty fashion.
+     * Setting a value of null will clear the currently set reporter. If one
+     * is already set, the new value replaces the old.
+     *
+     * @param reporter The instance to use or null
+     */
+    static void setErrorReporter(ErrorReporter reporter) {
+        errorReporter = reporter;
+
+        // Reset the default only if we are not shutting down the system.
+        if(reporter == null)
+            errorReporter = DefaultErrorReporter.getDefaultReporter();
+    }
+
+    /**
+     * Adds input-method-listener-a with input-method-listener-b and
+     * returns the resulting multicast listener.
+     * @param a input-method-listener-a
+     * @param b input-method-listener-b
+     */
+    static Xj3DNavigationUIListener add(Xj3DNavigationUIListener a,
+                                        Xj3DNavigationUIListener b) {
+        return addInternal(a, b);
+    }
+
+    /**
+     * Removes the old component-listener from component-listener-l and
+     * returns the resulting multicast listener.
+     * @param l component-listener-l
+     * @param oldl the component-listener being removed
+     */
+    static Xj3DNavigationUIListener remove(Xj3DNavigationUIListener l,
+                                           Xj3DNavigationUIListener oldl) {
+        return removeInternal(l, oldl);
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by Xj3DNavigationUIListener
+    //----------------------------------------------------------
+
+    /**
+     * The list of active viewpoints have been changed to this new list. A new
+     * list can be given due to either a new world being loaded, or the active
+     * navigation layer has been changed. This method is not called if a single
+     * viewpoint is added or removed from the scene.
+     * <p>
+     *
+     * If the scene contains no viewpoints at all (except the default bindable),
+     * then this will be called with a null parameter.
+     * <p>
+     *
+     * On scene or navigation layer change, it is guaranteed that this method
+     * will be called before the notification of the actual bound viewpoint.
+     *
+     * @param An array of exactly the number of viewpoints in the list
+     */
+    @Override
+    public void availableViewpointsChanged(Xj3DViewpoint[] viewpoints) {
+        try {
+            a.availableViewpointsChanged(viewpoints);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(STATUS_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.availableViewpointsChanged(viewpoints);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(STATUS_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+
+    /**
+     * Notification that the selected viewpoint has been changed to this
+     * new instance. There are many different reasons this could happen -
+     * new node bound, world changed or even active navigation layer has
+     * changed and this is the default in that new layer.
+     * <p>
+     *
+     * If the file contains no viewpoints or the default viewpoint is
+     * bound (due to unbinding all real viewpoints on the stack) then this
+     * will be called with a null parameter.
+     * <p>
+     *
+     * It is guaranteed that this will always contain something from the
+     * currently active viewpoint list. If all change, that callback will be
+     * called before this one, to ensure consistency.
+     *
+     * @param vp The viewpoint instance that is now selected or null
+     */
+    @Override
+    public void selectedViewpointChanged(Xj3DViewpoint vp) {
+        try {
+            a.selectedViewpointChanged(vp);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(STATUS_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.selectedViewpointChanged(vp);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(STATUS_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+
+    /**
+     * Notification that this viewpoint has been appended to the list of
+     * available viewpoints.
+     *
+     * @param vp The viewpoint instance that was added
+     */
+    @Override
+    public void viewpointAdded(Xj3DViewpoint vp) {
+        try {
+            a.viewpointAdded(vp);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(STATUS_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.viewpointAdded(vp);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(STATUS_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+
+    /**
+     * Notification that this viewpoint has been removed from the list of
+     * available viewpoints.
+     *
+     * @param vp The viewpoint instance that was added
+     */
+    @Override
+    public void viewpointRemoved(Xj3DViewpoint vp) {
+        try {
+            a.viewpointRemoved(vp);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(STATUS_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.viewpointRemoved(vp);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(STATUS_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+
+
+    /**
+     * The list of available navigation states has changed to this new list.
+     * The list of states corresponds to the X3D-specification defined list
+     * and any additional browser-specific state names. If a state is not
+     * listed in this array, then the ability to activate it should be
+     * disabled (eg greying out the button that represents it). If no states
+     * are currently defined, this will contain the default string "NONE",
+     * which corresponds to disabling all user selection of navigation and
+     * even the ability to navigate.
+     *
+     * @param states An array of the available state strings.
+     */
+    @Override
+    public void availableNavigationStatesChanged(String[] states) {
+        try {
+            a.availableNavigationStatesChanged(states);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(STATUS_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.availableNavigationStatesChanged(states);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(STATUS_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+
+    /**
+     * Notification that the currently selected navigation state has changed
+     * to this new value. Selection may be due to the UI interaction,
+     * courtesy of a node being bound or the active navigation layer has
+     * changed.
+     *
+     * @param state The name of the state that is now the active state
+     */
+    @Override
+    public void selectedNavigationStateChanged(String state) {
+        try {
+            a.selectedNavigationStateChanged(state);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(STATUS_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.selectedNavigationStateChanged(state);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(STATUS_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+
+    //----------------------------------------------------------
+    // Local Methods
+    //----------------------------------------------------------
+
+    /**
+     * Returns the resulting multicast listener from adding listener-a
+     * and listener-b together.
+     * If listener-a is null, it returns listener-b;
+     * If listener-b is null, it returns listener-a
+     * If neither are null, then it creates and returns
+     *     a new Xj3DNavigationUIMulticaster instance which chains a with b.
+     * @param a event listener-a
+     * @param b event listener-b
+     */
+    private static Xj3DNavigationUIListener addInternal(Xj3DNavigationUIListener a,
+                                                     Xj3DNavigationUIListener b) {
+        if(a == null)
+            return b;
+
+        if(b == null)
+            return a;
+
+        return new NavigationListenerMulticaster(a, b);
+    }
+
+    /**
+     * Returns the resulting multicast listener after removing the
+     * old listener from listener-l.
+     * If listener-l equals the old listener OR listener-l is null,
+     * returns null.
+     * Else if listener-l is an instance of Xj3DNavigationUIMulticaster,
+     * then it removes the old listener from it.
+     * Else, returns listener l.
+     * @param l the listener being removed from
+     * @param oldl the listener being removed
+     */
+    private static Xj3DNavigationUIListener removeInternal(Xj3DNavigationUIListener l,
+                                                        Xj3DNavigationUIListener oldl) {
+        if (l == oldl || l == null) {
+            return null;
+        } else if (l instanceof NavigationListenerMulticaster) {
+            return ((NavigationListenerMulticaster)l).remove(oldl);
+        } else {
+            return l;   // it's not here
+        }
+    }
+}
diff --git a/src/java/org/web3d/vrml/scripting/external/sai/SAIBrowser.java b/src/java/org/web3d/vrml/scripting/external/sai/SAIBrowser.java
index e93aff90d23984c7c9463f3179682a986ae7fee2..62f02440a7b983cad5238df8c5eda6e2deb5d8f1 100644
--- a/src/java/org/web3d/vrml/scripting/external/sai/SAIBrowser.java
+++ b/src/java/org/web3d/vrml/scripting/external/sai/SAIBrowser.java
@@ -69,13 +69,15 @@ import org.xj3d.impl.core.eventmodel.DefaultNavigationManager;
  * SAIBrowser implements the {@link Browser} interface, largely by
  * translating and interfacing between the wrapper classes and the
  * implementation class represented by {org.web3d.vrml.scripting.CommonBrowser}.
- * 
+ *  <p>
  * To function correctly, SAIBrowser needs to be constructed using
  * CommonBrowser and BrowserCore instances.  The SAIBrowser then registers
  * as a listener so that BrowserCoreListener BrowserInitialized and
  * browserShutdown messages.  The BrowserCore instance is necessary mainly
  * for the global namespace and VRMLExecutionSpace information.
- * 
+ *
+ *  <p>
+ *
  * @author Brad Vender, Rex Melton, Justin Couch
  * @version $Revision: 1.64 $
  */
diff --git a/src/java/org/web3d/vrml/scripting/external/sai/SAINodeFactory.java b/src/java/org/web3d/vrml/scripting/external/sai/SAINodeFactory.java
index 4475d285cba4f074454ee14aa440efab63cc581d..dc2aa32d838632591ae9b84f871cc2535522b7a5 100644
--- a/src/java/org/web3d/vrml/scripting/external/sai/SAINodeFactory.java
+++ b/src/java/org/web3d/vrml/scripting/external/sai/SAINodeFactory.java
@@ -22,11 +22,11 @@ import org.web3d.x3d.sai.X3DProtoInstance;
   * dependency loops in the SAI implementation--between EventIn*NodeWrapper
   * and SimpleWrappingNode and between SimpleWrappingNode and 
   * EventOut*Node Wrapper.  
-  * 
+  *  <p>
   * Given a VRMLNodeType or X3DNode, this class can produce or locate
   * the corresponding instance.  Whether the instance returned is unique or
   * simply equivalent between subsequent calls is implementation dependent.
-  * 
+  *  <p>
   * @author Brad Vender
   */
 
diff --git a/src/java/org/web3d/vrml/scripting/external/sai/StatusAdapter.java b/src/java/org/web3d/vrml/scripting/external/sai/StatusAdapter.java
index c84f5f66c5cb513a95eb43a2c1967e48eef148db..7206b13da5d256b7812f21ed08a6da1fc170b8cc 100644
--- a/src/java/org/web3d/vrml/scripting/external/sai/StatusAdapter.java
+++ b/src/java/org/web3d/vrml/scripting/external/sai/StatusAdapter.java
@@ -1,310 +1,310 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2007
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.scripting.external.sai;
-
-// External imports
-import org.ietf.uri.ResourceConnection;
-import org.ietf.uri.URI;
-import org.ietf.uri.event.ProgressEvent;
-import org.ietf.uri.event.ProgressListener;
-
-// Local imports
-import org.web3d.browser.BrowserCore;
-import org.web3d.browser.ProfilingInfo;
-import org.web3d.browser.ProfilingListener;
-
-import org.j3d.util.DefaultErrorReporter;
-import org.j3d.util.ErrorReporter;
-
-import org.web3d.vrml.nodes.FrameStateListener;
-import org.web3d.vrml.nodes.FrameStateManager;
-
-import org.xj3d.core.loading.ContentLoadManager;
-
-import org.xj3d.sai.Xj3DStatusListener;
-
-/**
- * An adapter class for providing browser internal info and state through
- * the <code>Xj3DStatusListener</code> interface.
- *
- * @author Rex Melton
- * @version $Revision: 1.2 $
- */
-class StatusAdapter implements ProfilingListener, ProgressListener, FrameStateListener {
-
-    /** Load started progress message */
-    private static final String LOAD_STARTED_MSG =
-        "Load Started";
-
-    /** Load started progress message */
-    private static final String LOADING_MSG =
-        "Loading";
-
-    /** Load complete progress message */
-    private static final String LOAD_COMPLETE_MSG =
-        "Load Complete";
-
-    /** The implementation of the browser core */
-    private BrowserCore browserCore;
-
-    /** FrameState manager */
-    private FrameStateManager stateManager;
-
-    /** The load manager */
-    private ContentLoadManager loadManager;
-
-    /** The ErrorReporter to send errors and warnings to. */
-    private ErrorReporter errorReporter;
-
-    /** Multicaster for status event listeners. */
-    private Xj3DStatusListener statusListener;
-
-    /**
-     * Constructor
-     *
-     * @param browserCore The BrowserCore to use as the implementation.
-     * @param fsm The frame state manager
-     * @param clm The content load manager
-     * @param reporter The ErrorReporter to use.  If null, will use
-     * DefaultErrorReporter's default.
-     */
-    StatusAdapter(
-		BrowserCore core, 
-		FrameStateManager fsm, 
-		ContentLoadManager clm, 
-		ErrorReporter reporter) {
-		
-        browserCore = core;
-		stateManager = fsm;
-		loadManager = clm;
-        errorReporter = (reporter == null) ?
-            DefaultErrorReporter.getDefaultReporter() : reporter;
-		
-        browserCore.addProfilingListener(this);
-        ResourceConnection.addGlobalProgressListener(this);
-    }
-		
-    //-------------------------------------------------------------------
-    // Methods defined by FrameStateListener
-    //-------------------------------------------------------------------
-
-    @Override
-    public void allEventsComplete() {
-		if (statusListener != null) {
-			statusListener.loadUpdate(loadManager.getNumberInProgress());
-			stateManager.addEndOfThisFrameListener(this);
-		}
-	}
-	
-    //-------------------------------------------------------------------
-    // Methods defined by ProfilingListener
-    //-------------------------------------------------------------------
-
-    /**
-     * The profiling data has changed. This will happen at the end of each
-     * frame render.
-     *
-     * @param data The profiling data
-     */
-    @Override
-    public void profilingDataChanged(ProfilingInfo data) {
-        // at present, the data being delivered in ProfilingInfo is....
-        // incomplete. presumably we want to use that eventually, till
-        // then however, return the core's notion of the frame rate.
-		if (statusListener != null) {
-        	statusListener.updateFramesPerSecond(browserCore.getCurrentFrameRate());
-		}
-    }
-
-    //---------------------------------------------------------------
-    // Methods defined by ProgressListener
-    //---------------------------------------------------------------
-
-    /**
-     * A connection to the resource has been established. At this point, no data
-     * has yet been downloaded.
-     *
-     * @param evt The event that caused this method to be called.
-     */
-    @Override
-    public void connectionEstablished(ProgressEvent evt) {
-		if (statusListener != null) {
-        	statusListener.updateStatusMessage(evt.getMessage());
-		}
-    }
-
-    /**
-     * The header information reading and handshaking is taking place. Reading
-     * and interpreting of the data (a download started event) should commence
-     * shortly. When that begins, you will be given the appropriate event.
-     *
-     * @param evt The event that caused this method to be called.
-     */
-    @Override
-    public void handshakeInProgress(ProgressEvent evt) {
-		if (statusListener != null) {
-        	statusListener.updateStatusMessage(evt.getMessage());
-		}
-    }
-
-    /**
-     * The download has started.
-     *
-     * @param evt The event that caused this method to be called.
-     */
-    @Override
-    public void downloadStarted(ProgressEvent evt) {
-		if (statusListener != null) {
-			ResourceConnection conn = evt.getSource();
-			if (conn != null) {
-				URI uri = conn.getURI();
-				String url = uri.toExternalForm();
-				statusListener.progressUpdate(url, LOAD_STARTED_MSG, 0);
-			}
-			statusListener.updateStatusMessage(evt.getMessage());
-		}
-    }
-
-    /**
-     * The download has updated its status.
-     *
-     * @param evt The event that caused this method to be called.
-     */
-    @Override
-    public void downloadUpdate(ProgressEvent evt) {
-		if (statusListener != null) {
-			ResourceConnection conn = evt.getSource();
-			if (conn != null) {
-				String url = conn.getURI().toExternalForm();
-				if (isFile(conn)) {
-					// it has been observed that getContentLength() does not
-					// return useful information for network connections.
-					// therefore, progress updates are only logged for local files
-					float total = conn.getContentLength();
-					float progress = evt.getValue();
-					float perc = 100 * progress/total;
-					statusListener.progressUpdate(url, LOADING_MSG, perc);
-				}
-			}
-		}
-    }
-
-    /**
-     * The download has ended.
-     *
-     * @param evt The event that caused this method to be called.
-     */
-    @Override
-    public void downloadEnded(ProgressEvent evt) {
-		if (statusListener != null) {
-			ResourceConnection conn = evt.getSource();
-			if (conn != null) {
-				String url = conn.getURI().toExternalForm();
-				String msg = url + " download complete.";
-				statusListener.updateStatusMessage(msg);
-				statusListener.progressUpdate(url, LOAD_COMPLETE_MSG, 100);
-				errorReporter.messageReport(msg);
-			}
-		}
-    }
-
-    /**
-     * An error has occurred during the download.
-     *
-     * @param evt The event that caused this method to be called.
-     */
-    @Override
-    public void downloadError(ProgressEvent evt) {
-		if (statusListener != null) {
-			statusListener.updateStatusMessage(evt.getMessage());
-			errorReporter.errorReport(evt.getMessage(), null);
-		}
-    }
-
-    //-------------------------------------------------------------------
-    // Local Methods
-    //-------------------------------------------------------------------
-
-    /**
-     * Send a status message out to the listeners.
-     *
-     * @param msg The status message to send through.
-     */
-    void sendStatusMessage(String msg) {
-		if (statusListener != null) {
-        	statusListener.updateStatusMessage(msg);
-		}
-    }
-
-    /**
-     * Set the handler for error messages.
-     *
-     * @param reporter The error reporter instance to use
-     */
-    void setErrorReporter(ErrorReporter reporter) {
-        errorReporter = (reporter == null) ?
-            DefaultErrorReporter.getDefaultReporter() : reporter;
-    }
-
-    /**
-     * Shutdown and release resources
-     */
-    void shutdown() {
-        ResourceConnection.removeGlobalProgressListener(this);
-    }
-
-    /**
-     * Add a listener for status messages. Adding the same listener
-     * instance more than once will be silently ignored. Null values are
-     * ignored.
-     *
-     * @param l The listener instance to add
-     */
-    void addStatusListener(Xj3DStatusListener l) {
-        statusListener = StatusListenerMulticaster.add(statusListener, l);
-		if (statusListener != null) {
-			stateManager.addEndOfThisFrameListener(this);
-		}
-    }
-
-    /**
-     * Remove a listener for status messages. If this listener is
-     * not currently registered, the request will be silently ignored.
-     *
-     * @param l The listener instance to remove
-     */
-    void removeStatusListener(Xj3DStatusListener l) {
-        statusListener = StatusListenerMulticaster.remove(statusListener, l);
-		if (statusListener != null) {
-			stateManager.addEndOfThisFrameListener(this);
-		}
-    }
-
-    /**
-     * Check whether the connection represents a local file
-     *
-     * @param conn The connection
-     * @return true if the connection is to a local file, false otherwise.
-     */
-    private boolean isFile(ResourceConnection conn) {
-        boolean isFile = false;
-        if (conn != null) {
-            URI uri = conn.getURI();
-            String form = uri.toExternalForm();
-
-            isFile = URI.getScheme(form).equals(URI.FILE_SCHEME);
-        }
-
-        return isFile;
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001 - 2007
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.scripting.external.sai;
+
+// External imports
+import org.ietf.uri.ResourceConnection;
+import org.ietf.uri.URI;
+import org.ietf.uri.event.ProgressEvent;
+import org.ietf.uri.event.ProgressListener;
+
+// Local imports
+import org.web3d.browser.BrowserCore;
+import org.web3d.browser.ProfilingInfo;
+import org.web3d.browser.ProfilingListener;
+
+import org.j3d.util.DefaultErrorReporter;
+import org.j3d.util.ErrorReporter;
+
+import org.web3d.vrml.nodes.FrameStateListener;
+import org.web3d.vrml.nodes.FrameStateManager;
+
+import org.xj3d.core.loading.ContentLoadManager;
+
+import org.xj3d.sai.Xj3DStatusListener;
+
+/**
+ * An adapter class for providing browser internal info and state through
+ * the <code>Xj3DStatusListener</code> interface.
+ *
+ * @author Rex Melton
+ * @version $Revision: 1.2 $
+ */
+class StatusAdapter implements ProfilingListener, ProgressListener, FrameStateListener {
+
+    /** Load started progress message */
+    private static final String LOAD_STARTED_MSG =
+        "Load Started";
+
+    /** Load started progress message */
+    private static final String LOADING_MSG =
+        "Loading";
+
+    /** Load complete progress message */
+    private static final String LOAD_COMPLETE_MSG =
+        "Load Complete";
+
+    /** The implementation of the browser core */
+    private BrowserCore browserCore;
+
+    /** FrameState manager */
+    private FrameStateManager stateManager;
+
+    /** The load manager */
+    private ContentLoadManager loadManager;
+
+    /** The ErrorReporter to send errors and warnings to. */
+    private ErrorReporter errorReporter;
+
+    /** Multicaster for status event listeners. */
+    private Xj3DStatusListener statusListener;
+
+    /**
+     * Constructor
+     *
+     * @param browserCore The BrowserCore to use as the implementation.
+     * @param fsm The frame state manager
+     * @param clm The content load manager
+     * @param reporter The ErrorReporter to use.  If null, will use
+     * DefaultErrorReporter's default.
+     */
+    StatusAdapter(
+		BrowserCore core, 
+		FrameStateManager fsm, 
+		ContentLoadManager clm, 
+		ErrorReporter reporter) {
+		
+        browserCore = core;
+		stateManager = fsm;
+		loadManager = clm;
+        errorReporter = (reporter == null) ?
+            DefaultErrorReporter.getDefaultReporter() : reporter;
+		
+        browserCore.addProfilingListener(this);
+        ResourceConnection.addGlobalProgressListener(this);
+    }
+		
+    //-------------------------------------------------------------------
+    // Methods defined by FrameStateListener
+    //-------------------------------------------------------------------
+
+    @Override
+    public void allEventsComplete() {
+		if (statusListener != null) {
+			statusListener.loadUpdate(loadManager.getNumberInProgress());
+			stateManager.addEndOfThisFrameListener(this);
+		}
+	}
+	
+    //-------------------------------------------------------------------
+    // Methods defined by ProfilingListener
+    //-------------------------------------------------------------------
+
+    /**
+     * The profiling data has changed. This will happen at the end of each
+     * frame render.
+     *
+     * @param data The profiling data
+     */
+    @Override
+    public void profilingDataChanged(ProfilingInfo data) {
+        // at present, the data being delivered in ProfilingInfo is....
+        // incomplete. presumably we want to use that eventually, till
+        // then however, return the core's notion of the frame rate.
+		if (statusListener != null) {
+        	statusListener.updateFramesPerSecond(browserCore.getCurrentFrameRate());
+		}
+    }
+
+    //---------------------------------------------------------------
+    // Methods defined by ProgressListener
+    //---------------------------------------------------------------
+
+    /**
+     * A connection to the resource has been established. At this point, no data
+     * has yet been downloaded.
+     *
+     * @param evt The event that caused this method to be called.
+     */
+    @Override
+    public void connectionEstablished(ProgressEvent evt) {
+		if (statusListener != null) {
+        	statusListener.updateStatusMessage(evt.getMessage());
+		}
+    }
+
+    /**
+     * The header information reading and handshaking is taking place. Reading
+     * and interpreting of the data (a download started event) should commence
+     * shortly. When that begins, you will be given the appropriate event.
+     *
+     * @param evt The event that caused this method to be called.
+     */
+    @Override
+    public void handshakeInProgress(ProgressEvent evt) {
+		if (statusListener != null) {
+        	statusListener.updateStatusMessage(evt.getMessage());
+		}
+    }
+
+    /**
+     * The download has started.
+     *
+     * @param evt The event that caused this method to be called.
+     */
+    @Override
+    public void downloadStarted(ProgressEvent evt) {
+		if (statusListener != null) {
+			ResourceConnection conn = evt.getSource();
+			if (conn != null) {
+				URI uri = conn.getURI();
+				String url = uri.toExternalForm();
+				statusListener.progressUpdate(url, LOAD_STARTED_MSG, 0);
+			}
+			statusListener.updateStatusMessage(evt.getMessage());
+		}
+    }
+
+    /**
+     * The download has updated its status.
+     *
+     * @param evt The event that caused this method to be called.
+     */
+    @Override
+    public void downloadUpdate(ProgressEvent evt) {
+		if (statusListener != null) {
+			ResourceConnection conn = evt.getSource();
+			if (conn != null) {
+				String url = conn.getURI().toExternalForm();
+				if (isFile(conn)) {
+					// it has been observed that getContentLength() does not
+					// return useful information for network connections.
+					// therefore, progress updates are only logged for local files
+					float total = conn.getContentLength();
+					float progress = evt.getValue();
+					float perc = 100 * progress/total;
+					statusListener.progressUpdate(url, LOADING_MSG, perc);
+				}
+			}
+		}
+    }
+
+    /**
+     * The download has ended.
+     *
+     * @param evt The event that caused this method to be called.
+     */
+    @Override
+    public void downloadEnded(ProgressEvent evt) {
+		if (statusListener != null) {
+			ResourceConnection conn = evt.getSource();
+			if (conn != null) {
+				String url = conn.getURI().toExternalForm();
+				String msg = url + " download complete.";
+				statusListener.updateStatusMessage(msg);
+				statusListener.progressUpdate(url, LOAD_COMPLETE_MSG, 100);
+				errorReporter.messageReport(msg);
+			}
+		}
+    }
+
+    /**
+     * An error has occurred during the download.
+     *
+     * @param evt The event that caused this method to be called.
+     */
+    @Override
+    public void downloadError(ProgressEvent evt) {
+		if (statusListener != null) {
+			statusListener.updateStatusMessage(evt.getMessage());
+			errorReporter.errorReport(evt.getMessage(), null);
+		}
+    }
+
+    //-------------------------------------------------------------------
+    // Local Methods
+    //-------------------------------------------------------------------
+
+    /**
+     * Send a status message out to the listeners.
+     *
+     * @param msg The status message to send through.
+     */
+    void sendStatusMessage(String msg) {
+		if (statusListener != null) {
+        	statusListener.updateStatusMessage(msg);
+		}
+    }
+
+    /**
+     * Set the handler for error messages.
+     *
+     * @param reporter The error reporter instance to use
+     */
+    void setErrorReporter(ErrorReporter reporter) {
+        errorReporter = (reporter == null) ?
+            DefaultErrorReporter.getDefaultReporter() : reporter;
+    }
+
+    /**
+     * Shutdown and release resources
+     */
+    void shutdown() {
+        ResourceConnection.removeGlobalProgressListener(this);
+    }
+
+    /**
+     * Add a listener for status messages. Adding the same listener
+     * instance more than once will be silently ignored. Null values are
+     * ignored.
+     *
+     * @param l The listener instance to add
+     */
+    void addStatusListener(Xj3DStatusListener l) {
+        statusListener = StatusListenerMulticaster.add(statusListener, l);
+		if (statusListener != null) {
+			stateManager.addEndOfThisFrameListener(this);
+		}
+    }
+
+    /**
+     * Remove a listener for status messages. If this listener is
+     * not currently registered, the request will be silently ignored.
+     *
+     * @param l The listener instance to remove
+     */
+    void removeStatusListener(Xj3DStatusListener l) {
+        statusListener = StatusListenerMulticaster.remove(statusListener, l);
+		if (statusListener != null) {
+			stateManager.addEndOfThisFrameListener(this);
+		}
+    }
+
+    /**
+     * Check whether the connection represents a local file
+     *
+     * @param conn The connection
+     * @return true if the connection is to a local file, false otherwise.
+     */
+    private boolean isFile(ResourceConnection conn) {
+        boolean isFile = false;
+        if (conn != null) {
+            URI uri = conn.getURI();
+            String form = uri.toExternalForm();
+
+            isFile = URI.getScheme(form).equals(URI.FILE_SCHEME);
+        }
+
+        return isFile;
+    }
+}
diff --git a/src/java/org/web3d/vrml/scripting/external/sai/StatusListenerMulticaster.java b/src/java/org/web3d/vrml/scripting/external/sai/StatusListenerMulticaster.java
index 84008e9945ff0d4e35f371095552039df6bb0f5e..8edb2824a11782f2559bb21d4308a9a0f97578e0 100644
--- a/src/java/org/web3d/vrml/scripting/external/sai/StatusListenerMulticaster.java
+++ b/src/java/org/web3d/vrml/scripting/external/sai/StatusListenerMulticaster.java
@@ -1,344 +1,344 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.scripting.external.sai;
-
-// External imports
-// none
-
-// Local imports
-import org.j3d.util.DefaultErrorReporter;
-import org.j3d.util.ErrorReporter;
-
-import org.xj3d.sai.Xj3DStatusListener;
-
-/**
- * A class which implements efficient and thread-safe multi-cast event
- * dispatching for the events defined in this package.
- * <p>
- *
- * This class will manage an immutable structure consisting of a chain of
- * event listeners and will dispatch events to those listeners.  Because
- * the structure is immutable, it is safe to use this API to add/remove
- * listeners during the process of an event dispatch operation.
- * <p>
- *
- * An example of how this class could be used to implement a new
- * component which fires "action" events:
- *
- * <pre><code>
- * public myComponent extends Component {
- *   Xj3DStatusListener listener = null;
- *
- *   public void addNodeListener(Xj3DStatusListener l) {
- *     listener = StatusListenerMulticaster.add(listener, l);
- *   }
- *
- *   public void removeNodeListener(Xj3DStatusListener l) {
- *     listener = StatusListenerMulticaster.remove(listener, l);
- *   }
- *
- *   public void browerChanged(Xj3DStatusEvent evt) {
- *     if(listener != null) {
- *       listener.browserChanged(evt);
- *   }
- * }
- * </code></pre>
- *
- * @author  Justin Couch
- * @version $Revision: 1.1 $
- */
-class StatusListenerMulticaster
-    implements Xj3DStatusListener {
-
-    /** Error message when the user code barfs */
-    private static final String STATUS_ERROR_MSG =
-        "Error sending status message change updates: ";
-
-    /** Error message when the user code barfs */
-    private static final String FPS_ERROR_MSG =
-        "Error sending framerate updates: ";
-
-    /** Error message when the user code barfs */
-    private static final String PROGRESS_ERROR_MSG =
-        "Error sending progress update message: ";
-
-    /** Default error message when sending the error message fails */
-    private static final String DEFAULT_ERR_MSG =
-        "Unknown error sending browser change event: ";
-
-    /** The node listeners in use by this class */
-    private final Xj3DStatusListener a;
-
-    /** The node listeners in use by this class */
-    private final Xj3DStatusListener b;
-
-    /** Reporter instance for handing out errors */
-    private static ErrorReporter errorReporter =
-        DefaultErrorReporter.getDefaultReporter();
-
-    /**
-     * Creates an event multicaster instance which chains listener-a
-     * with listener-b. Input parameters <code>a</code> and <code>b</code>
-     * should not be <code>null</code>, though implementations may vary in
-     * choosing whether or not to throw <code>NullPointerException</code>
-     * in that case.
-     * @param a listener-a
-     * @param b listener-b
-     */
-    StatusListenerMulticaster(Xj3DStatusListener a, Xj3DStatusListener b) {
-        this.a = a;
-        this.b = b;
-    }
-
-    /**
-     * Removes a listener from this multicaster and returns the
-     * resulting multicast listener.
-     * @param oldl the listener to be removed
-     */
-    Xj3DStatusListener remove(Xj3DStatusListener oldl) {
-
-        if(oldl == a)
-            return b;
-
-        if(oldl == b)
-            return a;
-
-        Xj3DStatusListener a2 = removeInternal(a, oldl);
-        Xj3DStatusListener b2 = removeInternal(b, oldl);
-
-        if (a2 == a && b2 == b) {
-            return this;  // it's not here
-        }
-
-        return addInternal(a2, b2);
-    }
-
-    /**
-     * Register an error reporter with the engine so that any errors generated
-     * by the loading of script code can be reported in a nice, pretty fashion.
-     * Setting a value of null will clear the currently set reporter. If one
-     * is already set, the new value replaces the old.
-     *
-     * @param reporter The instance to use or null
-     */
-    static void setErrorReporter(ErrorReporter reporter) {
-        errorReporter = reporter;
-
-        // Reset the default only if we are not shutting down the system.
-        if(reporter == null)
-            errorReporter = DefaultErrorReporter.getDefaultReporter();
-    }
-
-    /**
-     * Adds input-method-listener-a with input-method-listener-b and
-     * returns the resulting multicast listener.
-     * @param a input-method-listener-a
-     * @param b input-method-listener-b
-     */
-    static Xj3DStatusListener add(Xj3DStatusListener a, Xj3DStatusListener b) {
-        return addInternal(a, b);
-    }
-
-    /**
-     * Removes the old component-listener from component-listener-l and
-     * returns the resulting multicast listener.
-     * @param l component-listener-l
-     * @param oldl the component-listener being removed
-     */
-    static Xj3DStatusListener remove(Xj3DStatusListener l, Xj3DStatusListener oldl) {
-        return removeInternal(l, oldl);
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by Xj3DStatusListener
-    //----------------------------------------------------------
-
-    /**
-     * Notification that a single line status message has changed to the new
-     * string. A null string means to clear the currently displayed message.
-     *
-     * @param msg The new message string to display for the status
-     */
-    @Override
-    public void updateStatusMessage(String msg) {
-        try {
-            a.updateStatusMessage(msg);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(STATUS_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.updateStatusMessage(msg);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(STATUS_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-
-    /**
-     * Notification that the calculated frames per second has changed to this
-     * new value. It is expected that this is called frequently.
-     */
-    @Override
-    public void updateFramesPerSecond(float fps) {
-        try {
-            a.updateFramesPerSecond(fps);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(FPS_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.updateFramesPerSecond(fps);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(FPS_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-
-    /**
-     * Notification of a progress update. There may be several items in
-     * progression at once (eg multithreaded texture and scripting loading)
-     * so implementers should work appropriately for this situation. To keep
-     * this aligned, each item that is reporting progress will have a unique
-     * ID string (for this session) associated with it so you can keep track
-     * of the multiples. Once 100% has been reached you can assume that the
-     * tracking is complete for that object.
-     *
-     * @param id A unique ID string for the given item
-     * @param msg A message to accompany the update
-     * @param perc A percentage from 0-100 of the progress completion
-     */
-    @Override
-    public void progressUpdate(String id, String msg, float perc) {
-
-        try {
-            a.progressUpdate(id, msg, perc);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(PROGRESS_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.progressUpdate(id, msg, perc);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(PROGRESS_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-
-    @Override
-	public void loadUpdate(int numInProgress) {
-
-        try {
-            a.loadUpdate(numInProgress);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(PROGRESS_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.loadUpdate(numInProgress);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(PROGRESS_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-    //----------------------------------------------------------
-    // Local Methods
-    //----------------------------------------------------------
-
-    /**
-     * Returns the resulting multicast listener from adding listener-a
-     * and listener-b together.
-     * If listener-a is null, it returns listener-b;
-     * If listener-b is null, it returns listener-a
-     * If neither are null, then it creates and returns
-     *     a new Xj3DStatusMulticaster instance which chains a with b.
-     * @param a event listener-a
-     * @param b event listener-b
-     */
-    private static Xj3DStatusListener addInternal(Xj3DStatusListener a,
-                                                     Xj3DStatusListener b) {
-        if(a == null)
-            return b;
-
-        if(b == null)
-            return a;
-
-        return new StatusListenerMulticaster(a, b);
-    }
-
-    /**
-     * Returns the resulting multicast listener after removing the
-     * old listener from listener-l.
-     * If listener-l equals the old listener OR listener-l is null,
-     * returns null.
-     * Else if listener-l is an instance of Xj3DStatusMulticaster,
-     * then it removes the old listener from it.
-     * Else, returns listener l.
-     * @param l the listener being removed from
-     * @param oldl the listener being removed
-     */
-    private static Xj3DStatusListener removeInternal(Xj3DStatusListener l,
-                                                        Xj3DStatusListener oldl) {
-        if (l == oldl || l == null) {
-            return null;
-        } else if (l instanceof StatusListenerMulticaster) {
-            return ((StatusListenerMulticaster)l).remove(oldl);
-        } else {
-            return l;   // it's not here
-        }
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.scripting.external.sai;
+
+// External imports
+// none
+
+// Local imports
+import org.j3d.util.DefaultErrorReporter;
+import org.j3d.util.ErrorReporter;
+
+import org.xj3d.sai.Xj3DStatusListener;
+
+/**
+ * A class which implements efficient and thread-safe multi-cast event
+ * dispatching for the events defined in this package.
+ * <p>
+ *
+ * This class will manage an immutable structure consisting of a chain of
+ * event listeners and will dispatch events to those listeners.  Because
+ * the structure is immutable, it is safe to use this API to add/remove
+ * listeners during the process of an event dispatch operation.
+ * <p>
+ *
+ * An example of how this class could be used to implement a new
+ * component which fires "action" events:
+ *
+ * <pre><code>
+ * public myComponent extends Component {
+ *   Xj3DStatusListener listener = null;
+ *
+ *   public void addNodeListener(Xj3DStatusListener l) {
+ *     listener = StatusListenerMulticaster.add(listener, l);
+ *   }
+ *
+ *   public void removeNodeListener(Xj3DStatusListener l) {
+ *     listener = StatusListenerMulticaster.remove(listener, l);
+ *   }
+ *
+ *   public void browerChanged(Xj3DStatusEvent evt) {
+ *     if(listener != null) {
+ *       listener.browserChanged(evt);
+ *   }
+ * }
+ * </code></pre>
+ *
+ * @author  Justin Couch
+ * @version $Revision: 1.1 $
+ */
+class StatusListenerMulticaster
+    implements Xj3DStatusListener {
+
+    /** Error message when the user code barfs */
+    private static final String STATUS_ERROR_MSG =
+        "Error sending status message change updates: ";
+
+    /** Error message when the user code barfs */
+    private static final String FPS_ERROR_MSG =
+        "Error sending framerate updates: ";
+
+    /** Error message when the user code barfs */
+    private static final String PROGRESS_ERROR_MSG =
+        "Error sending progress update message: ";
+
+    /** Default error message when sending the error message fails */
+    private static final String DEFAULT_ERR_MSG =
+        "Unknown error sending browser change event: ";
+
+    /** The node listeners in use by this class */
+    private final Xj3DStatusListener a;
+
+    /** The node listeners in use by this class */
+    private final Xj3DStatusListener b;
+
+    /** Reporter instance for handing out errors */
+    private static ErrorReporter errorReporter =
+        DefaultErrorReporter.getDefaultReporter();
+
+    /**
+     * Creates an event multicaster instance which chains listener-a
+     * with listener-b. Input parameters <code>a</code> and <code>b</code>
+     * should not be <code>null</code>, though implementations may vary in
+     * choosing whether or not to throw <code>NullPointerException</code>
+     * in that case.
+     * @param a listener-a
+     * @param b listener-b
+     */
+    StatusListenerMulticaster(Xj3DStatusListener a, Xj3DStatusListener b) {
+        this.a = a;
+        this.b = b;
+    }
+
+    /**
+     * Removes a listener from this multicaster and returns the
+     * resulting multicast listener.
+     * @param oldl the listener to be removed
+     */
+    Xj3DStatusListener remove(Xj3DStatusListener oldl) {
+
+        if(oldl == a)
+            return b;
+
+        if(oldl == b)
+            return a;
+
+        Xj3DStatusListener a2 = removeInternal(a, oldl);
+        Xj3DStatusListener b2 = removeInternal(b, oldl);
+
+        if (a2 == a && b2 == b) {
+            return this;  // it's not here
+        }
+
+        return addInternal(a2, b2);
+    }
+
+    /**
+     * Register an error reporter with the engine so that any errors generated
+     * by the loading of script code can be reported in a nice, pretty fashion.
+     * Setting a value of null will clear the currently set reporter. If one
+     * is already set, the new value replaces the old.
+     *
+     * @param reporter The instance to use or null
+     */
+    static void setErrorReporter(ErrorReporter reporter) {
+        errorReporter = reporter;
+
+        // Reset the default only if we are not shutting down the system.
+        if(reporter == null)
+            errorReporter = DefaultErrorReporter.getDefaultReporter();
+    }
+
+    /**
+     * Adds input-method-listener-a with input-method-listener-b and
+     * returns the resulting multicast listener.
+     * @param a input-method-listener-a
+     * @param b input-method-listener-b
+     */
+    static Xj3DStatusListener add(Xj3DStatusListener a, Xj3DStatusListener b) {
+        return addInternal(a, b);
+    }
+
+    /**
+     * Removes the old component-listener from component-listener-l and
+     * returns the resulting multicast listener.
+     * @param l component-listener-l
+     * @param oldl the component-listener being removed
+     */
+    static Xj3DStatusListener remove(Xj3DStatusListener l, Xj3DStatusListener oldl) {
+        return removeInternal(l, oldl);
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by Xj3DStatusListener
+    //----------------------------------------------------------
+
+    /**
+     * Notification that a single line status message has changed to the new
+     * string. A null string means to clear the currently displayed message.
+     *
+     * @param msg The new message string to display for the status
+     */
+    @Override
+    public void updateStatusMessage(String msg) {
+        try {
+            a.updateStatusMessage(msg);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(STATUS_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.updateStatusMessage(msg);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(STATUS_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+
+    /**
+     * Notification that the calculated frames per second has changed to this
+     * new value. It is expected that this is called frequently.
+     */
+    @Override
+    public void updateFramesPerSecond(float fps) {
+        try {
+            a.updateFramesPerSecond(fps);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(FPS_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.updateFramesPerSecond(fps);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(FPS_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+
+    /**
+     * Notification of a progress update. There may be several items in
+     * progression at once (eg multithreaded texture and scripting loading)
+     * so implementers should work appropriately for this situation. To keep
+     * this aligned, each item that is reporting progress will have a unique
+     * ID string (for this session) associated with it so you can keep track
+     * of the multiples. Once 100% has been reached you can assume that the
+     * tracking is complete for that object.
+     *
+     * @param id A unique ID string for the given item
+     * @param msg A message to accompany the update
+     * @param perc A percentage from 0-100 of the progress completion
+     */
+    @Override
+    public void progressUpdate(String id, String msg, float perc) {
+
+        try {
+            a.progressUpdate(id, msg, perc);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(PROGRESS_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.progressUpdate(id, msg, perc);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(PROGRESS_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+
+    @Override
+	public void loadUpdate(int numInProgress) {
+
+        try {
+            a.loadUpdate(numInProgress);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(PROGRESS_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.loadUpdate(numInProgress);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(PROGRESS_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+    //----------------------------------------------------------
+    // Local Methods
+    //----------------------------------------------------------
+
+    /**
+     * Returns the resulting multicast listener from adding listener-a
+     * and listener-b together.
+     * If listener-a is null, it returns listener-b;
+     * If listener-b is null, it returns listener-a
+     * If neither are null, then it creates and returns
+     *     a new Xj3DStatusMulticaster instance which chains a with b.
+     * @param a event listener-a
+     * @param b event listener-b
+     */
+    private static Xj3DStatusListener addInternal(Xj3DStatusListener a,
+                                                     Xj3DStatusListener b) {
+        if(a == null)
+            return b;
+
+        if(b == null)
+            return a;
+
+        return new StatusListenerMulticaster(a, b);
+    }
+
+    /**
+     * Returns the resulting multicast listener after removing the
+     * old listener from listener-l.
+     * If listener-l equals the old listener OR listener-l is null,
+     * returns null.
+     * Else if listener-l is an instance of Xj3DStatusMulticaster,
+     * then it removes the old listener from it.
+     * Else, returns listener l.
+     * @param l the listener being removed from
+     * @param oldl the listener being removed
+     */
+    private static Xj3DStatusListener removeInternal(Xj3DStatusListener l,
+                                                        Xj3DStatusListener oldl) {
+        if (l == oldl || l == null) {
+            return null;
+        } else if (l instanceof StatusListenerMulticaster) {
+            return ((StatusListenerMulticaster)l).remove(oldl);
+        } else {
+            return l;   // it's not here
+        }
+    }
+}
diff --git a/src/java/org/web3d/vrml/scripting/sai/BaseExecutionContext.java b/src/java/org/web3d/vrml/scripting/sai/BaseExecutionContext.java
index 0becafcb19624f94b56fab5be67dc52deae3b90a..56f1484ff40965e2d282c8e5c97fc367379064e4 100644
--- a/src/java/org/web3d/vrml/scripting/sai/BaseExecutionContext.java
+++ b/src/java/org/web3d/vrml/scripting/sai/BaseExecutionContext.java
@@ -41,6 +41,7 @@ import org.xj3d.core.eventmodel.RouteManager;
 /**
  * X3DExecutionContext implementation that is used for Protos and the base
  * of a X3DScene.
+ *  <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.26 $
diff --git a/src/java/org/web3d/vrml/scripting/sai/BaseNodeFactory.java b/src/java/org/web3d/vrml/scripting/sai/BaseNodeFactory.java
index 5fb1a69613ad274565fee56061f949a984006b22..2e0398d8a0a6b7ce9c4a1e9141bbc9def5fa9b43 100644
--- a/src/java/org/web3d/vrml/scripting/sai/BaseNodeFactory.java
+++ b/src/java/org/web3d/vrml/scripting/sai/BaseNodeFactory.java
@@ -1,39 +1,39 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2007
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.scripting.sai;
-
-// External imports
-// none
-
-// Local imports
-import org.web3d.vrml.nodes.VRMLNodeType;
-
-import org.web3d.x3d.sai.X3DNode;
-
-/**
- * Defines the requirements of the node wrapper factory.
- *
- * @author Rex Melton
- * @version $Revision: 1.1 $
- */
-public interface BaseNodeFactory {
-
-    /**
-     * Given the argument VRMLNodeType, create and return a corresponding
-     * BaseNode instance.
-     *
-     * @param vrmlNode the node to wrap in a BaseNode instance
-     * @return The BaseNode instance
-     */
-    X3DNode getBaseNode(VRMLNodeType vrmlNode);
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2007
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.scripting.sai;
+
+// External imports
+// none
+
+// Local imports
+import org.web3d.vrml.nodes.VRMLNodeType;
+
+import org.web3d.x3d.sai.X3DNode;
+
+/**
+ * Defines the requirements of the node wrapper factory.
+ *
+ * @author Rex Melton
+ * @version $Revision: 1.1 $
+ */
+public interface BaseNodeFactory {
+
+    /**
+     * Given the argument VRMLNodeType, create and return a corresponding
+     * BaseNode instance.
+     *
+     * @param vrmlNode the node to wrap in a BaseNode instance
+     * @return The BaseNode instance
+     */
+    X3DNode getBaseNode(VRMLNodeType vrmlNode);
+}
diff --git a/src/java/org/web3d/vrml/scripting/sai/FieldListenerMulticaster.java b/src/java/org/web3d/vrml/scripting/sai/FieldListenerMulticaster.java
index edcb9b57e04d0674030af3db91cec6db3fb8b02d..7af92d98e721f4a1e84c3b52573193cb9a092940 100644
--- a/src/java/org/web3d/vrml/scripting/sai/FieldListenerMulticaster.java
+++ b/src/java/org/web3d/vrml/scripting/sai/FieldListenerMulticaster.java
@@ -1,189 +1,189 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2005
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.scripting.sai;
-
-// External imports
-// None
-
-// Local imports
-import org.web3d.x3d.sai.X3DFieldEvent;
-import org.web3d.x3d.sai.X3DFieldEventListener;
-
-/**
- * A class which implements efficient and thread-safe multi-cast event
- * dispatching for the events defined in this package.
- *  <p>
- *
- * This class will manage an immutable structure consisting of a chain of
- * event listeners and will dispatch events to those listeners.  Because
- * the structure is immutable, it is safe to use this API to add/remove
- * listeners during the process of an event dispatch operation.
- *  <p>
- *
- * An example of how this class could be used to implement a new
- * component which fires "action" events:
- *
- *  <pre><code>
- * public myComponent extends Component {
- *   X3DFieldEventListener nodeListener = null;
- *
- *   public void addFieldListener(X3DFieldEventListener l) {
- *     nodeListener = FieldListenerMulticaster.add(nodeListener, l);
- *   }
- *
- *   public void removeFieldListener(X3DFieldEventListener l) {
- *     nodeListener = FieldListenerMulticaster.remove(nodeListener, l);
- *   }
- *
- *   public void fireFieldChanged(int index) {
- *     if(nodeListener != null) {
- *       nodeListener.fieldChanged(index);
- *   }
- * }
- * </code> </pre>
- *
- * @author  Justin Couch
- * @version 0.7 (27 August 1999)
- */
-public class FieldListenerMulticaster implements X3DFieldEventListener {
-
-    /** The node listeners in use by this class */
-    final X3DFieldEventListener a, b;
-
-    /**
-     * Creates an event multicaster instance which chains listener-a
-     * with listener-b. Input parameters <code>a</code> and <code>b</code>
-     * should not be <code>null</code>, though implementations may vary in
-     * choosing whether or not to throw <code>NullPointerException</code>
-     * in that case.
-     * @param a listener-a
-     * @param b listener-b
-     */
-    public FieldListenerMulticaster(X3DFieldEventListener a, X3DFieldEventListener b) {
-        this.a = a;
-        this.b = b;
-    }
-
-    /**
-     * Removes a listener from this multicaster and returns the
-     * resulting multicast listener.
-     * @param oldl the listener to be removed
-     * @return 
-     */
-    public X3DFieldEventListener remove(X3DFieldEventListener oldl) {
-
-        if(oldl == a)
-            return b;
-
-        if(oldl == b)
-            return a;
-
-        X3DFieldEventListener a2 = removeInternal(a, oldl);
-        X3DFieldEventListener b2 = removeInternal(b, oldl);
-
-        if (a2 == a && b2 == b) {
-            return this;  // it's not here
-        }
-
-        return addInternal(a2, b2);
-    }
-
-    /**
-     * Adds input-method-listener-a with input-method-listener-b and
-     * returns the resulting multicast listener.
-     * @param a input-method-listener-a
-     * @param b input-method-listener-b
-     * @return 
-     */
-    public static X3DFieldEventListener add(X3DFieldEventListener a,
-                                            X3DFieldEventListener b) {
-        return addInternal(a, b);
-    }
-
-    /**
-     * Removes the old component-listener from component-listener-l and
-     * returns the resulting multicast listener.
-     * @param l component-listener-l
-     * @param oldl the component-listener being removed
-     * @return 
-     */
-    public static X3DFieldEventListener remove(X3DFieldEventListener l,
-                                               X3DFieldEventListener oldl) {
-        return removeInternal(l, oldl);
-    }
-
-    /**
-     * Send a field change notification.
-     *
-     * @param evt An event describing what happened
-     */
-    @Override
-    public void readableFieldChanged(X3DFieldEvent evt) {
-        try {
-            a.readableFieldChanged(evt);
-        } catch(Throwable th) {
-            System.err.println("Error sending connection event to: " + a);
-            th.printStackTrace(System.err);
-        }
-
-        try {
-            b.readableFieldChanged(evt);
-        } catch(Throwable th) {
-            System.err.println("Error sending connection event to: " + b);
-            th.printStackTrace(System.err);
-        }
-    }
-
-    /**
-     * Returns the resulting multicast listener from adding listener-a
-     * and listener-b together.
-     * If listener-a is null, it returns listener-b;
-     * If listener-b is null, it returns listener-a
-     * If neither are null, then it creates and returns
-     * a new FieldListenerMulticaster instance which chains a with b.
-     * @param a event listener-a
-     * @param b event listener-b
-     */
-    private static X3DFieldEventListener addInternal(X3DFieldEventListener a,
-                                                     X3DFieldEventListener b) {
-        if(a == null)
-            return b;
-
-        if(b == null)
-            return a;
-
-        return new FieldListenerMulticaster(a, b);
-    }
-
-    /**
-     * Returns the resulting multicast listener after removing the
-     * old listener from listener-l.
-     * If listener-l equals the old listener OR listener-l is null,
-     * returns null.
-     * Else if listener-l is an instance of FieldListenerMulticaster,
-     * then it removes the old listener from it.
-     * Else, returns listener l.
-     * @param l the listener being removed from
-     * @param oldl the listener being removed
-     */
-    private static X3DFieldEventListener removeInternal(X3DFieldEventListener l,
-                                 X3DFieldEventListener oldl) {
-        if (l == oldl || l == null) {
-            return null;
-        } else if (l instanceof FieldListenerMulticaster) {
-            return ((FieldListenerMulticaster)l).remove(oldl);
-        } else {
-            return l;   // it's not here
-        }
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001 - 2005
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.scripting.sai;
+
+// External imports
+// None
+
+// Local imports
+import org.web3d.x3d.sai.X3DFieldEvent;
+import org.web3d.x3d.sai.X3DFieldEventListener;
+
+/**
+ * A class which implements efficient and thread-safe multi-cast event
+ * dispatching for the events defined in this package.
+ *  <p>
+ *
+ * This class will manage an immutable structure consisting of a chain of
+ * event listeners and will dispatch events to those listeners.  Because
+ * the structure is immutable, it is safe to use this API to add/remove
+ * listeners during the process of an event dispatch operation.
+ *  <p>
+ *
+ * An example of how this class could be used to implement a new
+ * component which fires "action" events:
+ *
+ *  <pre><code>
+ * public myComponent extends Component {
+ *   X3DFieldEventListener nodeListener = null;
+ *
+ *   public void addFieldListener(X3DFieldEventListener l) {
+ *     nodeListener = FieldListenerMulticaster.add(nodeListener, l);
+ *   }
+ *
+ *   public void removeFieldListener(X3DFieldEventListener l) {
+ *     nodeListener = FieldListenerMulticaster.remove(nodeListener, l);
+ *   }
+ *
+ *   public void fireFieldChanged(int index) {
+ *     if(nodeListener != null) {
+ *       nodeListener.fieldChanged(index);
+ *   }
+ * }
+ * </code> </pre>
+ *
+ * @author  Justin Couch
+ * @version 0.7 (27 August 1999)
+ */
+public class FieldListenerMulticaster implements X3DFieldEventListener {
+
+    /** The node listeners in use by this class */
+    final X3DFieldEventListener a, b;
+
+    /**
+     * Creates an event multicaster instance which chains listener-a
+     * with listener-b. Input parameters <code>a</code> and <code>b</code>
+     * should not be <code>null</code>, though implementations may vary in
+     * choosing whether or not to throw <code>NullPointerException</code>
+     * in that case.
+     * @param a listener-a
+     * @param b listener-b
+     */
+    public FieldListenerMulticaster(X3DFieldEventListener a, X3DFieldEventListener b) {
+        this.a = a;
+        this.b = b;
+    }
+
+    /**
+     * Removes a listener from this multicaster and returns the
+     * resulting multicast listener.
+     * @param oldl the listener to be removed
+     * @return 
+     */
+    public X3DFieldEventListener remove(X3DFieldEventListener oldl) {
+
+        if(oldl == a)
+            return b;
+
+        if(oldl == b)
+            return a;
+
+        X3DFieldEventListener a2 = removeInternal(a, oldl);
+        X3DFieldEventListener b2 = removeInternal(b, oldl);
+
+        if (a2 == a && b2 == b) {
+            return this;  // it's not here
+        }
+
+        return addInternal(a2, b2);
+    }
+
+    /**
+     * Adds input-method-listener-a with input-method-listener-b and
+     * returns the resulting multicast listener.
+     * @param a input-method-listener-a
+     * @param b input-method-listener-b
+     * @return 
+     */
+    public static X3DFieldEventListener add(X3DFieldEventListener a,
+                                            X3DFieldEventListener b) {
+        return addInternal(a, b);
+    }
+
+    /**
+     * Removes the old component-listener from component-listener-l and
+     * returns the resulting multicast listener.
+     * @param l component-listener-l
+     * @param oldl the component-listener being removed
+     * @return 
+     */
+    public static X3DFieldEventListener remove(X3DFieldEventListener l,
+                                               X3DFieldEventListener oldl) {
+        return removeInternal(l, oldl);
+    }
+
+    /**
+     * Send a field change notification.
+     *
+     * @param evt An event describing what happened
+     */
+    @Override
+    public void readableFieldChanged(X3DFieldEvent evt) {
+        try {
+            a.readableFieldChanged(evt);
+        } catch(Throwable th) {
+            System.err.println("Error sending connection event to: " + a);
+            th.printStackTrace(System.err);
+        }
+
+        try {
+            b.readableFieldChanged(evt);
+        } catch(Throwable th) {
+            System.err.println("Error sending connection event to: " + b);
+            th.printStackTrace(System.err);
+        }
+    }
+
+    /**
+     * Returns the resulting multicast listener from adding listener-a
+     * and listener-b together.
+     * If listener-a is null, it returns listener-b;
+     * If listener-b is null, it returns listener-a
+     * If neither are null, then it creates and returns
+     * a new FieldListenerMulticaster instance which chains a with b.
+     * @param a event listener-a
+     * @param b event listener-b
+     */
+    private static X3DFieldEventListener addInternal(X3DFieldEventListener a,
+                                                     X3DFieldEventListener b) {
+        if(a == null)
+            return b;
+
+        if(b == null)
+            return a;
+
+        return new FieldListenerMulticaster(a, b);
+    }
+
+    /**
+     * Returns the resulting multicast listener after removing the
+     * old listener from listener-l.
+     * If listener-l equals the old listener OR listener-l is null,
+     * returns null.
+     * Else if listener-l is an instance of FieldListenerMulticaster,
+     * then it removes the old listener from it.
+     * Else, returns listener l.
+     * @param l the listener being removed from
+     * @param oldl the listener being removed
+     */
+    private static X3DFieldEventListener removeInternal(X3DFieldEventListener l,
+                                 X3DFieldEventListener oldl) {
+        if (l == oldl || l == null) {
+            return null;
+        } else if (l instanceof FieldListenerMulticaster) {
+            return ((FieldListenerMulticaster)l).remove(oldl);
+        } else {
+            return l;   // it's not here
+        }
+    }
+}
diff --git a/src/java/org/web3d/vrml/scripting/sai/SAIFieldDefinition.java b/src/java/org/web3d/vrml/scripting/sai/SAIFieldDefinition.java
index e18d4e2c7dd35a1340bb1aed1c97f12fed1e3a9b..f3f78adf724c207cdf7f154cd4e69ddd3db09f1b 100644
--- a/src/java/org/web3d/vrml/scripting/sai/SAIFieldDefinition.java
+++ b/src/java/org/web3d/vrml/scripting/sai/SAIFieldDefinition.java
@@ -1,153 +1,153 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.scripting.sai;
-
-// External imports
-// None
-
-// Local imports
-import org.j3d.util.IntHashMap;
-import org.web3d.vrml.lang.FieldConstants;
-import org.web3d.x3d.sai.X3DFieldDefinition;
-import org.web3d.x3d.sai.X3DFieldTypes;
-
-import org.xj3d.sai.X3DFieldTypeMapper;
-
-/**
- * Implementation of a node's field definition.
- * <p>
- *
- * @author Justin Couch
- * @version $Revision: 1.2 $
- */
-class SAIFieldDefinition implements X3DFieldDefinition {
-
-    /** The name of the field */
-    private final String name;
-
-    /** The access type the field uses */
-    private final int accessType;
-
-    /** The data type of the field */
-    private final int dataType;
-
-    /** The data type of the field */
-    private final String typeName;
-
-    /**
-     * Construct a new field definition based on the internal Xj3D data type
-     * from the FieldConstants class. Designed to be directly compatible with
-     * VRMLFieldDeclaration.
-     *
-     * @param name The name of the field
-     * @param access The access type identifier
-     * @param type The data type identifier
-     */
-    SAIFieldDefinition(String name, int access, int type) {
-        this.name = name;
-
-        switch(access) {
-            case FieldConstants.EVENTIN:
-                accessType = X3DFieldTypes.INPUT_ONLY;
-                break;
-
-            case FieldConstants.EVENTOUT:
-                accessType = X3DFieldTypes.OUTPUT_ONLY;
-                break;
-
-            case FieldConstants.EXPOSEDFIELD:
-                accessType = X3DFieldTypes.INPUT_OUTPUT;
-                break;
-
-            case FieldConstants.FIELD:
-                accessType = X3DFieldTypes.INITIALIZE_ONLY;
-                break;
-
-            default:
-                accessType = -1;
-        }
-
-        X3DFieldTypeMapper typeMapper = X3DFieldTypeMapper.getInstance( );
-        
-        dataType=typeMapper.getX3DFieldType( type );
-        typeName=typeMapper.getTypeName( type );
-    }
-
-    /**
-     * Get the name of this field. This will be something like "children"
-     * or "translation". If the field is an exposed field then the name
-     * give will be the base name without any <i>set_</i> or <i>_changed</i>
-     * added to the name, regardless of how the initial field was fetched.
-     *
-     * @return The name of this field
-     */
-    @Override
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * Get the access type of the field. This will be one of field,
-     * exposedField, eventIn or eventOut constants described in the
-     * X3DFieldTypes interface.
-     *
-     * @return The access type of this node
-     * @see X3DFieldTypes
-     */
-    @Override
-    public int getAccessType() {
-        return accessType;
-    }
-
-    /**
-     * Get the field type. This string represents the field type such as
-     * MFNode, SFInt32. The defintion of the int values returned is
-     * described in the X3DFieldType interface.
-     *
-     * @return A constant describing the field type
-     * @see X3DFieldTypes
-     */
-    @Override
-    public int getFieldType() {
-        return dataType;
-    }
-
-    /**
-     * Get the field type. This string represents the field type such as
-     * MFNode, SFInt32. A string is used to allow full extensibility.
-     *
-     * @return A string describing the field type
-     */
-    @Override
-    public String getFieldTypeString() {
-        return( typeName );
-    }
-
-    /**
-     * Check this object for comparison to another
-     *
-     * @param obj The object to compare it to
-     * @return true if these represent exactly the same field type
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if(!(obj instanceof SAIFieldDefinition))
-            return false;
-
-        SAIFieldDefinition o = (SAIFieldDefinition)obj;
-
-        return name.equals(o.name) &&
-               o.dataType == dataType &&
-               o.accessType == accessType;
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.scripting.sai;
+
+// External imports
+// None
+
+// Local imports
+import org.j3d.util.IntHashMap;
+import org.web3d.vrml.lang.FieldConstants;
+import org.web3d.x3d.sai.X3DFieldDefinition;
+import org.web3d.x3d.sai.X3DFieldTypes;
+
+import org.xj3d.sai.X3DFieldTypeMapper;
+
+/**
+ * Implementation of a node's field definition.
+ * <p>
+ *
+ * @author Justin Couch
+ * @version $Revision: 1.2 $
+ */
+class SAIFieldDefinition implements X3DFieldDefinition {
+
+    /** The name of the field */
+    private final String name;
+
+    /** The access type the field uses */
+    private final int accessType;
+
+    /** The data type of the field */
+    private final int dataType;
+
+    /** The data type of the field */
+    private final String typeName;
+
+    /**
+     * Construct a new field definition based on the internal Xj3D data type
+     * from the FieldConstants class. Designed to be directly compatible with
+     * VRMLFieldDeclaration.
+     *
+     * @param name The name of the field
+     * @param access The access type identifier
+     * @param type The data type identifier
+     */
+    SAIFieldDefinition(String name, int access, int type) {
+        this.name = name;
+
+        switch(access) {
+            case FieldConstants.EVENTIN:
+                accessType = X3DFieldTypes.INPUT_ONLY;
+                break;
+
+            case FieldConstants.EVENTOUT:
+                accessType = X3DFieldTypes.OUTPUT_ONLY;
+                break;
+
+            case FieldConstants.EXPOSEDFIELD:
+                accessType = X3DFieldTypes.INPUT_OUTPUT;
+                break;
+
+            case FieldConstants.FIELD:
+                accessType = X3DFieldTypes.INITIALIZE_ONLY;
+                break;
+
+            default:
+                accessType = -1;
+        }
+
+        X3DFieldTypeMapper typeMapper = X3DFieldTypeMapper.getInstance( );
+        
+        dataType=typeMapper.getX3DFieldType( type );
+        typeName=typeMapper.getTypeName( type );
+    }
+
+    /**
+     * Get the name of this field. This will be something like "children"
+     * or "translation". If the field is an exposed field then the name
+     * give will be the base name without any <i>set_</i> or <i>_changed</i>
+     * added to the name, regardless of how the initial field was fetched.
+     *
+     * @return The name of this field
+     */
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Get the access type of the field. This will be one of field,
+     * exposedField, eventIn or eventOut constants described in the
+     * X3DFieldTypes interface.
+     *
+     * @return The access type of this node
+     * @see X3DFieldTypes
+     */
+    @Override
+    public int getAccessType() {
+        return accessType;
+    }
+
+    /**
+     * Get the field type. This string represents the field type such as
+     * MFNode, SFInt32. The defintion of the int values returned is
+     * described in the X3DFieldType interface.
+     *
+     * @return A constant describing the field type
+     * @see X3DFieldTypes
+     */
+    @Override
+    public int getFieldType() {
+        return dataType;
+    }
+
+    /**
+     * Get the field type. This string represents the field type such as
+     * MFNode, SFInt32. A string is used to allow full extensibility.
+     *
+     * @return A string describing the field type
+     */
+    @Override
+    public String getFieldTypeString() {
+        return( typeName );
+    }
+
+    /**
+     * Check this object for comparison to another
+     *
+     * @param obj The object to compare it to
+     * @return true if these represent exactly the same field type
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if(!(obj instanceof SAIFieldDefinition))
+            return false;
+
+        SAIFieldDefinition o = (SAIFieldDefinition)obj;
+
+        return name.equals(o.name) &&
+               o.dataType == dataType &&
+               o.accessType == accessType;
+    }
+}
diff --git a/src/java/org/web3d/vrml/util/KeySensorDevice.java b/src/java/org/web3d/vrml/util/KeySensorDevice.java
index d408c7e3a35ce9b372ca453d16b412d67e2594f3..807acd27611b6ecebec1b41ca9f5d38d8addff0b 100644
--- a/src/java/org/web3d/vrml/util/KeySensorDevice.java
+++ b/src/java/org/web3d/vrml/util/KeySensorDevice.java
@@ -1,35 +1,35 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.util;
-
-// External imports - NONE
-// Local imports - NONE
-
-/**
- * Defines the requirements for retrieving an ordered set of key events.
- *
- * @author Rex Melton
- * @version $Revision: 1.1 $
- */
-public interface KeySensorDevice {
-    
-    /**
-     * Return the ordered set of key events in the argument KeySequence
-     * object that have occurred since the previous call to this method.
-     *
-     * @param seq - The KeySequence object to initialize with the set
-     * of key events
-     */
-    void getEvents( KeySequence seq );
-}
-
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.util;
+
+// External imports - NONE
+// Local imports - NONE
+
+/**
+ * Defines the requirements for retrieving an ordered set of key events.
+ *
+ * @author Rex Melton
+ * @version $Revision: 1.1 $
+ */
+public interface KeySensorDevice {
+    
+    /**
+     * Return the ordered set of key events in the argument KeySequence
+     * object that have occurred since the previous call to this method.
+     *
+     * @param seq - The KeySequence object to initialize with the set
+     * of key events
+     */
+    void getEvents( KeySequence seq );
+}
+
diff --git a/src/java/org/web3d/vrml/util/KeySequence.java b/src/java/org/web3d/vrml/util/KeySequence.java
index 74e7a7bb0dc70d8560e9ddf83ff291b8fee7d5c4..00e995aedeb0dfdfb1c372df0a74a56eeb3e4adf 100644
--- a/src/java/org/web3d/vrml/util/KeySequence.java
+++ b/src/java/org/web3d/vrml/util/KeySequence.java
@@ -1,163 +1,163 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.util;
-
-// External imports - NONE
-
-// Local imports - NONE
-
-/**
- * A sequence, much like the collections List interface, specifically
- * designed for queuing up sequences of Xj3DKeyEvents between
- * rendering frames.
- * <p>
- * The methods involved with loading a sequence or manipulating it's
- * underlying array of events are synchronized.
- *
- * @author Rex Melton
- * @version $Revision: 1.1 $
- */
-public class KeySequence {
-
-    /** Static initial array size. */
-    private static final int DEFAULT_INITIAL_CAPACITY = 128;
-
-    /** Increment size */
-    private static final int INCREMENT_SIZE = 16;
-
-    /** Mutex object for reading/writing the key events */
-    private final Object mutex;
-
-    /** The number of key events currently stored */
-    protected int index;
-
-    /** The array storing key events */
-    protected Xj3DKeyEvent[] eventArray;
-
-    /**
-     * Construct an instance with the default capacity.
-     */
-    public KeySequence( ) {
-        this( DEFAULT_INITIAL_CAPACITY );
-    }
-
-    /**
-     * Construct an instance with the specified initial capacity.
-     *
-     * @param initialCapacity - The initial holding capacity for events.
-     */
-    public KeySequence( int initialCapacity ) {
-        mutex = new Object( );
-        index = 0;
-        eventArray = new Xj3DKeyEvent[initialCapacity];
-    }
-
-    /**
-     * Return the key event at the specified index.
-     *
-     * @param i - The index of the event to return
-     * @return The event
-     * @throws IndexOutOfBoundsException - if i is out of range
-     * ( i &lt; 0 || i &gt;= size( ) ).
-     */
-    public Xj3DKeyEvent get( int i ) {
-        return( eventArray[i] );
-    }
-
-    /**
-     * Return the number of events in the sequence
-     *
-     * @return the number of events in the sequence
-     */
-    public int size( ) {
-        return( index );
-    }
-
-    /**
-     * Add the event to the end of the sequence
-     *
-     * @param evt - The event
-     */
-    public void add( Xj3DKeyEvent evt ) {
-        if ( index == eventArray.length ) {
-            ensureCapacity( index + INCREMENT_SIZE );
-        }
-        synchronized( mutex ) {
-            eventArray[index++] = evt;
-        }
-    }
-
-    /**
-     * Clear the sequence
-     */
-    public void clear( ) {
-        if ( index > 0 ) {
-            synchronized( mutex ) {
-                for ( int i = index - 1; i >= 0; i-- ) {
-                    eventArray[i] = null;
-                }
-                index = 0;
-            }
-        }
-    }
-
-    /**
-     * Move the current contents of this object into the argument sequence
-     * object. Any events currently in the argument sequence will be cleared.
-     * The argument sequence's capacity will be increased if it is
-     * insufficent to hold the complete set of events. At the end of the
-     * transfer, this object will be empty.
-     *
-     * @param seq - The KeySequence object to initialize
-     */
-    public void transfer( KeySequence seq ) {
-        seq.clear( );
-        if ( seq.eventArray.length < index ) {
-            seq.ensureCapacity( index );
-        }
-        if ( index > 0 ) {
-            synchronized( mutex ) {
-                for ( int i = index - 1; i >= 0; i-- ) {
-                    seq.eventArray[i] = eventArray[i];
-                    eventArray[i] = null;
-                }
-                seq.index = index;
-                index = 0;
-            }
-        }
-    }
-
-    /**
-     * Ensure that the capacity of this sequence is sufficient to
-     * contain the specified number of events.
-     *
-     * @param minCapacity the minimum number of events that this
-     * sequence must be able to hold.
-     */
-    public void ensureCapacity( int minCapacity ) {
-        int newCapacity = eventArray.length;
-        if ( newCapacity < minCapacity ) {
-            while ( newCapacity < minCapacity ) {
-                newCapacity += INCREMENT_SIZE;
-            }
-            synchronized( mutex ) {
-                Xj3DKeyEvent[] tmp = new Xj3DKeyEvent[newCapacity];
-                if ( index > 0 ) {
-                    System.arraycopy( eventArray, 0, tmp, 0, index );
-                }
-                eventArray = tmp;
-            }
-        }
-    }
-}
-
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.util;
+
+// External imports - NONE
+
+// Local imports - NONE
+
+/**
+ * A sequence, much like the collections List interface, specifically
+ * designed for queuing up sequences of Xj3DKeyEvents between
+ * rendering frames.
+ * <p>
+ * The methods involved with loading a sequence or manipulating it's
+ * underlying array of events are synchronized.
+ *
+ * @author Rex Melton
+ * @version $Revision: 1.1 $
+ */
+public class KeySequence {
+
+    /** Static initial array size. */
+    private static final int DEFAULT_INITIAL_CAPACITY = 128;
+
+    /** Increment size */
+    private static final int INCREMENT_SIZE = 16;
+
+    /** Mutex object for reading/writing the key events */
+    private final Object mutex;
+
+    /** The number of key events currently stored */
+    protected int index;
+
+    /** The array storing key events */
+    protected Xj3DKeyEvent[] eventArray;
+
+    /**
+     * Construct an instance with the default capacity.
+     */
+    public KeySequence( ) {
+        this( DEFAULT_INITIAL_CAPACITY );
+    }
+
+    /**
+     * Construct an instance with the specified initial capacity.
+     *
+     * @param initialCapacity - The initial holding capacity for events.
+     */
+    public KeySequence( int initialCapacity ) {
+        mutex = new Object( );
+        index = 0;
+        eventArray = new Xj3DKeyEvent[initialCapacity];
+    }
+
+    /**
+     * Return the key event at the specified index.
+     *
+     * @param i - The index of the event to return
+     * @return The event
+     * @throws IndexOutOfBoundsException - if i is out of range
+     * ( i &lt; 0 || i &gt;= size( ) ).
+     */
+    public Xj3DKeyEvent get( int i ) {
+        return( eventArray[i] );
+    }
+
+    /**
+     * Return the number of events in the sequence
+     *
+     * @return the number of events in the sequence
+     */
+    public int size( ) {
+        return( index );
+    }
+
+    /**
+     * Add the event to the end of the sequence
+     *
+     * @param evt - The event
+     */
+    public void add( Xj3DKeyEvent evt ) {
+        if ( index == eventArray.length ) {
+            ensureCapacity( index + INCREMENT_SIZE );
+        }
+        synchronized( mutex ) {
+            eventArray[index++] = evt;
+        }
+    }
+
+    /**
+     * Clear the sequence
+     */
+    public void clear( ) {
+        if ( index > 0 ) {
+            synchronized( mutex ) {
+                for ( int i = index - 1; i >= 0; i-- ) {
+                    eventArray[i] = null;
+                }
+                index = 0;
+            }
+        }
+    }
+
+    /**
+     * Move the current contents of this object into the argument sequence
+     * object. Any events currently in the argument sequence will be cleared.
+     * The argument sequence's capacity will be increased if it is
+     * insufficent to hold the complete set of events. At the end of the
+     * transfer, this object will be empty.
+     *
+     * @param seq - The KeySequence object to initialize
+     */
+    public void transfer( KeySequence seq ) {
+        seq.clear( );
+        if ( seq.eventArray.length < index ) {
+            seq.ensureCapacity( index );
+        }
+        if ( index > 0 ) {
+            synchronized( mutex ) {
+                for ( int i = index - 1; i >= 0; i-- ) {
+                    seq.eventArray[i] = eventArray[i];
+                    eventArray[i] = null;
+                }
+                seq.index = index;
+                index = 0;
+            }
+        }
+    }
+
+    /**
+     * Ensure that the capacity of this sequence is sufficient to
+     * contain the specified number of events.
+     *
+     * @param minCapacity the minimum number of events that this
+     * sequence must be able to hold.
+     */
+    public void ensureCapacity( int minCapacity ) {
+        int newCapacity = eventArray.length;
+        if ( newCapacity < minCapacity ) {
+            while ( newCapacity < minCapacity ) {
+                newCapacity += INCREMENT_SIZE;
+            }
+            synchronized( mutex ) {
+                Xj3DKeyEvent[] tmp = new Xj3DKeyEvent[newCapacity];
+                if ( index > 0 ) {
+                    System.arraycopy( eventArray, 0, tmp, 0, index );
+                }
+                eventArray = tmp;
+            }
+        }
+    }
+}
+
diff --git a/src/java/org/web3d/vrml/util/URLChecker.java b/src/java/org/web3d/vrml/util/URLChecker.java
index d0a4f40b05448585ffc879dd4852d5e4f2439eea..e48af45b0d4d1ee5525de34e68977f7f3418dc1e 100644
--- a/src/java/org/web3d/vrml/util/URLChecker.java
+++ b/src/java/org/web3d/vrml/util/URLChecker.java
@@ -15,11 +15,15 @@ package org.web3d.vrml.util;
 import java.io.File;
 import java.net.MalformedURLException;
 import java.util.StringTokenizer;
+
 import org.ietf.uri.URIUtils;
+
+// Application specific imports
 import org.j3d.util.ObjectArray;
 
 /**
  * A checker of URLs to update them and include a root URL if needed.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.12 $
@@ -55,7 +59,6 @@ public class URLChecker {
     /** Ensure that the proper URI scheme of file:/// is prepended to the
      * given url if missing, or incomplete from a local file source. Return URLs 
      * unchanged if the scheme is http:// or https://.
-     * 
      * @param url the url to prepend the proper URI scheme to 
      * @return a properly prepended URI scheme to a url
      */
diff --git a/src/java/org/web3d/vrml/util/Xj3DKeyCode.java b/src/java/org/web3d/vrml/util/Xj3DKeyCode.java
index 7cdc122fdcf7d3daaf81f6be07937798897de618..6bad276f54059819bce5add3926565bbf1be44a0 100644
--- a/src/java/org/web3d/vrml/util/Xj3DKeyCode.java
+++ b/src/java/org/web3d/vrml/util/Xj3DKeyCode.java
@@ -1,122 +1,122 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.util;
-
-// External imports - NONE
-// Local imports - NONE
-
-/**
- * The key code identifiers of the set of character and non-character
- * generating keys that are specifically identified by the X3D spec. 
- *
- * @author Rex Melton
- * @version $Revision: 1.1 $
- */
-public interface Xj3DKeyCode {
-    
-    //-----------------------------------------------------------------------
-    // Action keys, non-character generating - codes specifically defined
-    // by the X3D KeySensor spec
-    
-    /** The F1 key action code, defined by the X3D KeySensor spec */
-    public static final int ACTION_KEY_F1 = 1;
-    
-    /** The F2 key action code, defined by the X3D KeySensor spec */
-    public static final int ACTION_KEY_F2 = 2;
-    
-    /** The F3 key action code, defined by the X3D KeySensor spec */
-    public static final int ACTION_KEY_F3 = 3;
-    
-    /** The F4 key action code, defined by the X3D KeySensor spec */
-    public static final int ACTION_KEY_F4 = 4;
-    
-    /** The F5 key action code, defined by the X3D KeySensor spec */
-    public static final int ACTION_KEY_F5 = 5;
-    
-    /** The F6 key action code, defined by the X3D KeySensor spec */
-    public static final int ACTION_KEY_F6 = 6;
-    
-    /** The F7 key action code, defined by the X3D KeySensor spec */
-    public static final int ACTION_KEY_F7 = 7;
-    
-    /** The F8 key action code, defined by the X3D KeySensor spec */
-    public static final int ACTION_KEY_F8 = 8;
-    
-    /** The F9 key action code, defined by the X3D KeySensor spec */
-    public static final int ACTION_KEY_F9 = 9;
-    
-    /** The F10 key action code, defined by the X3D KeySensor spec */
-    public static final int ACTION_KEY_F10 = 10;
-    
-    /** The F11 key action code, defined by the X3D KeySensor spec */
-    public static final int ACTION_KEY_F11 = 11;
-    
-    /** The F12 key action code, defined by the X3D KeySensor spec */
-    public static final int ACTION_KEY_F12 = 12;
-    
-    /** The Home key action code, defined by the X3D KeySensor spec */
-    public static final int ACTION_KEY_HOME = 13;
-    
-    /** The End key action code, defined by the X3D KeySensor spec */
-    public static final int ACTION_KEY_END = 14;
-    
-    /** The Page Up key action code, defined by the X3D KeySensor spec */
-    public static final int ACTION_KEY_PGUP = 15;
-    
-    /** The Page Down key action code, defined by the X3D KeySensor spec */
-    public static final int ACTION_KEY_PGDN = 16;
-    
-    /** The Up Arrow key action code, defined by the X3D KeySensor spec */
-    public static final int ACTION_KEY_UP = 17;
-    
-    /** The Down Arrow key action code, defined by the X3D KeySensor spec */
-    public static final int ACTION_KEY_DOWN = 18;
-    
-    /** The Left Arrow key action code, defined by the X3D KeySensor spec */
-    public static final int ACTION_KEY_LEFT = 19;
-    
-    /** The Right Arrow key action code, defined by the X3D KeySensor spec */
-    public static final int ACTION_KEY_RIGHT = 20;
-    
-    //-----------------------------------------------------------------------
-    // Modifier keys - non-character generating - codes arbitrarily defined
-    
-    /** The modifier key code base identifier */
-    public static final int MODIFIER_KEY_BASE = 0x100;
-    
-    /** The Alt key modifier code */
-    public static final int MODIFIER_KEY_ALT = MODIFIER_KEY_BASE + 0;
-    
-    /** The Control key modifier code */
-    public static final int MODIFIER_KEY_CONTROL = MODIFIER_KEY_BASE + 1;
-    
-    /** The Shift key modifier code */
-    public static final int MODIFIER_KEY_SHIFT = MODIFIER_KEY_BASE + 2;
-    
-    //-----------------------------------------------------------------------
-    // Character keys - character generating - codes arbitrarily defined
-    
-    /** The constant defining that the character is the Enter key */
-    public static final int CHAR_KEY_ENTER = '\n';
-    
-    /** The constant defining that the character is the Backspace key */
-    public static final int CHAR_KEY_BACKSPACE = '\b';
-    
-    //-----------------------------------------------------------------------
-    // Null key code - arbitrarily defined
-    
-    /** The constant defining that no action or modifier code is associated
-     *  with the key */
-    public static final int KEY_CODE_UNDEFINED = 0xFFFF;
-}
-
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.util;
+
+// External imports - NONE
+// Local imports - NONE
+
+/**
+ * The key code identifiers of the set of character and non-character
+ * generating keys that are specifically identified by the X3D spec. 
+ *
+ * @author Rex Melton
+ * @version $Revision: 1.1 $
+ */
+public interface Xj3DKeyCode {
+    
+    //-----------------------------------------------------------------------
+    // Action keys, non-character generating - codes specifically defined
+    // by the X3D KeySensor spec
+    
+    /** The F1 key action code, defined by the X3D KeySensor spec */
+    public static final int ACTION_KEY_F1 = 1;
+    
+    /** The F2 key action code, defined by the X3D KeySensor spec */
+    public static final int ACTION_KEY_F2 = 2;
+    
+    /** The F3 key action code, defined by the X3D KeySensor spec */
+    public static final int ACTION_KEY_F3 = 3;
+    
+    /** The F4 key action code, defined by the X3D KeySensor spec */
+    public static final int ACTION_KEY_F4 = 4;
+    
+    /** The F5 key action code, defined by the X3D KeySensor spec */
+    public static final int ACTION_KEY_F5 = 5;
+    
+    /** The F6 key action code, defined by the X3D KeySensor spec */
+    public static final int ACTION_KEY_F6 = 6;
+    
+    /** The F7 key action code, defined by the X3D KeySensor spec */
+    public static final int ACTION_KEY_F7 = 7;
+    
+    /** The F8 key action code, defined by the X3D KeySensor spec */
+    public static final int ACTION_KEY_F8 = 8;
+    
+    /** The F9 key action code, defined by the X3D KeySensor spec */
+    public static final int ACTION_KEY_F9 = 9;
+    
+    /** The F10 key action code, defined by the X3D KeySensor spec */
+    public static final int ACTION_KEY_F10 = 10;
+    
+    /** The F11 key action code, defined by the X3D KeySensor spec */
+    public static final int ACTION_KEY_F11 = 11;
+    
+    /** The F12 key action code, defined by the X3D KeySensor spec */
+    public static final int ACTION_KEY_F12 = 12;
+    
+    /** The Home key action code, defined by the X3D KeySensor spec */
+    public static final int ACTION_KEY_HOME = 13;
+    
+    /** The End key action code, defined by the X3D KeySensor spec */
+    public static final int ACTION_KEY_END = 14;
+    
+    /** The Page Up key action code, defined by the X3D KeySensor spec */
+    public static final int ACTION_KEY_PGUP = 15;
+    
+    /** The Page Down key action code, defined by the X3D KeySensor spec */
+    public static final int ACTION_KEY_PGDN = 16;
+    
+    /** The Up Arrow key action code, defined by the X3D KeySensor spec */
+    public static final int ACTION_KEY_UP = 17;
+    
+    /** The Down Arrow key action code, defined by the X3D KeySensor spec */
+    public static final int ACTION_KEY_DOWN = 18;
+    
+    /** The Left Arrow key action code, defined by the X3D KeySensor spec */
+    public static final int ACTION_KEY_LEFT = 19;
+    
+    /** The Right Arrow key action code, defined by the X3D KeySensor spec */
+    public static final int ACTION_KEY_RIGHT = 20;
+    
+    //-----------------------------------------------------------------------
+    // Modifier keys - non-character generating - codes arbitrarily defined
+    
+    /** The modifier key code base identifier */
+    public static final int MODIFIER_KEY_BASE = 0x100;
+    
+    /** The Alt key modifier code */
+    public static final int MODIFIER_KEY_ALT = MODIFIER_KEY_BASE + 0;
+    
+    /** The Control key modifier code */
+    public static final int MODIFIER_KEY_CONTROL = MODIFIER_KEY_BASE + 1;
+    
+    /** The Shift key modifier code */
+    public static final int MODIFIER_KEY_SHIFT = MODIFIER_KEY_BASE + 2;
+    
+    //-----------------------------------------------------------------------
+    // Character keys - character generating - codes arbitrarily defined
+    
+    /** The constant defining that the character is the Enter key */
+    public static final int CHAR_KEY_ENTER = '\n';
+    
+    /** The constant defining that the character is the Backspace key */
+    public static final int CHAR_KEY_BACKSPACE = '\b';
+    
+    //-----------------------------------------------------------------------
+    // Null key code - arbitrarily defined
+    
+    /** The constant defining that no action or modifier code is associated
+     *  with the key */
+    public static final int KEY_CODE_UNDEFINED = 0xFFFF;
+}
+
diff --git a/src/java/org/web3d/vrml/util/Xj3DKeyEvent.java b/src/java/org/web3d/vrml/util/Xj3DKeyEvent.java
index c72edbff8fb601d30ab42fd9dd29b9a8d40414c4..8adbe7977496cb57c56f19577021e4ce3ca29001 100644
--- a/src/java/org/web3d/vrml/util/Xj3DKeyEvent.java
+++ b/src/java/org/web3d/vrml/util/Xj3DKeyEvent.java
@@ -1,226 +1,226 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.util;
-
-// External imports
-import java.util.EventObject;
-
-// Local imports - NONE
-
-/**
- * A key event object modeled on the awt and swt key event objects. This class
- * has been developed for use within the X3D KeySensor and StringSensor node
- * implementations to ensure independence from a specific ui toolkit
- * implementation. This class is limited in capability to delivering key
- * characters and identifying the few non-character generating keys that are
- * specifically required by the X3D spec.
- *
- * @author Rex Melton
- * @version $Revision: 1.1 $
- */
-public class Xj3DKeyEvent extends EventObject {
-
-    /**
-     * The constant defining a key pressed event
-     */
-    public static final int KEY_PRESSED = 'K' << 24 | 'P' << 18;
-
-    /**
-     * The constant defining a key released event
-     */
-    public static final int KEY_RELEASED = 'K' << 24 | 'R' << 18;
-
-    /**
-     * The constant defining that no character is associated with the key
-     */
-    public static final char CHAR_UNDEFINED = 0xFFFF;
-
-    /**
-     * The id of the event, either KEY_PRESSED or KEY_RELEASED
-     */
-    private int eventID;
-
-    /**
-     * The character associated with the key in this event, or the NO_CHARACTER
-     * constant if no character is associated with the key
-     */
-    private char character = CHAR_UNDEFINED;
-
-    /**
-     * The identifier code associated with this key
-     */
-    private int keyCode = Xj3DKeyCode.KEY_CODE_UNDEFINED;
-
-    /**
-     * Flag indicating that a character is associated with this key
-     */
-    private boolean isCharacter;
-
-    /**
-     * Flag indicating that the character associated with this key is the Enter
-     * key
-     */
-    private boolean isEnter;
-
-    /**
-     * Flag indicating that the character associated with this key is the
-     * Backspace key
-     */
-    private boolean isBackspace;
-
-    /**
-     * Flag indicating that this key is a defined Action key
-     */
-    private boolean isAction;
-
-    /**
-     * Flag indicating that this key is a defined Modifier key
-     */
-    private boolean isModifier;
-
-    //-----------------------------------------------------------------------
-    // Note - the min max ranges presume sequential definitions...
-
-    /**
-     * The minimum modifier key code, used to bounds check in the constructor
-     */
-    private static final int MODIFIER_KEY_MIN = Xj3DKeyCode.MODIFIER_KEY_ALT;
-
-    /**
-     * The maximum modifier key code, used to bounds check in the constructor
-     */
-    private static final int MODIFIER_KEY_MAX = Xj3DKeyCode.MODIFIER_KEY_SHIFT;
-
-    /**
-     * The minimum action key code, used to bounds check in the constructor
-     */
-    private static final int ACTION_KEY_MIN = Xj3DKeyCode.ACTION_KEY_F1;
-
-    /**
-     * The maximum action key code, used to bounds check in the constructor
-     */
-    private static final int ACTION_KEY_MAX = Xj3DKeyCode.ACTION_KEY_RIGHT;
-
-    //-----------------------------------------------------------------------
-
-    /**
-     * Constructor for a character associated event. If the argument character
-     * equals the NO_CHARACTER constant, the getKeyChar() method will return
-     * NO_CHARACTER and the isCharacter() method will return false. Otherwise,
-     * the getKeyChar() method will return the argument character and the
-     * isCharacter() method will return true.
-     *
-     * @param src the object that was the source of the event
-     * @param id the event id, either KEY_PRESSED or KEY_RELEASED.
-     * @param c the character associated with the key.
-     * @param code the identifier of the specific defined function of this
-     * character associated key event.
-     */
-    public Xj3DKeyEvent(Object src, int id, char c, int code) {
-        super(src);
-        if (((id != KEY_PRESSED) && (id != KEY_RELEASED))) {
-            throw new IllegalArgumentException("Unknown Event ID");
-        }
-        eventID = id;
-        character = c;
-        keyCode = code;
-        if (c != CHAR_UNDEFINED) {
-            isCharacter = true;
-            if (code == Xj3DKeyCode.CHAR_KEY_ENTER) {
-                isEnter = true;
-            } else if (code == Xj3DKeyCode.CHAR_KEY_BACKSPACE) {
-                isBackspace = true;
-            }
-        } else {
-            if ((code >= MODIFIER_KEY_MIN) && (code <= MODIFIER_KEY_MAX)) {
-                isModifier = true;
-            } else if ((code >= ACTION_KEY_MIN) && (code <= ACTION_KEY_MAX)) {
-                isAction = true;
-            }
-        }
-    }
-
-    /**
-     * Return the event identifier.
-     *
-     * @return the event identifier, either KEY_PRESSED or KEY_RELEASED.
-     */
-    public int getID() {
-        return (eventID);
-    }
-
-    /**
-     * Returns whether there is a character associated with the key that
-     * generated this event.
-     * @return 
-     */
-    public boolean isCharacter() {
-        return (isCharacter);
-    }
-
-    /**
-     * Returns whether the character associated with the key that generated this
-     * event is the Enter key.
-     * @return 
-     */
-    public boolean isEnterKey() {
-        return (isEnter);
-    }
-
-    /**
-     * Returns whether the character associated with the key that generated this
-     * event is the Backspace key.
-     * @return 
-     */
-    public boolean isBackspaceKey() {
-        return (isBackspace);
-    }
-
-    /**
-     * Returns the character associated with the key that generated this event.
-     * If no character is associated, then the NO_CHARACTER constant is
-     * returned.
-     * @return 
-     */
-    public char getKeyChar() {
-        return (character);
-    }
-
-    /**
-     * Returns the key identifier code associated with the key that generated
-     * this event. If no key identifier code is associated, then the NO_KEY_CODE
-     * constant is returned.
-     * @return 
-     */
-    public int getKeyCode() {
-        return (keyCode);
-    }
-
-    /**
-     * Returns whether the key that generated this event is a defined action
-     * key.
-     * @return 
-     */
-    public boolean isAction() {
-        return (isAction);
-    }
-
-    /**
-     * Returns whether the key that generated this event is a defined modifier
-     * key.
-     * @return 
-     */
-    public boolean isModifier() {
-        return (isModifier);
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.util;
+
+// External imports
+import java.util.EventObject;
+
+// Local imports - NONE
+
+/**
+ * A key event object modeled on the awt and swt key event objects. This class
+ * has been developed for use within the X3D KeySensor and StringSensor node
+ * implementations to ensure independence from a specific ui toolkit
+ * implementation. This class is limited in capability to delivering key
+ * characters and identifying the few non-character generating keys that are
+ * specifically required by the X3D spec.
+ *
+ * @author Rex Melton
+ * @version $Revision: 1.1 $
+ */
+public class Xj3DKeyEvent extends EventObject {
+
+    /**
+     * The constant defining a key pressed event
+     */
+    public static final int KEY_PRESSED = 'K' << 24 | 'P' << 18;
+
+    /**
+     * The constant defining a key released event
+     */
+    public static final int KEY_RELEASED = 'K' << 24 | 'R' << 18;
+
+    /**
+     * The constant defining that no character is associated with the key
+     */
+    public static final char CHAR_UNDEFINED = 0xFFFF;
+
+    /**
+     * The id of the event, either KEY_PRESSED or KEY_RELEASED
+     */
+    private int eventID;
+
+    /**
+     * The character associated with the key in this event, or the NO_CHARACTER
+     * constant if no character is associated with the key
+     */
+    private char character = CHAR_UNDEFINED;
+
+    /**
+     * The identifier code associated with this key
+     */
+    private int keyCode = Xj3DKeyCode.KEY_CODE_UNDEFINED;
+
+    /**
+     * Flag indicating that a character is associated with this key
+     */
+    private boolean isCharacter;
+
+    /**
+     * Flag indicating that the character associated with this key is the Enter
+     * key
+     */
+    private boolean isEnter;
+
+    /**
+     * Flag indicating that the character associated with this key is the
+     * Backspace key
+     */
+    private boolean isBackspace;
+
+    /**
+     * Flag indicating that this key is a defined Action key
+     */
+    private boolean isAction;
+
+    /**
+     * Flag indicating that this key is a defined Modifier key
+     */
+    private boolean isModifier;
+
+    //-----------------------------------------------------------------------
+    // Note - the min max ranges presume sequential definitions...
+
+    /**
+     * The minimum modifier key code, used to bounds check in the constructor
+     */
+    private static final int MODIFIER_KEY_MIN = Xj3DKeyCode.MODIFIER_KEY_ALT;
+
+    /**
+     * The maximum modifier key code, used to bounds check in the constructor
+     */
+    private static final int MODIFIER_KEY_MAX = Xj3DKeyCode.MODIFIER_KEY_SHIFT;
+
+    /**
+     * The minimum action key code, used to bounds check in the constructor
+     */
+    private static final int ACTION_KEY_MIN = Xj3DKeyCode.ACTION_KEY_F1;
+
+    /**
+     * The maximum action key code, used to bounds check in the constructor
+     */
+    private static final int ACTION_KEY_MAX = Xj3DKeyCode.ACTION_KEY_RIGHT;
+
+    //-----------------------------------------------------------------------
+
+    /**
+     * Constructor for a character associated event. If the argument character
+     * equals the NO_CHARACTER constant, the getKeyChar() method will return
+     * NO_CHARACTER and the isCharacter() method will return false. Otherwise,
+     * the getKeyChar() method will return the argument character and the
+     * isCharacter() method will return true.
+     *
+     * @param src the object that was the source of the event
+     * @param id the event id, either KEY_PRESSED or KEY_RELEASED.
+     * @param c the character associated with the key.
+     * @param code the identifier of the specific defined function of this
+     * character associated key event.
+     */
+    public Xj3DKeyEvent(Object src, int id, char c, int code) {
+        super(src);
+        if (((id != KEY_PRESSED) && (id != KEY_RELEASED))) {
+            throw new IllegalArgumentException("Unknown Event ID");
+        }
+        eventID = id;
+        character = c;
+        keyCode = code;
+        if (c != CHAR_UNDEFINED) {
+            isCharacter = true;
+            if (code == Xj3DKeyCode.CHAR_KEY_ENTER) {
+                isEnter = true;
+            } else if (code == Xj3DKeyCode.CHAR_KEY_BACKSPACE) {
+                isBackspace = true;
+            }
+        } else {
+            if ((code >= MODIFIER_KEY_MIN) && (code <= MODIFIER_KEY_MAX)) {
+                isModifier = true;
+            } else if ((code >= ACTION_KEY_MIN) && (code <= ACTION_KEY_MAX)) {
+                isAction = true;
+            }
+        }
+    }
+
+    /**
+     * Return the event identifier.
+     *
+     * @return the event identifier, either KEY_PRESSED or KEY_RELEASED.
+     */
+    public int getID() {
+        return (eventID);
+    }
+
+    /**
+     * Returns whether there is a character associated with the key that
+     * generated this event.
+     * @return 
+     */
+    public boolean isCharacter() {
+        return (isCharacter);
+    }
+
+    /**
+     * Returns whether the character associated with the key that generated this
+     * event is the Enter key.
+     * @return 
+     */
+    public boolean isEnterKey() {
+        return (isEnter);
+    }
+
+    /**
+     * Returns whether the character associated with the key that generated this
+     * event is the Backspace key.
+     * @return 
+     */
+    public boolean isBackspaceKey() {
+        return (isBackspace);
+    }
+
+    /**
+     * Returns the character associated with the key that generated this event.
+     * If no character is associated, then the NO_CHARACTER constant is
+     * returned.
+     * @return 
+     */
+    public char getKeyChar() {
+        return (character);
+    }
+
+    /**
+     * Returns the key identifier code associated with the key that generated
+     * this event. If no key identifier code is associated, then the NO_KEY_CODE
+     * constant is returned.
+     * @return 
+     */
+    public int getKeyCode() {
+        return (keyCode);
+    }
+
+    /**
+     * Returns whether the key that generated this event is a defined action
+     * key.
+     * @return 
+     */
+    public boolean isAction() {
+        return (isAction);
+    }
+
+    /**
+     * Returns whether the key that generated this event is a defined modifier
+     * key.
+     * @return 
+     */
+    public boolean isModifier() {
+        return (isModifier);
+    }
+}
diff --git a/src/java/org/web3d/vrml/util/Xj3DKeyListener.java b/src/java/org/web3d/vrml/util/Xj3DKeyListener.java
index 9155a725c8ca38197eaf757d84022e33e469b4fb..f2c355fe0234ed66c935219539f8ebb19e174a3b 100644
--- a/src/java/org/web3d/vrml/util/Xj3DKeyListener.java
+++ b/src/java/org/web3d/vrml/util/Xj3DKeyListener.java
@@ -1,38 +1,38 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.vrml.util;
-
-// External imports
-import java.util.EventListener;
-
-// Local imports - NONE
-
-/**
- * A key event listener interface modeled on the awt and swt key listener
- * interface. This interface has been developed for use within the KeySensor
- * and StringSensor node implementations to ensure independence from a
- * specific ui toolkit implementation.
- *
- * @author Rex Melton
- * @version $Revision: 1.1 $
- */
-public interface Xj3DKeyListener extends EventListener {
-
-    /** Invoked when a key has been pressed.
-     * @param e */
-    void keyPressed( Xj3DKeyEvent e );
-
-    /** Invoked when a key has been released.
-     * @param e */
-    void keyReleased( Xj3DKeyEvent e );
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.vrml.util;
+
+// External imports
+import java.util.EventListener;
+
+// Local imports - NONE
+
+/**
+ * A key event listener interface modeled on the awt and swt key listener
+ * interface. This interface has been developed for use within the KeySensor
+ * and StringSensor node implementations to ensure independence from a
+ * specific ui toolkit implementation.
+ *
+ * @author Rex Melton
+ * @version $Revision: 1.1 $
+ */
+public interface Xj3DKeyListener extends EventListener {
+
+    /** Invoked when a key has been pressed.
+     * @param e */
+    void keyPressed( Xj3DKeyEvent e );
+
+    /** Invoked when a key has been released.
+     * @param e */
+    void keyReleased( Xj3DKeyEvent e );
+}
diff --git a/src/java/org/web3d/x3d/sai/Browser.java b/src/java/org/web3d/x3d/sai/Browser.java
index d352d5842a13942032aa976a8fd3a15ff8fa7cf4..e22b4a9b159590ded79db1dfbe34bb25fd5789d5 100644
--- a/src/java/org/web3d/x3d/sai/Browser.java
+++ b/src/java/org/web3d/x3d/sai/Browser.java
@@ -23,22 +23,19 @@ import org.w3c.dom.Node;
 // None
 
 /**
- * <p>
  * Basic browser interface that represents the interface to the VRML browser
  * from any application.
- * </p>
  * <p>
  * Individual VRML browser implementors are to extend this
  * interface and provide this functionality. The individual users will not see
  * anything but this interface.
- * 
+ * <p>
  * A number of the methods in this application can take strings representing URLs.
  * Relative URL strings contained in URL fields of nodes or these method
  * arguments are interpreted as follows:
- * </p>
  * <p>
  * Relative URLs are treated as per clause B.3.5 of the EAI Java Bindings
- * </p>
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.15 $
diff --git a/src/java/org/web3d/x3d/sai/BrowserNotSharedException.java b/src/java/org/web3d/x3d/sai/BrowserNotSharedException.java
index c4c1da1167d581b6c781073825eba4811470ccc7..f61f36f61f4eae53132145d7d32d80fec71e113a 100644
--- a/src/java/org/web3d/x3d/sai/BrowserNotSharedException.java
+++ b/src/java/org/web3d/x3d/sai/BrowserNotSharedException.java
@@ -1,36 +1,36 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001-2005
- *                               Java Source
- *
- * This source is licensed under the BSD license.
- * Please read docs/BSD.txt for the text of the license.
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.x3d.sai;
-
-/**
- * The exception that is thrown when the user attempts to make method calls
- * that require this browser to be shared.
- *
- * @version 1.0 7th March 1998
- */
-public class BrowserNotSharedException extends X3DException {
-    /**
-     * Construct a basic instance of this exception with no error message
-     */
-    public BrowserNotSharedException() {
-    }
-
-    /**
-     * Constructs a new exception with a particular message
-     *
-     * @param msg The message to use
-     */
-    public BrowserNotSharedException(String msg) {
-        super(msg);
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001-2005
+ *                               Java Source
+ *
+ * This source is licensed under the BSD license.
+ * Please read docs/BSD.txt for the text of the license.
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.x3d.sai;
+
+/**
+ * The exception that is thrown when the user attempts to make method calls
+ * that require this browser to be shared.
+ *
+ * @version 1.0 7th March 1998
+ */
+public class BrowserNotSharedException extends X3DException {
+    /**
+     * Construct a basic instance of this exception with no error message
+     */
+    public BrowserNotSharedException() {
+    }
+
+    /**
+     * Constructs a new exception with a particular message
+     *
+     * @param msg The message to use
+     */
+    public BrowserNotSharedException(String msg) {
+        super(msg);
+    }
+}
diff --git a/src/java/org/web3d/x3d/sai/ConnectionException.java b/src/java/org/web3d/x3d/sai/ConnectionException.java
index 877cabecebfa147cd40aefa430b7a331f33f4dbd..d13cbffaafeea521861c1afdbe81980499d751eb 100644
--- a/src/java/org/web3d/x3d/sai/ConnectionException.java
+++ b/src/java/org/web3d/x3d/sai/ConnectionException.java
@@ -1,37 +1,37 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001-2005
- *                               Java Source
- *
- * This source is licensed under the BSD license.
- * Please read docs/BSD.txt for the text of the license.
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.x3d.sai;
-
-/**
- * The exception that is thrown when an error occurs in the connection between
- * the external application and the VRML browser. Typically this might be a
- * network connection stopping or similar problem.
- *
- * @version 1.0 3 August 1998
- */
-public class ConnectionException extends X3DException {
-    /**
-     * Construct a basic instance of this exception with no error message
-     */
-    public ConnectionException() {
-    }
-
-    /**
-     * Constructs a new exception with a particular message
-     *
-     * @param msg The message to use
-     */
-    public ConnectionException(String msg) {
-        super(msg);
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001-2005
+ *                               Java Source
+ *
+ * This source is licensed under the BSD license.
+ * Please read docs/BSD.txt for the text of the license.
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.x3d.sai;
+
+/**
+ * The exception that is thrown when an error occurs in the connection between
+ * the external application and the VRML browser. Typically this might be a
+ * network connection stopping or similar problem.
+ *
+ * @version 1.0 3 August 1998
+ */
+public class ConnectionException extends X3DException {
+    /**
+     * Construct a basic instance of this exception with no error message
+     */
+    public ConnectionException() {
+    }
+
+    /**
+     * Constructs a new exception with a particular message
+     *
+     * @param msg The message to use
+     */
+    public ConnectionException(String msg) {
+        super(msg);
+    }
+}
diff --git a/src/java/org/web3d/x3d/sai/ExternalBrowser.java b/src/java/org/web3d/x3d/sai/ExternalBrowser.java
index 346e3e69441e572d05ee72654a6b15f2bfe3d14b..c680ff64235a53d2ebc92094428b33cf350e651f 100644
--- a/src/java/org/web3d/x3d/sai/ExternalBrowser.java
+++ b/src/java/org/web3d/x3d/sai/ExternalBrowser.java
@@ -15,12 +15,13 @@ package org.web3d.x3d.sai;
 /**
  * Browser interface that represents the additional abilities an external
  * application is granted to the VRML browser.
+ * <p>
  * A number of the methods in this application can take strings representing URLs.
  * Relative URL strings contained in URL fields of nodes or these method
  * arguments are interpreted as follows:
- * 
+ * <p>
  * Relative URLs are treated as per clause B.3.5 of the EAI Java Bindings
- * 
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.4 $
diff --git a/src/java/org/web3d/x3d/sai/InsufficientCapabilitiesException.java b/src/java/org/web3d/x3d/sai/InsufficientCapabilitiesException.java
index c614ba816bf1015c35ed3ea3e6cfbeff7b88ced9..d9216c4b418e8ccfd62a54990eca2d4876db8e2a 100644
--- a/src/java/org/web3d/x3d/sai/InsufficientCapabilitiesException.java
+++ b/src/java/org/web3d/x3d/sai/InsufficientCapabilitiesException.java
@@ -1,39 +1,39 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001-2005
- *                               Java Source
- *
- * This source is licensed under the BSD license.
- * Please read docs/BSD.txt for the text of the license.
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.x3d.sai;
-
-/**
- * The exception that is thrown when a node of greater capabilities than
- * the scene's declared profile and additional components is attempted to be
- * added to that scene.
- *
- * @author Justion Couch
- * @version $Revision: 1.2 $
- */
-public class InsufficientCapabilitiesException extends X3DException {
-
-    /**
-     * Construct a basic instance of this exception with no error message
-     */
-    public InsufficientCapabilitiesException() {
-    }
-
-    /**
-     * Constructs a new exception with a particular message
-     *
-     * @param msg The message to use
-     */
-    public InsufficientCapabilitiesException(String msg) {
-        super(msg);
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001-2005
+ *                               Java Source
+ *
+ * This source is licensed under the BSD license.
+ * Please read docs/BSD.txt for the text of the license.
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.x3d.sai;
+
+/**
+ * The exception that is thrown when a node of greater capabilities than
+ * the scene's declared profile and additional components is attempted to be
+ * added to that scene.
+ *
+ * @author Justion Couch
+ * @version $Revision: 1.2 $
+ */
+public class InsufficientCapabilitiesException extends X3DException {
+
+    /**
+     * Construct a basic instance of this exception with no error message
+     */
+    public InsufficientCapabilitiesException() {
+    }
+
+    /**
+     * Constructs a new exception with a particular message
+     *
+     * @param msg The message to use
+     */
+    public InsufficientCapabilitiesException(String msg) {
+        super(msg);
+    }
+}
diff --git a/src/java/org/web3d/x3d/sai/InvalidExecutionContextException.java b/src/java/org/web3d/x3d/sai/InvalidExecutionContextException.java
index d04a5bcf5dbffa86c05b4da7df30fa22675e314f..70c108a941a3a0eef3cb193e609c77ae692444ef 100644
--- a/src/java/org/web3d/x3d/sai/InvalidExecutionContextException.java
+++ b/src/java/org/web3d/x3d/sai/InvalidExecutionContextException.java
@@ -1,38 +1,38 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001-2005
- *                               Java Source
- *
- * This source is licensed under the BSD license.
- * Please read docs/BSD.txt for the text of the license.
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.x3d.sai;
-
-/**
- * The exception that is thrown when a reference to an ExecutionContext is
- * not valid.
- *
- * @author Justion Couch
- * @version $Revision: 1.2 $
- */
-public class InvalidExecutionContextException extends X3DException {
-
-    /**
-     * Construct a basic instance of this exception with no error message
-     */
-    public InvalidExecutionContextException() {
-    }
-
-    /**
-     * Constructs a new exception with a particular message
-     *
-     * @param msg The message to use
-     */
-    public InvalidExecutionContextException(String msg) {
-        super(msg);
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001-2005
+ *                               Java Source
+ *
+ * This source is licensed under the BSD license.
+ * Please read docs/BSD.txt for the text of the license.
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.x3d.sai;
+
+/**
+ * The exception that is thrown when a reference to an ExecutionContext is
+ * not valid.
+ *
+ * @author Justion Couch
+ * @version $Revision: 1.2 $
+ */
+public class InvalidExecutionContextException extends X3DException {
+
+    /**
+     * Construct a basic instance of this exception with no error message
+     */
+    public InvalidExecutionContextException() {
+    }
+
+    /**
+     * Constructs a new exception with a particular message
+     *
+     * @param msg The message to use
+     */
+    public InvalidExecutionContextException(String msg) {
+        super(msg);
+    }
+}
diff --git a/src/java/org/web3d/x3d/sai/InvalidNodeException.java b/src/java/org/web3d/x3d/sai/InvalidNodeException.java
index 1990c0ee3780ca2fe65e3da7120e6cb8517e580c..6e148c5a9286c12566dacdfa945bdfaa82e3ce41 100644
--- a/src/java/org/web3d/x3d/sai/InvalidNodeException.java
+++ b/src/java/org/web3d/x3d/sai/InvalidNodeException.java
@@ -1,35 +1,35 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001-2005
- *                               Java Source
- *
- * This source is licensed under the BSD license.
- * Please read docs/BSD.txt for the text of the license.
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.x3d.sai;
-
-/**
- * The exception that is thrown when a reference to an Node is not valid.
- *
- * @version 1.0 7th March 1998
- */
-public class InvalidNodeException extends X3DException {
-    /**
-     * Construct a basic instance of this exception with no error message
-     */
-    public InvalidNodeException() {
-    }
-
-    /**
-     * Constructs a new exception with a particular message
-     *
-     * @param msg The message to use
-     */
-    public InvalidNodeException(String msg) {
-        super(msg);
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001-2005
+ *                               Java Source
+ *
+ * This source is licensed under the BSD license.
+ * Please read docs/BSD.txt for the text of the license.
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.x3d.sai;
+
+/**
+ * The exception that is thrown when a reference to an Node is not valid.
+ *
+ * @version 1.0 7th March 1998
+ */
+public class InvalidNodeException extends X3DException {
+    /**
+     * Construct a basic instance of this exception with no error message
+     */
+    public InvalidNodeException() {
+    }
+
+    /**
+     * Constructs a new exception with a particular message
+     *
+     * @param msg The message to use
+     */
+    public InvalidNodeException(String msg) {
+        super(msg);
+    }
+}
diff --git a/src/java/org/web3d/x3d/sai/InvalidProtoException.java b/src/java/org/web3d/x3d/sai/InvalidProtoException.java
index 6e1fdc02f681cdfd14c4d7d6f9aaebad19f43420..dc404a1d611439af8dce542c33545f1463edc0ed 100644
--- a/src/java/org/web3d/x3d/sai/InvalidProtoException.java
+++ b/src/java/org/web3d/x3d/sai/InvalidProtoException.java
@@ -1,38 +1,38 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001-2005
- *                               Java Source
- *
- * This source is licensed under the BSD license.
- * Please read docs/BSD.txt for the text of the license.
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.x3d.sai;
-
-/**
- * The exception that is thrown when a reference to an Proto or ExternProto
- * is not valid.
- *
- * @author Justin Couch
- * @version $Revision: 1.2 $
- */
-public class InvalidProtoException extends X3DException {
-
-    /**
-     * Construct a basic instance of this exception with no error message
-     */
-    public InvalidProtoException() {
-    }
-
-    /**
-     * Constructs a new exception with a particular message
-     *
-     * @param msg The message to use
-     */
-    public InvalidProtoException(String msg) {
-        super(msg);
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001-2005
+ *                               Java Source
+ *
+ * This source is licensed under the BSD license.
+ * Please read docs/BSD.txt for the text of the license.
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.x3d.sai;
+
+/**
+ * The exception that is thrown when a reference to an Proto or ExternProto
+ * is not valid.
+ *
+ * @author Justin Couch
+ * @version $Revision: 1.2 $
+ */
+public class InvalidProtoException extends X3DException {
+
+    /**
+     * Construct a basic instance of this exception with no error message
+     */
+    public InvalidProtoException() {
+    }
+
+    /**
+     * Constructs a new exception with a particular message
+     *
+     * @param msg The message to use
+     */
+    public InvalidProtoException(String msg) {
+        super(msg);
+    }
+}
diff --git a/src/java/org/web3d/x3d/sai/InvalidRouteException.java b/src/java/org/web3d/x3d/sai/InvalidRouteException.java
index 4c45e76593ec4e7e0d26af602fbd800bcb57f9b4..9d767a99763e266695908c09ab3ccee649ef607f 100644
--- a/src/java/org/web3d/x3d/sai/InvalidRouteException.java
+++ b/src/java/org/web3d/x3d/sai/InvalidRouteException.java
@@ -14,6 +14,7 @@ package org.web3d.x3d.sai;
 
 /**
  * The exception that is thrown when a reference to any route is not valid.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/web3d/x3d/sai/MFBool.java b/src/java/org/web3d/x3d/sai/MFBool.java
index e86efa92a351d9f510f6efade08b45b46a3f6755..65388940d3cf981008b82510c6080ce448d01b00 100644
--- a/src/java/org/web3d/x3d/sai/MFBool.java
+++ b/src/java/org/web3d/x3d/sai/MFBool.java
@@ -14,6 +14,7 @@ package org.web3d.x3d.sai;
 
 /**
  * Interface representing a MFBool field.
+ * <p>
  *
  * @version 1.0 30 April 1998
  */
diff --git a/src/java/org/web3d/x3d/sai/NoSuchBrowserException.java b/src/java/org/web3d/x3d/sai/NoSuchBrowserException.java
index 4a109fe2260a0aca8c60a6a1d3b938ad6cdcd66f..9cc845389e27a985ebe15f603f4049cb5869decd 100644
--- a/src/java/org/web3d/x3d/sai/NoSuchBrowserException.java
+++ b/src/java/org/web3d/x3d/sai/NoSuchBrowserException.java
@@ -1,39 +1,39 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001-2005
- *                               Java Source
- *
- * This source is licensed under the BSD license.
- * Please read docs/BSD.txt for the text of the license.
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.x3d.sai;
-
-/**
- * The exception that is thrown when the Browser factory is not able to locate
- * a browser given the arguments.
- *
- * @see BrowserFactory
- * @see BrowserFactoryImpl
- *
- * @version 1.0 23rd June 1998
- */
-public class NoSuchBrowserException extends X3DException {
-    /**
-     * Construct a basic instance of this exception with no error message
-     */
-    public NoSuchBrowserException() {
-    }
-
-    /**
-     * Constructs a new exception with a particular message
-     *
-     * @param msg The message to use
-     */
-    public NoSuchBrowserException(String msg) {
-        super(msg);
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001-2005
+ *                               Java Source
+ *
+ * This source is licensed under the BSD license.
+ * Please read docs/BSD.txt for the text of the license.
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.x3d.sai;
+
+/**
+ * The exception that is thrown when the Browser factory is not able to locate
+ * a browser given the arguments.
+ *
+ * @see BrowserFactory
+ * @see BrowserFactoryImpl
+ *
+ * @version 1.0 23rd June 1998
+ */
+public class NoSuchBrowserException extends X3DException {
+    /**
+     * Construct a basic instance of this exception with no error message
+     */
+    public NoSuchBrowserException() {
+    }
+
+    /**
+     * Constructs a new exception with a particular message
+     *
+     * @param msg The message to use
+     */
+    public NoSuchBrowserException(String msg) {
+        super(msg);
+    }
+}
diff --git a/src/java/org/web3d/x3d/sai/NodeUnavailableException.java b/src/java/org/web3d/x3d/sai/NodeUnavailableException.java
index 4af306ff479e431a9548a1df5928442fb838f560..b40483826c4482ed2ba41fb058e5950647355c5a 100644
--- a/src/java/org/web3d/x3d/sai/NodeUnavailableException.java
+++ b/src/java/org/web3d/x3d/sai/NodeUnavailableException.java
@@ -1,37 +1,37 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001-2005
- *                               Java Source
- *
- * This source is licensed under the BSD license.
- * Please read docs/BSD.txt for the text of the license.
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.x3d.sai;
-
-/**
- * The exception that is thrown when asking for a node by name Node and the
- * name is valid but the underlying node reference is not available from the
- * inline yet.
- *
- * @version 1.0 7th March 1998
- */
-public class NodeUnavailableException extends X3DException {
-    /**
-     * Construct a basic instance of this exception with no error message
-     */
-    public NodeUnavailableException() {
-    }
-
-    /**
-     * Constructs a new exception with a particular message
-     *
-     * @param msg The message to use
-     */
-    public NodeUnavailableException(String msg) {
-        super(msg);
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001-2005
+ *                               Java Source
+ *
+ * This source is licensed under the BSD license.
+ * Please read docs/BSD.txt for the text of the license.
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.x3d.sai;
+
+/**
+ * The exception that is thrown when asking for a node by name Node and the
+ * name is valid but the underlying node reference is not available from the
+ * inline yet.
+ *
+ * @version 1.0 7th March 1998
+ */
+public class NodeUnavailableException extends X3DException {
+    /**
+     * Construct a basic instance of this exception with no error message
+     */
+    public NodeUnavailableException() {
+    }
+
+    /**
+     * Constructs a new exception with a particular message
+     *
+     * @param msg The message to use
+     */
+    public NodeUnavailableException(String msg) {
+        super(msg);
+    }
+}
diff --git a/src/java/org/web3d/x3d/sai/X3DExternProtoDeclaration.java b/src/java/org/web3d/x3d/sai/X3DExternProtoDeclaration.java
index bfda907e8833922592e746572e65fa5262ee5815..cfe0ce88f8afac306d238976c5d2bd17f5c2f9e5 100644
--- a/src/java/org/web3d/x3d/sai/X3DExternProtoDeclaration.java
+++ b/src/java/org/web3d/x3d/sai/X3DExternProtoDeclaration.java
@@ -14,42 +14,41 @@ package org.web3d.x3d.sai;
 
 
 /**
- * <p>
  * The representation of an EXTERNPROTO declaration.
- * </p>
  * <p>
+ *
  * This is the representation of the declaration, not of a runtime node. For
  * this reason you cannot access the internals, nor can you work with the
  * individual field values. You can, however, perform basic introspection
  * tasks such as looking at the available field definitions and seeing the
  * basic node type.
- * </p>
  * <p>
+ *
  * The implementation extends the basic proto declaration class to represent
  * externally represented information. While all the basic method calls are
  * supported, they do need to have thier behaivour modified somewhat to deal
  * with the external nature of this structure. The following modifications to
  * the behaviours are made:
- * </p>
  * <p>
+ *
  * <i>createInstance()</i><br>
  * <i>getNodeType()</i><br>
  * If the instance has not loaded yet or failed to load, this will generate
  * an InvalidNodeException in addition to the normal reasons. A user should
  * check the load state first before trying to create an instance if they
  * wish to avoid this error.
- * </p>
+ *
  * <p>
  * <i>getFieldDeclarations()</i><br>
  * When queried, this will return the definitions of the fields as declared
  * in the externproto, not the underlying proto definition.
- * </p>
  * <p>
+ *
  * No access is provided to the underlying proto declaration that fulfills
  * this external representation. If the user wishes to access that, then
  * they may make use of the createVrmlFromURL feature of the browser to load
  * the individual file as needed.
- * </p>
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/x3d/sai/X3DField.java b/src/java/org/web3d/x3d/sai/X3DField.java
index beefe5c3e91ba886a5f2d83d8df56c32f6580434..34e170d4f25b576e18554d0a44ae353ececf7b0c 100644
--- a/src/java/org/web3d/x3d/sai/X3DField.java
+++ b/src/java/org/web3d/x3d/sai/X3DField.java
@@ -1,99 +1,100 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001-2005
- *                               Java Source
- *
- * This source is licensed under the BSD license.
- * Please read docs/BSD.txt for the text of the license.
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.x3d.sai;
-
-/**
- * Base representation of an X3D field type.
- *
- * @author Justin Couch
- * @version $Revision: 1.3 $
- */
-public interface X3DField {
-
-    /**
-     * Get the definition of this field.
-     *
-     * @return The field definition to use
-     */
-    X3DFieldDefinition getDefinition();
-
-    /**
-     * Check to see if this field is readable. This may return two different
-     * sets of values depending on the use. If this field is the field of a
-     * script that has been passed to a script implementation, it will return
-     * true if the field is an eventIn, exposedField or field and false for an
-     * eventOut. If it is a field of any other circumstance (ie an external
-     * application querying a node or a script querying another node it has a
-     * reference to) it shall return true for eventOuts, exposedFields and
-     * false for eventIn or field.
-     *
-     * @return true if the values of this field are readable
-     * @throws InvalidFieldException The underlying node this field came from
-     *    has been disposed of
-     */
-    boolean isReadable();
-
-    /**
-     * Check to see if this field is writable. This may return two different
-     * sets of values depending on the use. If this field is the field of a
-     * script that has been passed to a script implementation, it will return
-     * true if the field is an eventOut, exposedField or field and false for an
-     * eventIn. If it is a field of any other circumstance (ie an external
-     * application querying a node or a script querying another node it has a
-     * reference to) it shall return true for eventIns, exposedFields and
-     * false for eventOut or field.
-     *
-     * @return true if the values of this field are readable
-     * @throws InvalidFieldException The underlying node this field came from
-     *    has been disposed of
-     */
-    boolean isWritable();
-
-    /**
-     * Add a listener for changes in this field. This works for listening to
-     * changes in a readable field. A future extension to the specification,
-     * or a browser-specific extension, may allow for listeners to be added
-     * to writable nodes as well.
-     * <p>
-     * A listener instance cannot have multiple simultaneous registrations.
-     * If the listener instance is currently registered, this request shall
-     * be silently ignored.
-     *
-     * @param l The listener to add
-     */
-    void addX3DEventListener(X3DFieldEventListener l);
-
-    /**
-     * Remove a listener for changes in the readable field. If the listener is
-     * not currently registered, this request shall be silently ignored.
-     *
-     * @param l The listener to remove
-     */
-    void removeX3DEventListener(X3DFieldEventListener l);
-
-    /**
-     * Associate user data with this field. Whenever an field is generated
-     * on this field, this data will be available with the Event through
-     * its getData method.
-     *
-     * @param data The data to associate with this eventOut instance
-     */
-    void setUserData(Object data);
-
-    /**
-     * Get the user data that is associated with this field.
-     *
-     * @return The user data, if any, associated with this field
-     */
-    Object getUserData();
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001-2005
+ *                               Java Source
+ *
+ * This source is licensed under the BSD license.
+ * Please read docs/BSD.txt for the text of the license.
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.x3d.sai;
+
+/**
+ * Base representation of an X3D field type.
+ * <p>
+ *
+ * @author Justin Couch
+ * @version $Revision: 1.3 $
+ */
+public interface X3DField {
+
+    /**
+     * Get the definition of this field.
+     *
+     * @return The field definition to use
+     */
+    X3DFieldDefinition getDefinition();
+
+    /**
+     * Check to see if this field is readable. This may return two different
+     * sets of values depending on the use. If this field is the field of a
+     * script that has been passed to a script implementation, it will return
+     * true if the field is an eventIn, exposedField or field and false for an
+     * eventOut. If it is a field of any other circumstance (ie an external
+     * application querying a node or a script querying another node it has a
+     * reference to) it shall return true for eventOuts, exposedFields and
+     * false for eventIn or field.
+     *
+     * @return true if the values of this field are readable
+     * @throws InvalidFieldException The underlying node this field came from
+     *    has been disposed of
+     */
+    boolean isReadable();
+
+    /**
+     * Check to see if this field is writable. This may return two different
+     * sets of values depending on the use. If this field is the field of a
+     * script that has been passed to a script implementation, it will return
+     * true if the field is an eventOut, exposedField or field and false for an
+     * eventIn. If it is a field of any other circumstance (ie an external
+     * application querying a node or a script querying another node it has a
+     * reference to) it shall return true for eventIns, exposedFields and
+     * false for eventOut or field.
+     *
+     * @return true if the values of this field are readable
+     * @throws InvalidFieldException The underlying node this field came from
+     *    has been disposed of
+     */
+    boolean isWritable();
+
+    /**
+     * Add a listener for changes in this field. This works for listening to
+     * changes in a readable field. A future extension to the specification,
+     * or a browser-specific extension, may allow for listeners to be added
+     * to writable nodes as well.
+     * <p>
+     * A listener instance cannot have multiple simultaneous registrations.
+     * If the listener instance is currently registered, this request shall
+     * be silently ignored.
+     *
+     * @param l The listener to add
+     */
+    void addX3DEventListener(X3DFieldEventListener l);
+
+    /**
+     * Remove a listener for changes in the readable field. If the listener is
+     * not currently registered, this request shall be silently ignored.
+     *
+     * @param l The listener to remove
+     */
+    void removeX3DEventListener(X3DFieldEventListener l);
+
+    /**
+     * Associate user data with this field. Whenever an field is generated
+     * on this field, this data will be available with the Event through
+     * its getData method.
+     *
+     * @param data The data to associate with this eventOut instance
+     */
+    void setUserData(Object data);
+
+    /**
+     * Get the user data that is associated with this field.
+     *
+     * @return The user data, if any, associated with this field
+     */
+    Object getUserData();
+}
diff --git a/src/java/org/web3d/x3d/sai/X3DFieldDefinition.java b/src/java/org/web3d/x3d/sai/X3DFieldDefinition.java
index 118b4cc298f6f6d71897e2f3ad84f327c1dda63f..cf205ee408ca120e77fb10ffceb6adafd4034fce 100644
--- a/src/java/org/web3d/x3d/sai/X3DFieldDefinition.java
+++ b/src/java/org/web3d/x3d/sai/X3DFieldDefinition.java
@@ -1,73 +1,73 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001-2005
- *                               Java Source
- *
- * This source is licensed under the BSD license.
- * Please read docs/BSD.txt for the text of the license.
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.x3d.sai;
-
-/**
- * <p>
- * Representation of a node's field definition.
- * </p>
- * <p>
- * The field definition holds the static field information such as the field
- * access type, the data type and the name of the field.
- * </p>
- * <p>
- * The implementation of the toString() method of this class shall return the
- * full IDL declaration of the field as per the specification, not the UTF8 or
- * XML format. Implementation of <code>.equals()</code> shall return true if
- * the two field definitions share the same access type, data type and name. It
- * shall not include the underlying field's values at that point in time.
- * </p>
- *
- * @author Justin Couch
- * @version $Revision: 1.5 $
- */
-public interface X3DFieldDefinition {
-
-    /**
-     * Get the name of this field. This will be something like "children"
-     * or "translation". If the field is an exposed field then the name
-     * give will be the base name without any <i>set_</i> or <i>_changed</i>
-     * added to the name, regardless of how the initial field was fetched.
-     *
-     * @return The name of this field
-     */
-    public String getName();
-
-    /**
-     * Get the access type of the field. This will be one of field,
-     * exposedField, eventIn or eventOut constants described in the
-     * X3DFieldTypes interface.
-     *
-     * @return The access type of this field
-     * @see X3DFieldTypes
-     */
-    public int getAccessType();
-
-    /**
-     * Get the field type. This string represents the field type such as
-     * MFNode, SFInt32. The definition of the returned int value is
-     * described in the X3DFieldType interface.
-     *
-     * @return A constant describing the field type
-     * @see X3DFieldTypes
-     */
-    public int getFieldType();
-
-    /**
-     * Get the field type. This string represents the field type such as
-     * MFNode, SFInt32, etc. A string is used to allow full extensibility.
-     *
-     * @return A string describing the field type
-     */
-    public String getFieldTypeString();
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001-2005
+ *                               Java Source
+ *
+ * This source is licensed under the BSD license.
+ * Please read docs/BSD.txt for the text of the license.
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.x3d.sai;
+
+/**
+ * <p>
+ * Representation of a node's field definition.
+ * </p>
+ * <p>
+ * The field definition holds the static field information such as the field
+ * access type, the data type and the name of the field.
+ * </p>
+ * <p>
+ * The implementation of the toString() method of this class shall return the
+ * full IDL declaration of the field as per the specification, not the UTF8 or
+ * XML format. Implementation of <code>.equals()</code> shall return true if
+ * the two field definitions share the same access type, data type and name. It
+ * shall not include the underlying field's values at that point in time.
+ * </p>
+ *
+ * @author Justin Couch
+ * @version $Revision: 1.5 $
+ */
+public interface X3DFieldDefinition {
+
+    /**
+     * Get the name of this field. This will be something like "children"
+     * or "translation". If the field is an exposed field then the name
+     * give will be the base name without any <i>set_</i> or <i>_changed</i>
+     * added to the name, regardless of how the initial field was fetched.
+     *
+     * @return The name of this field
+     */
+    public String getName();
+
+    /**
+     * Get the access type of the field. This will be one of field,
+     * exposedField, eventIn or eventOut constants described in the
+     * X3DFieldTypes interface.
+     *
+     * @return The access type of this field
+     * @see X3DFieldTypes
+     */
+    public int getAccessType();
+
+    /**
+     * Get the field type. This string represents the field type such as
+     * MFNode, SFInt32. The definition of the returned int value is
+     * described in the X3DFieldType interface.
+     *
+     * @return A constant describing the field type
+     * @see X3DFieldTypes
+     */
+    public int getFieldType();
+
+    /**
+     * Get the field type. This string represents the field type such as
+     * MFNode, SFInt32, etc. A string is used to allow full extensibility.
+     *
+     * @return A string describing the field type
+     */
+    public String getFieldTypeString();
+}
diff --git a/src/java/org/web3d/x3d/sai/X3DFieldEventListener.java b/src/java/org/web3d/x3d/sai/X3DFieldEventListener.java
index 1ba48945be990939e38cb1e879eb3c24b2e31142..59a3c1c4a070c8ce37ad87733d9f2e43b634c9f8 100644
--- a/src/java/org/web3d/x3d/sai/X3DFieldEventListener.java
+++ b/src/java/org/web3d/x3d/sai/X3DFieldEventListener.java
@@ -1,35 +1,35 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001-2005
- *                               Java Source
- *
- * This source is licensed under the BSD license.
- * Please read docs/BSD.txt for the text of the license.
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.web3d.x3d.sai;
-
-// Standard imports
-import java.util.EventListener;
-
-// Application specific imports
-// None
-
-/**
- * A listener for events on X3D fields
- *
- * @author Justin Couch
- * @version $Revision: 1.5 $
- */
-public interface X3DFieldEventListener extends EventListener {
-
-    /**
-     * Process an event that has occurred on a node's event output.
-     *
-     * @param evt The event that caused this method to be called
-     */
-    void readableFieldChanged(X3DFieldEvent evt);
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001-2005
+ *                               Java Source
+ *
+ * This source is licensed under the BSD license.
+ * Please read docs/BSD.txt for the text of the license.
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.web3d.x3d.sai;
+
+// Standard imports
+import java.util.EventListener;
+
+// Application specific imports
+// None
+
+/**
+ * A listener for events on X3D fields
+ *
+ * @author Justin Couch
+ * @version $Revision: 1.5 $
+ */
+public interface X3DFieldEventListener extends EventListener {
+
+    /**
+     * Process an event that has occurred on a node's event output.
+     *
+     * @param evt The event that caused this method to be called
+     */
+    void readableFieldChanged(X3DFieldEvent evt);
+}
diff --git a/src/java/org/web3d/x3d/sai/X3DLayerNode.java b/src/java/org/web3d/x3d/sai/X3DLayerNode.java
index fab9e00a35e54eeec1153094158b585579aa71b0..23af622a5212c28828aa84ce09d93cb78b2f2a3f 100644
--- a/src/java/org/web3d/x3d/sai/X3DLayerNode.java
+++ b/src/java/org/web3d/x3d/sai/X3DLayerNode.java
@@ -1,44 +1,44 @@
-/***************************************************************************** 
- *                        Web3d.org Copyright (c) 2007 
- *                               Java Source 
- * 
- * This source is licensed under the GNU LGPL v2.1 
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
- * 
- * This software comes with the standard NO WARRANTY disclaimer for any 
- * purpose. Use it at your own risk. If there's a problem you get to fix it. 
- * 
- ****************************************************************************/ 
-
-package org.web3d.x3d.sai;
-
-import org.web3d.x3d.sai.X3DNode;
-import org.web3d.x3d.sai.X3DProtoInstance;
-import org.web3d.x3d.sai.X3DViewportNode;
-
-/** Defines the requirements of an X3DLayerNode abstract node type
- * @author Rex Melton
- * @version $Revision: 1.1 $ */
-public interface X3DLayerNode extends X3DNode {
-
-/** Return the isPickable boolean value. 
- * @return The isPickable boolean value.  */
-public boolean getIsPickable();
-
-/** Set the isPickable field. 
- * @param val The boolean to set.  */
-public void setIsPickable(boolean val);
-
-/** Return the viewport X3DNode value. 
- * @return The viewport X3DNode value.  */
-public X3DNode getViewport();
-
-/** Set the viewport field. 
- * @param val The X3DViewportNode to set.  */
-public void setViewport(X3DViewportNode val);
-
-/** Set the viewport field. 
- * @param val The X3DProtoInstance to set.  */
-public void setViewport(X3DProtoInstance val);
-
-}
+/***************************************************************************** 
+ *                        Web3d.org Copyright (c) 2007 
+ *                               Java Source 
+ * 
+ * This source is licensed under the GNU LGPL v2.1 
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
+ * 
+ * This software comes with the standard NO WARRANTY disclaimer for any 
+ * purpose. Use it at your own risk. If there's a problem you get to fix it. 
+ * 
+ ****************************************************************************/ 
+
+package org.web3d.x3d.sai;
+
+import org.web3d.x3d.sai.X3DNode;
+import org.web3d.x3d.sai.X3DProtoInstance;
+import org.web3d.x3d.sai.X3DViewportNode;
+
+/** Defines the requirements of an X3DLayerNode abstract node type
+ * @author Rex Melton
+ * @version $Revision: 1.1 $ */
+public interface X3DLayerNode extends X3DNode {
+
+/** Return the isPickable boolean value. 
+ * @return The isPickable boolean value.  */
+public boolean getIsPickable();
+
+/** Set the isPickable field. 
+ * @param val The boolean to set.  */
+public void setIsPickable(boolean val);
+
+/** Return the viewport X3DNode value. 
+ * @return The viewport X3DNode value.  */
+public X3DNode getViewport();
+
+/** Set the viewport field. 
+ * @param val The X3DViewportNode to set.  */
+public void setViewport(X3DViewportNode val);
+
+/** Set the viewport field. 
+ * @param val The X3DProtoInstance to set.  */
+public void setViewport(X3DProtoInstance val);
+
+}
diff --git a/src/java/org/web3d/x3d/sai/X3DRoute.java b/src/java/org/web3d/x3d/sai/X3DRoute.java
index a4bf5c56bf98a579006734ca3cc7fc42dc621024..021e74decf915fedfa90c9bbda2c8342b16172a1 100644
--- a/src/java/org/web3d/x3d/sai/X3DRoute.java
+++ b/src/java/org/web3d/x3d/sai/X3DRoute.java
@@ -14,6 +14,7 @@ package org.web3d.x3d.sai;
 
 /**
  * Representation of a ROUTE structure in X3D.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/web3d/x3d/sai/cadgeometry/CADAssembly.java b/src/java/org/web3d/x3d/sai/cadgeometry/CADAssembly.java
index 25363f163a9a04db88a642da2f2917efbededc80..5536e6541b0d94e011b0dd9ac4dc0e0b055a5e0d 100644
--- a/src/java/org/web3d/x3d/sai/cadgeometry/CADAssembly.java
+++ b/src/java/org/web3d/x3d/sai/cadgeometry/CADAssembly.java
@@ -1,23 +1,23 @@
-/***************************************************************************** 
- *                        Web3d.org Copyright (c) 2007 
- *                               Java Source 
- * 
- * This source is licensed under the GNU LGPL v2.1 
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
- * 
- * This software comes with the standard NO WARRANTY disclaimer for any 
- * purpose. Use it at your own risk. If there's a problem you get to fix it. 
- * 
- ****************************************************************************/ 
-
-package org.web3d.x3d.sai.cadgeometry;
-
-import org.web3d.x3d.sai.X3DGroupingNode;
-import org.web3d.x3d.sai.X3DProductStructureChildNode;
-
-/** Defines the requirements of an X3D CADAssembly node
- * @author Rex Melton
- * @version $Revision: 1.1 $ */
-public interface CADAssembly extends X3DGroupingNode, X3DProductStructureChildNode {
-
-}
+/***************************************************************************** 
+ *                        Web3d.org Copyright (c) 2007 
+ *                               Java Source 
+ * 
+ * This source is licensed under the GNU LGPL v2.1 
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
+ * 
+ * This software comes with the standard NO WARRANTY disclaimer for any 
+ * purpose. Use it at your own risk. If there's a problem you get to fix it. 
+ * 
+ ****************************************************************************/ 
+
+package org.web3d.x3d.sai.cadgeometry;
+
+import org.web3d.x3d.sai.X3DGroupingNode;
+import org.web3d.x3d.sai.X3DProductStructureChildNode;
+
+/** Defines the requirements of an X3D CADAssembly node
+ * @author Rex Melton
+ * @version $Revision: 1.1 $ */
+public interface CADAssembly extends X3DGroupingNode, X3DProductStructureChildNode {
+
+}
diff --git a/src/java/org/web3d/x3d/sai/cadgeometry/QuadSet.java b/src/java/org/web3d/x3d/sai/cadgeometry/QuadSet.java
index 5e5f5efd7a5d99f7f7ce84c40254b28402b510a1..c8c00330e86abdd43095b2d9cb0481c48df81cbd 100644
--- a/src/java/org/web3d/x3d/sai/cadgeometry/QuadSet.java
+++ b/src/java/org/web3d/x3d/sai/cadgeometry/QuadSet.java
@@ -1,22 +1,22 @@
-/***************************************************************************** 
- *                        Web3d.org Copyright (c) 2007 
- *                               Java Source 
- * 
- * This source is licensed under the GNU LGPL v2.1 
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
- * 
- * This software comes with the standard NO WARRANTY disclaimer for any 
- * purpose. Use it at your own risk. If there's a problem you get to fix it. 
- * 
- ****************************************************************************/ 
-
-package org.web3d.x3d.sai.cadgeometry;
-
-import org.web3d.x3d.sai.X3DComposedGeometryNode;
-
-/** Defines the requirements of an X3D QuadSet node
- * @author Rex Melton
- * @version $Revision: 1.1 $ */
-public interface QuadSet extends X3DComposedGeometryNode {
-
-}
+/***************************************************************************** 
+ *                        Web3d.org Copyright (c) 2007 
+ *                               Java Source 
+ * 
+ * This source is licensed under the GNU LGPL v2.1 
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
+ * 
+ * This software comes with the standard NO WARRANTY disclaimer for any 
+ * purpose. Use it at your own risk. If there's a problem you get to fix it. 
+ * 
+ ****************************************************************************/ 
+
+package org.web3d.x3d.sai.cadgeometry;
+
+import org.web3d.x3d.sai.X3DComposedGeometryNode;
+
+/** Defines the requirements of an X3D QuadSet node
+ * @author Rex Melton
+ * @version $Revision: 1.1 $ */
+public interface QuadSet extends X3DComposedGeometryNode {
+
+}
diff --git a/src/java/org/web3d/x3d/sai/environmentaleffects/Fog.java b/src/java/org/web3d/x3d/sai/environmentaleffects/Fog.java
index 6ae5f0d30f09a6590fe3e4f4fa817db00d16b2af..7cf8cd36aceec2223fd59c4c11fec9ec392a08eb 100644
--- a/src/java/org/web3d/x3d/sai/environmentaleffects/Fog.java
+++ b/src/java/org/web3d/x3d/sai/environmentaleffects/Fog.java
@@ -1,23 +1,23 @@
-/***************************************************************************** 
- *                        Web3d.org Copyright (c) 2007 
- *                               Java Source 
- * 
- * This source is licensed under the GNU LGPL v2.1 
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
- * 
- * This software comes with the standard NO WARRANTY disclaimer for any 
- * purpose. Use it at your own risk. If there's a problem you get to fix it. 
- * 
- ****************************************************************************/ 
-
-package org.web3d.x3d.sai.environmentaleffects;
-
-import org.web3d.x3d.sai.X3DBindableNode;
-import org.web3d.x3d.sai.X3DFogObject;
-
-/** Defines the requirements of an X3D Fog node
- * @author Rex Melton
- * @version $Revision: 1.1 $ */
-public interface Fog extends X3DBindableNode, X3DFogObject {
-
-}
+/***************************************************************************** 
+ *                        Web3d.org Copyright (c) 2007 
+ *                               Java Source 
+ * 
+ * This source is licensed under the GNU LGPL v2.1 
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
+ * 
+ * This software comes with the standard NO WARRANTY disclaimer for any 
+ * purpose. Use it at your own risk. If there's a problem you get to fix it. 
+ * 
+ ****************************************************************************/ 
+
+package org.web3d.x3d.sai.environmentaleffects;
+
+import org.web3d.x3d.sai.X3DBindableNode;
+import org.web3d.x3d.sai.X3DFogObject;
+
+/** Defines the requirements of an X3D Fog node
+ * @author Rex Melton
+ * @version $Revision: 1.1 $ */
+public interface Fog extends X3DBindableNode, X3DFogObject {
+
+}
diff --git a/src/java/org/web3d/x3d/sai/environmentalsensor/VisibilitySensor.java b/src/java/org/web3d/x3d/sai/environmentalsensor/VisibilitySensor.java
index 111b1ebfb2adea2499cdf8ca786c759dc5765172..30f8b6133897a28e33bfb614dc5d6e9fd5d6e97c 100644
--- a/src/java/org/web3d/x3d/sai/environmentalsensor/VisibilitySensor.java
+++ b/src/java/org/web3d/x3d/sai/environmentalsensor/VisibilitySensor.java
@@ -1,22 +1,22 @@
-/***************************************************************************** 
- *                        Web3d.org Copyright (c) 2007 
- *                               Java Source 
- * 
- * This source is licensed under the GNU LGPL v2.1 
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
- * 
- * This software comes with the standard NO WARRANTY disclaimer for any 
- * purpose. Use it at your own risk. If there's a problem you get to fix it. 
- * 
- ****************************************************************************/ 
-
-package org.web3d.x3d.sai.environmentalsensor;
-
-import org.web3d.x3d.sai.X3DEnvironmentalSensorNode;
-
-/** Defines the requirements of an X3D VisibilitySensor node
- * @author Rex Melton
- * @version $Revision: 1.1 $ */
-public interface VisibilitySensor extends X3DEnvironmentalSensorNode {
-
-}
+/***************************************************************************** 
+ *                        Web3d.org Copyright (c) 2007 
+ *                               Java Source 
+ * 
+ * This source is licensed under the GNU LGPL v2.1 
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
+ * 
+ * This software comes with the standard NO WARRANTY disclaimer for any 
+ * purpose. Use it at your own risk. If there's a problem you get to fix it. 
+ * 
+ ****************************************************************************/ 
+
+package org.web3d.x3d.sai.environmentalsensor;
+
+import org.web3d.x3d.sai.X3DEnvironmentalSensorNode;
+
+/** Defines the requirements of an X3D VisibilitySensor node
+ * @author Rex Melton
+ * @version $Revision: 1.1 $ */
+public interface VisibilitySensor extends X3DEnvironmentalSensorNode {
+
+}
diff --git a/src/java/org/web3d/x3d/sai/layering/CustomViewport.java b/src/java/org/web3d/x3d/sai/layering/CustomViewport.java
index 9a3cede8e068e1bac064a2f471fe4f148dd75a14..4eaafb64210640e1dd6d36de9bee01cf11e8f25a 100644
--- a/src/java/org/web3d/x3d/sai/layering/CustomViewport.java
+++ b/src/java/org/web3d/x3d/sai/layering/CustomViewport.java
@@ -1,86 +1,86 @@
-/***************************************************************************** 
- *                        Web3d.org Copyright (c) 2007 
- *                               Java Source 
- * 
- * This source is licensed under the GNU LGPL v2.1 
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
- * 
- * This software comes with the standard NO WARRANTY disclaimer for any 
- * purpose. Use it at your own risk. If there's a problem you get to fix it. 
- * 
- ****************************************************************************/ 
-
-package org.web3d.x3d.sai.layering;
-
-import org.web3d.x3d.sai.X3DNode;
-
-/** Defines the requirements of an X3D CustomViewport node
- * @author Rex Melton
- * @version $Revision: 1.1 $ */
-public interface CustomViewport extends X3DNode {
-
-/** Return the fixedX boolean value. 
- * @return The fixedX boolean value.  */
-public boolean getFixedX();
-
-/** Set the fixedX field. 
- * @param val The boolean to set.  */
-public void setFixedX(boolean val);
-
-/** Return the fixedY boolean value. 
- * @return The fixedY boolean value.  */
-public boolean getFixedY();
-
-/** Set the fixedY field. 
- * @param val The boolean to set.  */
-public void setFixedY(boolean val);
-
-/** Return the fixedWidth boolean value. 
- * @return The fixedWidth boolean value.  */
-public boolean getFixedWidth();
-
-/** Set the fixedWidth field. 
- * @param val The boolean to set.  */
-public void setFixedWidth(boolean val);
-
-/** Return the fixedHeight boolean value. 
- * @return The fixedHeight boolean value.  */
-public boolean getFixedHeight();
-
-/** Set the fixedHeight field. 
- * @param val The boolean to set.  */
-public void setFixedHeight(boolean val);
-
-/** Return the x float value. 
- * @return The x float value.  */
-public float getX();
-
-/** Set the x field. 
- * @param val The float to set.  */
-public void setX(float val);
-
-/** Return the y float value. 
- * @return The y float value.  */
-public float getY();
-
-/** Set the y field. 
- * @param val The float to set.  */
-public void setY(float val);
-
-/** Return the width float value. 
- * @return The width float value.  */
-public float getWidth();
-
-/** Set the width field. 
- * @param val The float to set.  */
-public void setWidth(float val);
-
-/** Return the height float value. 
- * @return The height float value.  */
-public float getHeight();
-
-/** Set the height field. 
- * @param val The float to set.  */
-public void setHeight(float val);
-
-}
+/***************************************************************************** 
+ *                        Web3d.org Copyright (c) 2007 
+ *                               Java Source 
+ * 
+ * This source is licensed under the GNU LGPL v2.1 
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
+ * 
+ * This software comes with the standard NO WARRANTY disclaimer for any 
+ * purpose. Use it at your own risk. If there's a problem you get to fix it. 
+ * 
+ ****************************************************************************/ 
+
+package org.web3d.x3d.sai.layering;
+
+import org.web3d.x3d.sai.X3DNode;
+
+/** Defines the requirements of an X3D CustomViewport node
+ * @author Rex Melton
+ * @version $Revision: 1.1 $ */
+public interface CustomViewport extends X3DNode {
+
+/** Return the fixedX boolean value. 
+ * @return The fixedX boolean value.  */
+public boolean getFixedX();
+
+/** Set the fixedX field. 
+ * @param val The boolean to set.  */
+public void setFixedX(boolean val);
+
+/** Return the fixedY boolean value. 
+ * @return The fixedY boolean value.  */
+public boolean getFixedY();
+
+/** Set the fixedY field. 
+ * @param val The boolean to set.  */
+public void setFixedY(boolean val);
+
+/** Return the fixedWidth boolean value. 
+ * @return The fixedWidth boolean value.  */
+public boolean getFixedWidth();
+
+/** Set the fixedWidth field. 
+ * @param val The boolean to set.  */
+public void setFixedWidth(boolean val);
+
+/** Return the fixedHeight boolean value. 
+ * @return The fixedHeight boolean value.  */
+public boolean getFixedHeight();
+
+/** Set the fixedHeight field. 
+ * @param val The boolean to set.  */
+public void setFixedHeight(boolean val);
+
+/** Return the x float value. 
+ * @return The x float value.  */
+public float getX();
+
+/** Set the x field. 
+ * @param val The float to set.  */
+public void setX(float val);
+
+/** Return the y float value. 
+ * @return The y float value.  */
+public float getY();
+
+/** Set the y field. 
+ * @param val The float to set.  */
+public void setY(float val);
+
+/** Return the width float value. 
+ * @return The width float value.  */
+public float getWidth();
+
+/** Set the width field. 
+ * @param val The float to set.  */
+public void setWidth(float val);
+
+/** Return the height float value. 
+ * @return The height float value.  */
+public float getHeight();
+
+/** Set the height field. 
+ * @param val The float to set.  */
+public void setHeight(float val);
+
+}
diff --git a/src/java/org/web3d/x3d/sai/layering/FixedViewport.java b/src/java/org/web3d/x3d/sai/layering/FixedViewport.java
index e9e7140326a0f85953eb2b23f6b7ef0d534729c2..90cb091c09c226b68a517cc9f344b5db939ceaf7 100644
--- a/src/java/org/web3d/x3d/sai/layering/FixedViewport.java
+++ b/src/java/org/web3d/x3d/sai/layering/FixedViewport.java
@@ -1,54 +1,54 @@
-/***************************************************************************** 
- *                        Web3d.org Copyright (c) 2007 
- *                               Java Source 
- * 
- * This source is licensed under the GNU LGPL v2.1 
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
- * 
- * This software comes with the standard NO WARRANTY disclaimer for any 
- * purpose. Use it at your own risk. If there's a problem you get to fix it. 
- * 
- ****************************************************************************/ 
-
-package org.web3d.x3d.sai.layering;
-
-import org.web3d.x3d.sai.X3DNode;
-
-/** Defines the requirements of an X3D FixedViewport node
- * @author Rex Melton
- * @version $Revision: 1.1 $ */
-public interface FixedViewport extends X3DNode {
-
-/** Return the x int value. 
- * @return The x int value.  */
-public int getX();
-
-/** Set the x field. 
- * @param val The int to set.  */
-public void setX(int val);
-
-/** Return the y int value. 
- * @return The y int value.  */
-public int getY();
-
-/** Set the y field. 
- * @param val The int to set.  */
-public void setY(int val);
-
-/** Return the width int value. 
- * @return The width int value.  */
-public int getWidth();
-
-/** Set the width field. 
- * @param val The int to set.  */
-public void setWidth(int val);
-
-/** Return the height int value. 
- * @return The height int value.  */
-public int getHeight();
-
-/** Set the height field. 
- * @param val The int to set.  */
-public void setHeight(int val);
-
-}
+/***************************************************************************** 
+ *                        Web3d.org Copyright (c) 2007 
+ *                               Java Source 
+ * 
+ * This source is licensed under the GNU LGPL v2.1 
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
+ * 
+ * This software comes with the standard NO WARRANTY disclaimer for any 
+ * purpose. Use it at your own risk. If there's a problem you get to fix it. 
+ * 
+ ****************************************************************************/ 
+
+package org.web3d.x3d.sai.layering;
+
+import org.web3d.x3d.sai.X3DNode;
+
+/** Defines the requirements of an X3D FixedViewport node
+ * @author Rex Melton
+ * @version $Revision: 1.1 $ */
+public interface FixedViewport extends X3DNode {
+
+/** Return the x int value. 
+ * @return The x int value.  */
+public int getX();
+
+/** Set the x field. 
+ * @param val The int to set.  */
+public void setX(int val);
+
+/** Return the y int value. 
+ * @return The y int value.  */
+public int getY();
+
+/** Set the y field. 
+ * @param val The int to set.  */
+public void setY(int val);
+
+/** Return the width int value. 
+ * @return The width int value.  */
+public int getWidth();
+
+/** Set the width field. 
+ * @param val The int to set.  */
+public void setWidth(int val);
+
+/** Return the height int value. 
+ * @return The height int value.  */
+public int getHeight();
+
+/** Set the height field. 
+ * @param val The int to set.  */
+public void setHeight(int val);
+
+}
diff --git a/src/java/org/web3d/x3d/sai/layering/Layer.java b/src/java/org/web3d/x3d/sai/layering/Layer.java
index 90665ea19cd7bc13283f6ff839fd56c2e7214f3c..135646f959792dbe1a2928a0d98615c84ccf80ed 100644
--- a/src/java/org/web3d/x3d/sai/layering/Layer.java
+++ b/src/java/org/web3d/x3d/sai/layering/Layer.java
@@ -1,43 +1,43 @@
-/***************************************************************************** 
- *                        Web3d.org Copyright (c) 2007 
- *                               Java Source 
- * 
- * This source is licensed under the GNU LGPL v2.1 
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
- * 
- * This software comes with the standard NO WARRANTY disclaimer for any 
- * purpose. Use it at your own risk. If there's a problem you get to fix it. 
- * 
- ****************************************************************************/ 
-
-package org.web3d.x3d.sai.layering;
-
-import org.web3d.x3d.sai.X3DLayerNode;
-import org.web3d.x3d.sai.X3DNode;
-
-/** Defines the requirements of an X3D Layer node
- * @author Rex Melton
- * @version $Revision: 1.1 $ */
-public interface Layer extends X3DLayerNode {
-
-/** Set the addChildren field. 
- * @param val The X3DNode[] to set.  */
-public void addChildren(X3DNode[] val);
-
-/** Set the removeChildren field. 
- * @param val The X3DNode[] to set.  */
-public void removeChildren(X3DNode[] val);
-
-/** Return the number of MFNode items in the children field. 
- * @return the number of MFNode items in the children field.  */
-public int getNumChildren();
-
-/** Return the children value in the argument X3DNode[]
- * @param val The X3DNode[] to initialize.  */
-public void getChildren(X3DNode[] val);
-
-/** Set the children field. 
- * @param val The X3DNode[] to set.  */
-public void setChildren(X3DNode[] val);
-
-}
+/***************************************************************************** 
+ *                        Web3d.org Copyright (c) 2007 
+ *                               Java Source 
+ * 
+ * This source is licensed under the GNU LGPL v2.1 
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
+ * 
+ * This software comes with the standard NO WARRANTY disclaimer for any 
+ * purpose. Use it at your own risk. If there's a problem you get to fix it. 
+ * 
+ ****************************************************************************/ 
+
+package org.web3d.x3d.sai.layering;
+
+import org.web3d.x3d.sai.X3DLayerNode;
+import org.web3d.x3d.sai.X3DNode;
+
+/** Defines the requirements of an X3D Layer node
+ * @author Rex Melton
+ * @version $Revision: 1.1 $ */
+public interface Layer extends X3DLayerNode {
+
+/** Set the addChildren field. 
+ * @param val The X3DNode[] to set.  */
+public void addChildren(X3DNode[] val);
+
+/** Set the removeChildren field. 
+ * @param val The X3DNode[] to set.  */
+public void removeChildren(X3DNode[] val);
+
+/** Return the number of MFNode items in the children field. 
+ * @return the number of MFNode items in the children field.  */
+public int getNumChildren();
+
+/** Return the children value in the argument X3DNode[]
+ * @param val The X3DNode[] to initialize.  */
+public void getChildren(X3DNode[] val);
+
+/** Set the children field. 
+ * @param val The X3DNode[] to set.  */
+public void setChildren(X3DNode[] val);
+
+}
diff --git a/src/java/org/web3d/x3d/sai/layering/LayerSet.java b/src/java/org/web3d/x3d/sai/layering/LayerSet.java
index d3db93f1af26207bf82902c74aebc0778d42029a..1c7298631b7910bde8f72f3048b0cebd46aa8a35 100644
--- a/src/java/org/web3d/x3d/sai/layering/LayerSet.java
+++ b/src/java/org/web3d/x3d/sai/layering/LayerSet.java
@@ -1,54 +1,54 @@
-/***************************************************************************** 
- *                        Web3d.org Copyright (c) 2007 
- *                               Java Source 
- * 
- * This source is licensed under the GNU LGPL v2.1 
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
- * 
- * This software comes with the standard NO WARRANTY disclaimer for any 
- * purpose. Use it at your own risk. If there's a problem you get to fix it. 
- * 
- ****************************************************************************/ 
-
-package org.web3d.x3d.sai.layering;
-
-import org.web3d.x3d.sai.X3DNode;
-
-/** Defines the requirements of an X3D LayerSet node
- * @author Rex Melton
- * @version $Revision: 1.1 $ */
-public interface LayerSet extends X3DNode {
-
-/** Return the number of MFNode items in the layers field. 
- * @return the number of MFNode items in the layers field.  */
-public int getNumLayers();
-
-/** Return the layers value in the argument X3DNode[]
- * @param val The X3DNode[] to initialize.  */
-public void getLayers(X3DNode[] val);
-
-/** Set the layers field. 
- * @param val The X3DNode[] to set.  */
-public void setLayers(X3DNode[] val);
-
-/** Return the activeLayer int value. 
- * @return The activeLayer int value.  */
-public int getActiveLayer();
-
-/** Set the activeLayer field. 
- * @param val The int to set.  */
-public void setActiveLayer(int val);
-
-/** Return the number of MFInt32 items in the order field. 
- * @return the number of MFInt32 items in the order field.  */
-public int getNumOrder();
-
-/** Return the order value in the argument int[]
- * @param val The int[] to initialize.  */
-public void getOrder(int[] val);
-
-/** Set the order field. 
- * @param val The int[] to set.  */
-public void setOrder(int[] val);
-
-}
+/***************************************************************************** 
+ *                        Web3d.org Copyright (c) 2007 
+ *                               Java Source 
+ * 
+ * This source is licensed under the GNU LGPL v2.1 
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
+ * 
+ * This software comes with the standard NO WARRANTY disclaimer for any 
+ * purpose. Use it at your own risk. If there's a problem you get to fix it. 
+ * 
+ ****************************************************************************/ 
+
+package org.web3d.x3d.sai.layering;
+
+import org.web3d.x3d.sai.X3DNode;
+
+/** Defines the requirements of an X3D LayerSet node
+ * @author Rex Melton
+ * @version $Revision: 1.1 $ */
+public interface LayerSet extends X3DNode {
+
+/** Return the number of MFNode items in the layers field. 
+ * @return the number of MFNode items in the layers field.  */
+public int getNumLayers();
+
+/** Return the layers value in the argument X3DNode[]
+ * @param val The X3DNode[] to initialize.  */
+public void getLayers(X3DNode[] val);
+
+/** Set the layers field. 
+ * @param val The X3DNode[] to set.  */
+public void setLayers(X3DNode[] val);
+
+/** Return the activeLayer int value. 
+ * @return The activeLayer int value.  */
+public int getActiveLayer();
+
+/** Set the activeLayer field. 
+ * @param val The int to set.  */
+public void setActiveLayer(int val);
+
+/** Return the number of MFInt32 items in the order field. 
+ * @return the number of MFInt32 items in the order field.  */
+public int getNumOrder();
+
+/** Return the order value in the argument int[]
+ * @param val The int[] to initialize.  */
+public void getOrder(int[] val);
+
+/** Set the order field. 
+ * @param val The int[] to set.  */
+public void setOrder(int[] val);
+
+}
diff --git a/src/java/org/web3d/x3d/sai/layering/ProportionalViewport.java b/src/java/org/web3d/x3d/sai/layering/ProportionalViewport.java
index 249cf028467c0fc5095ed071cd46fa65f6d11596..5fc60ef7e23d66440052db0f044370c88dce63a4 100644
--- a/src/java/org/web3d/x3d/sai/layering/ProportionalViewport.java
+++ b/src/java/org/web3d/x3d/sai/layering/ProportionalViewport.java
@@ -1,54 +1,54 @@
-/***************************************************************************** 
- *                        Web3d.org Copyright (c) 2007 
- *                               Java Source 
- * 
- * This source is licensed under the GNU LGPL v2.1 
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
- * 
- * This software comes with the standard NO WARRANTY disclaimer for any 
- * purpose. Use it at your own risk. If there's a problem you get to fix it. 
- * 
- ****************************************************************************/ 
-
-package org.web3d.x3d.sai.layering;
-
-import org.web3d.x3d.sai.X3DNode;
-
-/** Defines the requirements of an X3D ProportionalViewport node
- * @author Rex Melton
- * @version $Revision: 1.1 $ */
-public interface ProportionalViewport extends X3DNode {
-
-/** Return the x float value. 
- * @return The x float value.  */
-public float getX();
-
-/** Set the x field. 
- * @param val The float to set.  */
-public void setX(float val);
-
-/** Return the y float value. 
- * @return The y float value.  */
-public float getY();
-
-/** Set the y field. 
- * @param val The float to set.  */
-public void setY(float val);
-
-/** Return the width float value. 
- * @return The width float value.  */
-public float getWidth();
-
-/** Set the width field. 
- * @param val The float to set.  */
-public void setWidth(float val);
-
-/** Return the height float value. 
- * @return The height float value.  */
-public float getHeight();
-
-/** Set the height field. 
- * @param val The float to set.  */
-public void setHeight(float val);
-
-}
+/***************************************************************************** 
+ *                        Web3d.org Copyright (c) 2007 
+ *                               Java Source 
+ * 
+ * This source is licensed under the GNU LGPL v2.1 
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
+ * 
+ * This software comes with the standard NO WARRANTY disclaimer for any 
+ * purpose. Use it at your own risk. If there's a problem you get to fix it. 
+ * 
+ ****************************************************************************/ 
+
+package org.web3d.x3d.sai.layering;
+
+import org.web3d.x3d.sai.X3DNode;
+
+/** Defines the requirements of an X3D ProportionalViewport node
+ * @author Rex Melton
+ * @version $Revision: 1.1 $ */
+public interface ProportionalViewport extends X3DNode {
+
+/** Return the x float value. 
+ * @return The x float value.  */
+public float getX();
+
+/** Set the x field. 
+ * @param val The float to set.  */
+public void setX(float val);
+
+/** Return the y float value. 
+ * @return The y float value.  */
+public float getY();
+
+/** Set the y field. 
+ * @param val The float to set.  */
+public void setY(float val);
+
+/** Return the width float value. 
+ * @return The width float value.  */
+public float getWidth();
+
+/** Set the width field. 
+ * @param val The float to set.  */
+public void setWidth(float val);
+
+/** Return the height float value. 
+ * @return The height float value.  */
+public float getHeight();
+
+/** Set the height field. 
+ * @param val The float to set.  */
+public void setHeight(float val);
+
+}
diff --git a/src/java/org/web3d/x3d/sai/pickingsensor/PickableGroup.java b/src/java/org/web3d/x3d/sai/pickingsensor/PickableGroup.java
index f018003d85eba28b2991fe6e6321cc36a88701b6..a0a8618ac386275dbba62e672d697725c55e8bb8 100644
--- a/src/java/org/web3d/x3d/sai/pickingsensor/PickableGroup.java
+++ b/src/java/org/web3d/x3d/sai/pickingsensor/PickableGroup.java
@@ -1,23 +1,23 @@
-/***************************************************************************** 
- *                        Web3d.org Copyright (c) 2007 
- *                               Java Source 
- * 
- * This source is licensed under the GNU LGPL v2.1 
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
- * 
- * This software comes with the standard NO WARRANTY disclaimer for any 
- * purpose. Use it at your own risk. If there's a problem you get to fix it. 
- * 
- ****************************************************************************/ 
-
-package org.web3d.x3d.sai.pickingsensor;
-
-import org.web3d.x3d.sai.X3DGroupingNode;
-import org.web3d.x3d.sai.X3DPickableObject;
-
-/** Defines the requirements of an X3D PickableGroup node
- * @author Rex Melton
- * @version $Revision: 1.1 $ */
-public interface PickableGroup extends X3DGroupingNode, X3DPickableObject {
-
-}
+/***************************************************************************** 
+ *                        Web3d.org Copyright (c) 2007 
+ *                               Java Source 
+ * 
+ * This source is licensed under the GNU LGPL v2.1 
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
+ * 
+ * This software comes with the standard NO WARRANTY disclaimer for any 
+ * purpose. Use it at your own risk. If there's a problem you get to fix it. 
+ * 
+ ****************************************************************************/ 
+
+package org.web3d.x3d.sai.pickingsensor;
+
+import org.web3d.x3d.sai.X3DGroupingNode;
+import org.web3d.x3d.sai.X3DPickableObject;
+
+/** Defines the requirements of an X3D PickableGroup node
+ * @author Rex Melton
+ * @version $Revision: 1.1 $ */
+public interface PickableGroup extends X3DGroupingNode, X3DPickableObject {
+
+}
diff --git a/src/java/org/web3d/x3d/sai/pickingsensor/VolumePicker.java b/src/java/org/web3d/x3d/sai/pickingsensor/VolumePicker.java
index 9193d728fe28596daeaa41be9466bfdaab8db14f..de9864803bc1d09f4922a46bc13b162d14d8652a 100644
--- a/src/java/org/web3d/x3d/sai/pickingsensor/VolumePicker.java
+++ b/src/java/org/web3d/x3d/sai/pickingsensor/VolumePicker.java
@@ -1,22 +1,22 @@
-/***************************************************************************** 
- *                        Web3d.org Copyright (c) 2007 
- *                               Java Source 
- * 
- * This source is licensed under the GNU LGPL v2.1 
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
- * 
- * This software comes with the standard NO WARRANTY disclaimer for any 
- * purpose. Use it at your own risk. If there's a problem you get to fix it. 
- * 
- ****************************************************************************/ 
-
-package org.web3d.x3d.sai.pickingsensor;
-
-import org.web3d.x3d.sai.X3DPickingNode;
-
-/** Defines the requirements of an X3D VolumePicker node
- * @author Rex Melton
- * @version $Revision: 1.1 $ */
-public interface VolumePicker extends X3DPickingNode {
-
-}
+/***************************************************************************** 
+ *                        Web3d.org Copyright (c) 2007 
+ *                               Java Source 
+ * 
+ * This source is licensed under the GNU LGPL v2.1 
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
+ * 
+ * This software comes with the standard NO WARRANTY disclaimer for any 
+ * purpose. Use it at your own risk. If there's a problem you get to fix it. 
+ * 
+ ****************************************************************************/ 
+
+package org.web3d.x3d.sai.pickingsensor;
+
+import org.web3d.x3d.sai.X3DPickingNode;
+
+/** Defines the requirements of an X3D VolumePicker node
+ * @author Rex Melton
+ * @version $Revision: 1.1 $ */
+public interface VolumePicker extends X3DPickingNode {
+
+}
diff --git a/src/java/org/web3d/x3d/sai/rendering/Color.java b/src/java/org/web3d/x3d/sai/rendering/Color.java
index 05989ed3ce99eda65b966272850051b31fa7e1ca..3990db45d5a55d68de11fc0369be5ed92607000f 100644
--- a/src/java/org/web3d/x3d/sai/rendering/Color.java
+++ b/src/java/org/web3d/x3d/sai/rendering/Color.java
@@ -1,22 +1,22 @@
-/***************************************************************************** 
- *                        Web3d.org Copyright (c) 2007 
- *                               Java Source 
- * 
- * This source is licensed under the GNU LGPL v2.1 
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
- * 
- * This software comes with the standard NO WARRANTY disclaimer for any 
- * purpose. Use it at your own risk. If there's a problem you get to fix it. 
- * 
- ****************************************************************************/ 
-
-package org.web3d.x3d.sai.rendering;
-
-import org.web3d.x3d.sai.X3DColorNode;
-
-/** Defines the requirements of an X3D Color node
- * @author Rex Melton
- * @version $Revision: 1.1 $ */
-public interface Color extends X3DColorNode {
-
-}
+/***************************************************************************** 
+ *                        Web3d.org Copyright (c) 2007 
+ *                               Java Source 
+ * 
+ * This source is licensed under the GNU LGPL v2.1 
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
+ * 
+ * This software comes with the standard NO WARRANTY disclaimer for any 
+ * purpose. Use it at your own risk. If there's a problem you get to fix it. 
+ * 
+ ****************************************************************************/ 
+
+package org.web3d.x3d.sai.rendering;
+
+import org.web3d.x3d.sai.X3DColorNode;
+
+/** Defines the requirements of an X3D Color node
+ * @author Rex Melton
+ * @version $Revision: 1.1 $ */
+public interface Color extends X3DColorNode {
+
+}
diff --git a/src/java/org/web3d/x3d/sai/rendering/ColorRGBA.java b/src/java/org/web3d/x3d/sai/rendering/ColorRGBA.java
index d50aee3989fbf153eb08de5a018bee70eda555f9..afa0ddd4d61f31abf60acc190e602bea451f3423 100644
--- a/src/java/org/web3d/x3d/sai/rendering/ColorRGBA.java
+++ b/src/java/org/web3d/x3d/sai/rendering/ColorRGBA.java
@@ -1,22 +1,22 @@
-/***************************************************************************** 
- *                        Web3d.org Copyright (c) 2007 
- *                               Java Source 
- * 
- * This source is licensed under the GNU LGPL v2.1 
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
- * 
- * This software comes with the standard NO WARRANTY disclaimer for any 
- * purpose. Use it at your own risk. If there's a problem you get to fix it. 
- * 
- ****************************************************************************/ 
-
-package org.web3d.x3d.sai.rendering;
-
-import org.web3d.x3d.sai.X3DColorNode;
-
-/** Defines the requirements of an X3D ColorRGBA node
- * @author Rex Melton
- * @version $Revision: 1.1 $ */
-public interface ColorRGBA extends X3DColorNode {
-
-}
+/***************************************************************************** 
+ *                        Web3d.org Copyright (c) 2007 
+ *                               Java Source 
+ * 
+ * This source is licensed under the GNU LGPL v2.1 
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
+ * 
+ * This software comes with the standard NO WARRANTY disclaimer for any 
+ * purpose. Use it at your own risk. If there's a problem you get to fix it. 
+ * 
+ ****************************************************************************/ 
+
+package org.web3d.x3d.sai.rendering;
+
+import org.web3d.x3d.sai.X3DColorNode;
+
+/** Defines the requirements of an X3D ColorRGBA node
+ * @author Rex Melton
+ * @version $Revision: 1.1 $ */
+public interface ColorRGBA extends X3DColorNode {
+
+}
diff --git a/src/java/org/web3d/x3d/sai/rendering/TriangleSet.java b/src/java/org/web3d/x3d/sai/rendering/TriangleSet.java
index 95858646a035c0d533e43193dee3a90d2ae3da03..470c7833190208019d6e7901691071ed72b42f64 100644
--- a/src/java/org/web3d/x3d/sai/rendering/TriangleSet.java
+++ b/src/java/org/web3d/x3d/sai/rendering/TriangleSet.java
@@ -1,22 +1,22 @@
-/***************************************************************************** 
- *                        Web3d.org Copyright (c) 2007 
- *                               Java Source 
- * 
- * This source is licensed under the GNU LGPL v2.1 
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
- * 
- * This software comes with the standard NO WARRANTY disclaimer for any 
- * purpose. Use it at your own risk. If there's a problem you get to fix it. 
- * 
- ****************************************************************************/ 
-
-package org.web3d.x3d.sai.rendering;
-
-import org.web3d.x3d.sai.X3DComposedGeometryNode;
-
-/** Defines the requirements of an X3D TriangleSet node
- * @author Rex Melton
- * @version $Revision: 1.1 $ */
-public interface TriangleSet extends X3DComposedGeometryNode {
-
-}
+/***************************************************************************** 
+ *                        Web3d.org Copyright (c) 2007 
+ *                               Java Source 
+ * 
+ * This source is licensed under the GNU LGPL v2.1 
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
+ * 
+ * This software comes with the standard NO WARRANTY disclaimer for any 
+ * purpose. Use it at your own risk. If there's a problem you get to fix it. 
+ * 
+ ****************************************************************************/ 
+
+package org.web3d.x3d.sai.rendering;
+
+import org.web3d.x3d.sai.X3DComposedGeometryNode;
+
+/** Defines the requirements of an X3D TriangleSet node
+ * @author Rex Melton
+ * @version $Revision: 1.1 $ */
+public interface TriangleSet extends X3DComposedGeometryNode {
+
+}
diff --git a/src/java/org/web3d/x3d/sai/rigidbodyphysics/CollisionSensor.java b/src/java/org/web3d/x3d/sai/rigidbodyphysics/CollisionSensor.java
index ac79dcb3357cac854e86a45500dcaa1b00150008..60c9c119a83a8365da18b396fb57b0a3c8a4518d 100644
--- a/src/java/org/web3d/x3d/sai/rigidbodyphysics/CollisionSensor.java
+++ b/src/java/org/web3d/x3d/sai/rigidbodyphysics/CollisionSensor.java
@@ -1,47 +1,47 @@
-/***************************************************************************** 
- *                        Web3d.org Copyright (c) 2007 
- *                               Java Source 
- * 
- * This source is licensed under the GNU LGPL v2.1 
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
- * 
- * This software comes with the standard NO WARRANTY disclaimer for any 
- * purpose. Use it at your own risk. If there's a problem you get to fix it. 
- * 
- ****************************************************************************/ 
-
-package org.web3d.x3d.sai.rigidbodyphysics;
-
-import org.web3d.x3d.sai.X3DNode;
-import org.web3d.x3d.sai.X3DSensorNode;
-
-/** Defines the requirements of an X3D CollisionSensor node
- * @author Rex Melton
- * @version $Revision: 1.1 $ */
-public interface CollisionSensor extends X3DSensorNode {
-
-/** Return the collidables X3DNode value. 
- * @return The collidables X3DNode value.  */
-public X3DNode getCollidables();
-
-/** Set the collidables field. 
- * @param val The X3DNode to set.  */
-public void setCollidables(X3DNode val);
-
-/** Return the number of MFNode items in the contacts field. 
- * @return the number of MFNode items in the contacts field.  */
-public int getNumContacts();
-
-/** Return the contacts value in the argument X3DNode[]
- * @param val The X3DNode[] to initialize.  */
-public void getContacts(X3DNode[] val);
-
-/** Return the number of MFNode items in the intersections field. 
- * @return the number of MFNode items in the intersections field.  */
-public int getNumIntersections();
-
-/** Return the intersections value in the argument X3DNode[]
- * @param val The X3DNode[] to initialize.  */
-public void getIntersections(X3DNode[] val);
-
-}
+/***************************************************************************** 
+ *                        Web3d.org Copyright (c) 2007 
+ *                               Java Source 
+ * 
+ * This source is licensed under the GNU LGPL v2.1 
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
+ * 
+ * This software comes with the standard NO WARRANTY disclaimer for any 
+ * purpose. Use it at your own risk. If there's a problem you get to fix it. 
+ * 
+ ****************************************************************************/ 
+
+package org.web3d.x3d.sai.rigidbodyphysics;
+
+import org.web3d.x3d.sai.X3DNode;
+import org.web3d.x3d.sai.X3DSensorNode;
+
+/** Defines the requirements of an X3D CollisionSensor node
+ * @author Rex Melton
+ * @version $Revision: 1.1 $ */
+public interface CollisionSensor extends X3DSensorNode {
+
+/** Return the collidables X3DNode value. 
+ * @return The collidables X3DNode value.  */
+public X3DNode getCollidables();
+
+/** Set the collidables field. 
+ * @param val The X3DNode to set.  */
+public void setCollidables(X3DNode val);
+
+/** Return the number of MFNode items in the contacts field. 
+ * @return the number of MFNode items in the contacts field.  */
+public int getNumContacts();
+
+/** Return the contacts value in the argument X3DNode[]
+ * @param val The X3DNode[] to initialize.  */
+public void getContacts(X3DNode[] val);
+
+/** Return the number of MFNode items in the intersections field. 
+ * @return the number of MFNode items in the intersections field.  */
+public int getNumIntersections();
+
+/** Return the intersections value in the argument X3DNode[]
+ * @param val The X3DNode[] to initialize.  */
+public void getIntersections(X3DNode[] val);
+
+}
diff --git a/src/java/org/web3d/x3d/sai/sound/AudioClip.java b/src/java/org/web3d/x3d/sai/sound/AudioClip.java
index 49877a6ea3caa2bd665cd5b9869b6ec4d7d856ab..11fd1fc828fa103f1c79bb4bf06fc1c49a725191 100644
--- a/src/java/org/web3d/x3d/sai/sound/AudioClip.java
+++ b/src/java/org/web3d/x3d/sai/sound/AudioClip.java
@@ -1,23 +1,23 @@
-/***************************************************************************** 
- *                        Web3d.org Copyright (c) 2007 
- *                               Java Source 
- * 
- * This source is licensed under the GNU LGPL v2.1 
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
- * 
- * This software comes with the standard NO WARRANTY disclaimer for any 
- * purpose. Use it at your own risk. If there's a problem you get to fix it. 
- * 
- ****************************************************************************/ 
-
-package org.web3d.x3d.sai.sound;
-
-import org.web3d.x3d.sai.X3DSoundSourceNode;
-import org.web3d.x3d.sai.X3DUrlObject;
-
-/** Defines the requirements of an X3D AudioClip node
- * @author Rex Melton
- * @version $Revision: 1.1 $ */
-public interface AudioClip extends X3DSoundSourceNode, X3DUrlObject {
-
-}
+/***************************************************************************** 
+ *                        Web3d.org Copyright (c) 2007 
+ *                               Java Source 
+ * 
+ * This source is licensed under the GNU LGPL v2.1 
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
+ * 
+ * This software comes with the standard NO WARRANTY disclaimer for any 
+ * purpose. Use it at your own risk. If there's a problem you get to fix it. 
+ * 
+ ****************************************************************************/ 
+
+package org.web3d.x3d.sai.sound;
+
+import org.web3d.x3d.sai.X3DSoundSourceNode;
+import org.web3d.x3d.sai.X3DUrlObject;
+
+/** Defines the requirements of an X3D AudioClip node
+ * @author Rex Melton
+ * @version $Revision: 1.1 $ */
+public interface AudioClip extends X3DSoundSourceNode, X3DUrlObject {
+
+}
diff --git a/src/java/org/web3d/x3d/sai/texturing/MovieTexture.java b/src/java/org/web3d/x3d/sai/texturing/MovieTexture.java
index 851f21c857d99a75b2b72de2dcfbcf02b6a8efab..375c8b737ca0fea2f5357fbfc3cf53d383d7e5b3 100644
--- a/src/java/org/web3d/x3d/sai/texturing/MovieTexture.java
+++ b/src/java/org/web3d/x3d/sai/texturing/MovieTexture.java
@@ -1,32 +1,32 @@
-/***************************************************************************** 
- *                        Web3d.org Copyright (c) 2007 
- *                               Java Source 
- * 
- * This source is licensed under the GNU LGPL v2.1 
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
- * 
- * This software comes with the standard NO WARRANTY disclaimer for any 
- * purpose. Use it at your own risk. If there's a problem you get to fix it. 
- * 
- ****************************************************************************/ 
-
-package org.web3d.x3d.sai.texturing;
-
-import org.web3d.x3d.sai.X3DSoundSourceNode;
-import org.web3d.x3d.sai.X3DTexture2DNode;
-import org.web3d.x3d.sai.X3DUrlObject;
-
-/** Defines the requirements of an X3D MovieTexture node
- * @author Rex Melton
- * @version $Revision: 1.1 $ */
-public interface MovieTexture extends X3DTexture2DNode, X3DSoundSourceNode, X3DUrlObject {
-
-/** Return the speed float value. 
- * @return The speed float value.  */
-public float getSpeed();
-
-/** Set the speed field. 
- * @param val The float to set.  */
-public void setSpeed(float val);
-
-}
+/***************************************************************************** 
+ *                        Web3d.org Copyright (c) 2007 
+ *                               Java Source 
+ * 
+ * This source is licensed under the GNU LGPL v2.1 
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
+ * 
+ * This software comes with the standard NO WARRANTY disclaimer for any 
+ * purpose. Use it at your own risk. If there's a problem you get to fix it. 
+ * 
+ ****************************************************************************/ 
+
+package org.web3d.x3d.sai.texturing;
+
+import org.web3d.x3d.sai.X3DSoundSourceNode;
+import org.web3d.x3d.sai.X3DTexture2DNode;
+import org.web3d.x3d.sai.X3DUrlObject;
+
+/** Defines the requirements of an X3D MovieTexture node
+ * @author Rex Melton
+ * @version $Revision: 1.1 $ */
+public interface MovieTexture extends X3DTexture2DNode, X3DSoundSourceNode, X3DUrlObject {
+
+/** Return the speed float value. 
+ * @return The speed float value.  */
+public float getSpeed();
+
+/** Set the speed field. 
+ * @param val The float to set.  */
+public void setSpeed(float val);
+
+}
diff --git a/src/java/org/web3d/x3d/sai/texturing/PixelTexture.java b/src/java/org/web3d/x3d/sai/texturing/PixelTexture.java
index c057dfdae6a239d37c9e7b4609155b9e88c09812..34ed2308b517ad75dd01452c669c07e01340e511 100644
--- a/src/java/org/web3d/x3d/sai/texturing/PixelTexture.java
+++ b/src/java/org/web3d/x3d/sai/texturing/PixelTexture.java
@@ -1,22 +1,22 @@
-/***************************************************************************** 
- *                        Web3d.org Copyright (c) 2007 
- *                               Java Source 
- * 
- * This source is licensed under the GNU LGPL v2.1 
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
- * 
- * This software comes with the standard NO WARRANTY disclaimer for any 
- * purpose. Use it at your own risk. If there's a problem you get to fix it. 
- * 
- ****************************************************************************/ 
-
-package org.web3d.x3d.sai.texturing;
-
-import org.web3d.x3d.sai.X3DTexture2DNode;
-
-/** Defines the requirements of an X3D PixelTexture node
- * @author Rex Melton
- * @version $Revision: 1.1 $ */
-public interface PixelTexture extends X3DTexture2DNode {
-
-}
+/***************************************************************************** 
+ *                        Web3d.org Copyright (c) 2007 
+ *                               Java Source 
+ * 
+ * This source is licensed under the GNU LGPL v2.1 
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
+ * 
+ * This software comes with the standard NO WARRANTY disclaimer for any 
+ * purpose. Use it at your own risk. If there's a problem you get to fix it. 
+ * 
+ ****************************************************************************/ 
+
+package org.web3d.x3d.sai.texturing;
+
+import org.web3d.x3d.sai.X3DTexture2DNode;
+
+/** Defines the requirements of an X3D PixelTexture node
+ * @author Rex Melton
+ * @version $Revision: 1.1 $ */
+public interface PixelTexture extends X3DTexture2DNode {
+
+}
diff --git a/src/java/org/web3d/x3d/sai/texturing3d/TextureCoordinate3D.java b/src/java/org/web3d/x3d/sai/texturing3d/TextureCoordinate3D.java
index 05869e0580cd3b85462cee5ecb5ce509078c546a..843f79cba82f6bcba38d7decdf18d660ecbb0cf1 100644
--- a/src/java/org/web3d/x3d/sai/texturing3d/TextureCoordinate3D.java
+++ b/src/java/org/web3d/x3d/sai/texturing3d/TextureCoordinate3D.java
@@ -1,34 +1,34 @@
-/***************************************************************************** 
- *                        Web3d.org Copyright (c) 2007 
- *                               Java Source 
- * 
- * This source is licensed under the GNU LGPL v2.1 
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
- * 
- * This software comes with the standard NO WARRANTY disclaimer for any 
- * purpose. Use it at your own risk. If there's a problem you get to fix it. 
- * 
- ****************************************************************************/ 
-
-package org.web3d.x3d.sai.texturing3d;
-
-import org.web3d.x3d.sai.X3DTextureCoordinateNode;
-
-/** Defines the requirements of an X3D TextureCoordinate3D node
- * @author Rex Melton
- * @version $Revision: 1.1 $ */
-public interface TextureCoordinate3D extends X3DTextureCoordinateNode {
-
-/** Return the number of MFVec3f items in the point field. 
- * @return the number of MFVec3f items in the point field.  */
-public int getNumPoint();
-
-/** Return the point value in the argument float[]
- * @param val The float[] to initialize.  */
-public void getPoint(float[] val);
-
-/** Set the point field. 
- * @param val The float[] to set.  */
-public void setPoint(float[] val);
-
-}
+/***************************************************************************** 
+ *                        Web3d.org Copyright (c) 2007 
+ *                               Java Source 
+ * 
+ * This source is licensed under the GNU LGPL v2.1 
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
+ * 
+ * This software comes with the standard NO WARRANTY disclaimer for any 
+ * purpose. Use it at your own risk. If there's a problem you get to fix it. 
+ * 
+ ****************************************************************************/ 
+
+package org.web3d.x3d.sai.texturing3d;
+
+import org.web3d.x3d.sai.X3DTextureCoordinateNode;
+
+/** Defines the requirements of an X3D TextureCoordinate3D node
+ * @author Rex Melton
+ * @version $Revision: 1.1 $ */
+public interface TextureCoordinate3D extends X3DTextureCoordinateNode {
+
+/** Return the number of MFVec3f items in the point field. 
+ * @return the number of MFVec3f items in the point field.  */
+public int getNumPoint();
+
+/** Return the point value in the argument float[]
+ * @param val The float[] to initialize.  */
+public void getPoint(float[] val);
+
+/** Set the point field. 
+ * @param val The float[] to set.  */
+public void setPoint(float[] val);
+
+}
diff --git a/src/java/org/web3d/x3d/sai/texturing3d/TextureTransform3D.java b/src/java/org/web3d/x3d/sai/texturing3d/TextureTransform3D.java
index afd18603534ed3b7f6419bbfce233fddfa30ac6f..5aeb6737c57fd52a31b02cbedc91ebcacb11d840 100644
--- a/src/java/org/web3d/x3d/sai/texturing3d/TextureTransform3D.java
+++ b/src/java/org/web3d/x3d/sai/texturing3d/TextureTransform3D.java
@@ -1,54 +1,54 @@
-/***************************************************************************** 
- *                        Web3d.org Copyright (c) 2007 
- *                               Java Source 
- * 
- * This source is licensed under the GNU LGPL v2.1 
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
- * 
- * This software comes with the standard NO WARRANTY disclaimer for any 
- * purpose. Use it at your own risk. If there's a problem you get to fix it. 
- * 
- ****************************************************************************/ 
-
-package org.web3d.x3d.sai.texturing3d;
-
-import org.web3d.x3d.sai.X3DTextureTransformNode;
-
-/** Defines the requirements of an X3D TextureTransform3D node
- * @author Rex Melton
- * @version $Revision: 1.1 $ */
-public interface TextureTransform3D extends X3DTextureTransformNode {
-
-/** Return the center value in the argument float[]
- * @param val The float[] to initialize.  */
-public void getCenter(float[] val);
-
-/** Set the center field. 
- * @param val The float[] to set.  */
-public void setCenter(float[] val);
-
-/** Return the orientation value in the argument float[]
- * @param val The float[] to initialize.  */
-public void getOrientation(float[] val);
-
-/** Set the orientation field. 
- * @param val The float[] to set.  */
-public void setOrientation(float[] val);
-
-/** Return the scale value in the argument float[]
- * @param val The float[] to initialize.  */
-public void getScale(float[] val);
-
-/** Set the scale field. 
- * @param val The float[] to set.  */
-public void setScale(float[] val);
-
-/** Return the translation value in the argument float[]
- * @param val The float[] to initialize.  */
-public void getTranslation(float[] val);
-
-/** Set the translation field. 
- * @param val The float[] to set.  */
-public void setTranslation(float[] val);
-
-}
+/***************************************************************************** 
+ *                        Web3d.org Copyright (c) 2007 
+ *                               Java Source 
+ * 
+ * This source is licensed under the GNU LGPL v2.1 
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information 
+ * 
+ * This software comes with the standard NO WARRANTY disclaimer for any 
+ * purpose. Use it at your own risk. If there's a problem you get to fix it. 
+ * 
+ ****************************************************************************/ 
+
+package org.web3d.x3d.sai.texturing3d;
+
+import org.web3d.x3d.sai.X3DTextureTransformNode;
+
+/** Defines the requirements of an X3D TextureTransform3D node
+ * @author Rex Melton
+ * @version $Revision: 1.1 $ */
+public interface TextureTransform3D extends X3DTextureTransformNode {
+
+/** Return the center value in the argument float[]
+ * @param val The float[] to initialize.  */
+public void getCenter(float[] val);
+
+/** Set the center field. 
+ * @param val The float[] to set.  */
+public void setCenter(float[] val);
+
+/** Return the orientation value in the argument float[]
+ * @param val The float[] to initialize.  */
+public void getOrientation(float[] val);
+
+/** Set the orientation field. 
+ * @param val The float[] to set.  */
+public void setOrientation(float[] val);
+
+/** Return the scale value in the argument float[]
+ * @param val The float[] to initialize.  */
+public void getScale(float[] val);
+
+/** Set the scale field. 
+ * @param val The float[] to set.  */
+public void setScale(float[] val);
+
+/** Return the translation value in the argument float[]
+ * @param val The float[] to initialize.  */
+public void getTranslation(float[] val);
+
+/** Set the translation field. 
+ * @param val The float[] to set.  */
+public void setTranslation(float[] val);
+
+}
diff --git a/src/java/org/xj3d/core/eventmodel/BindableNodeListener.java b/src/java/org/xj3d/core/eventmodel/BindableNodeListener.java
index 681c7a523f74be0221e3d32f3badd7ebf54501da..43d20820f7880d98f509fd7f38f801cfbc442603 100644
--- a/src/java/org/xj3d/core/eventmodel/BindableNodeListener.java
+++ b/src/java/org/xj3d/core/eventmodel/BindableNodeListener.java
@@ -20,6 +20,7 @@ import org.web3d.vrml.nodes.VRMLBindableNodeType;
 
 /**
  * Listener for notification of changes in the current bound node.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/xj3d/core/eventmodel/DeviceFactory.java b/src/java/org/xj3d/core/eventmodel/DeviceFactory.java
index 8bd9b3dfaca1b2181f5b16a8c1af2e9032e240d0..5e5e164681539a5cc1807569486e858644d586ff 100644
--- a/src/java/org/xj3d/core/eventmodel/DeviceFactory.java
+++ b/src/java/org/xj3d/core/eventmodel/DeviceFactory.java
@@ -1,258 +1,258 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.core.eventmodel;
-
-// External imports
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.io.IOException;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
-import java.util.StringTokenizer;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-
-import org.j3d.device.input.DeviceManager;
-
-// Local imports
-import org.j3d.util.DefaultErrorReporter;
-import org.j3d.util.ErrorReporter;
-
-import org.web3d.vrml.util.KeySensorDevice;
-
-/**
- * Partial implementation of a DeviceFactory, with plumbing in place
- * for the ui toolkit specific implementation to create pointing and
- * key sensor devices.
- *
- * @author Rex Melton
- * @version $Revision: 1.6 $
- */
-public abstract class DeviceFactory {
-
-    /** Name of the property file that defines the devices
-     *  to be loaded */
-    private static final String PROPERTY_FILE =
-        "xj3d-devices.properties";
-
-    /** Error loading device properties file message */
-    private static final String LOAD_DEVICE_PROPERTIES_ERR_MSG =
-        "Error getting device properties";
-
-    /** The identifier String of the ui toolkit type */
-    protected String toolkitID;
-
-    /** The identifier String of the renderer type */
-    protected String rendererID;
-
-    /** The toolkit specific object that is the source of device events */
-    protected Object canvas;
-
-    /** The renderer specific object, used for instantiating certain
-     *  DeviceManagers */
-    protected Object surface;
-
-    /** The class that handles external error messaging */
-    //protected static ErrorReporter errorReporter;
-    protected ErrorReporter errorReporter;
-
-    /** Protected Default Constructor */
-    protected DeviceFactory( ) {
-    }
-
-    /**
-     * Return the array of DeviceManagers that are available per the
-     * constructor parameters. The InputDevices instantiated will be
-     * initialized with the appropriate event listeners per the ui toolkit.
-     *
-     * @return the array of DeviceManagers. If no DeviceManagers are
-     * available, an empty (size 0) array is returned.
-     */
-    public abstract DeviceManager[] getDeviceManagers( );
-
-    /**
-     * Return the KeySensorDevice associated with the rendering surface
-     * initialized with the toolkit appropriate key event listener.
-     *
-     * @return the KeySensorDevice
-     */
-    public abstract KeySensorDevice getKeySensorDevice( );
-
-    /**
-     * Register an error reporter with the factory so that any errors
-     * generated can be directed appropriately. Setting a value of null
-     * will clear the currently set reporter and causes the factory to
-     * use the DefaultErrorReporter. If an error reporter is already set,
-     * the new value replaces the old.
-     *
-     * @param reporter The instance to use or null
-     */
-    public void setErrorReporter( ErrorReporter reporter ) {
-        errorReporter = ( reporter == null ) ?
-            DefaultErrorReporter.getDefaultReporter( ) : reporter;
-    }
-
-    /**
-     * Create and return the List of InputDevices defined in the
-     * the default properties file.
-     *
-     * @return the List of DeviceManagers. An empty (size 0) List will
-     * be returned if the properties file cannot be opened or if not
-     * valid DeviceManagers are created.
-     */
-    protected List<Object> createDevices( ) {
-        final List<Object> newManagers = new ArrayList<>();
-
-        try {
-            AccessController.doPrivileged(
-                new PrivilegedExceptionAction<Object>() {
-                    @Override
-                    public Object run() {
-                        String user_dir = System.getProperty("user.dir");
-                        InputStream is;
-                        String file = user_dir + File.separator + PROPERTY_FILE;
-
-                        // Using File.separator does not work for defLoc, not sure why
-                        String defLoc = "config/common/" + PROPERTY_FILE;
-
-                        try {
-                            is = new FileInputStream(file);
-                        } catch(FileNotFoundException fnfe) {
-                            // Fallback to default
-                            is = ClassLoader.getSystemResourceAsStream(defLoc);
-                        }
-
-                        // Fallback for WebStart
-                        if(is == null) {
-                            ClassLoader cl = DeviceFactory.class.getClassLoader();
-                            is = cl.getResourceAsStream(defLoc);
-                        }
-                        if(is == null) {
-                            errorReporter.warningReport("No property file found in " +
-                                defLoc, null);
-                        } else {
-                            Properties props = new Properties();
-                            try {
-                                props.load(is);
-                                is.close();
-                            } catch(IOException ioe) {
-                                errorReporter.warningReport(
-                                    "Error reading" + defLoc, null);
-                            }
-
-                            // Fetch the property defining the list of profiles
-                            String devList = "devices." + toolkitID +"."+ rendererID + ".list";
-                            String str = props.getProperty(devList);
-                            if(str == null) {
-                                errorReporter.warningReport("No devices list found: " +
-                                    devList, null);
-                                return null;
-                            }
-
-                            StringTokenizer strtok = new StringTokenizer(str);
-                            String keyword;
-                            String deviceName;
-                            String className;
-                            String paramsStr;
-                            int params;
-
-                            while (strtok.hasMoreTokens()) {
-                                params = 0;
-                                keyword = strtok.nextToken();
-                                deviceName = props.getProperty(keyword + ".name");
-                                className = props.getProperty(keyword + ".class");
-                                paramsStr = props.getProperty(keyword + ".params");
-
-                                Object[] constParams = new Object[params];
-
-                                if(paramsStr != null) {
-                                    params = Integer.parseInt(paramsStr);
-
-                                    if(params > 0) {
-                                        constParams = new Object[params];
-
-                                        for(int i=0; i < params; i++) {
-                                            paramsStr = props.getProperty(keyword + ".param." + i);
-                                            if(paramsStr != null) {
-                                                switch (paramsStr) {
-                                                    case "PARAM_CANVAS":
-                                                        constParams[i] = canvas;
-                                                        break;
-                                                    case "PARAM_SURFACE":
-                                                        constParams[i] = surface;
-                                                        break;
-                                                    default:
-                                                        errorReporter.warningReport(
-                                                                "Unhandled param in device: " +
-                                                                        deviceName, null);
-                                                        break;
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
-
-                                Class<?> devClass;
-                                Class<?>[] paramTypes;
-
-                                Object dev=null;
-                                boolean found=false;
-                                try {
-                                    devClass = Class.forName(className);
-
-                                    Constructor<?>[] consts = devClass.getConstructors();
-
-                                    for (Constructor<?> const1 : consts) {
-                                        paramTypes = const1.getParameterTypes();
-                                        if (paramTypes.length == params) {
-                                            dev = const1.newInstance(constParams);
-                                            found = true;
-                                            break;
-                                        }
-                                    }
-                                } catch(ClassNotFoundException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
-                                    errorReporter.warningReport(
-                                        "Error loading " + deviceName +
-                                        " at: " + className,
-                                        e);
-                                }
-
-                                if(found) {
-                                    newManagers.add(dev);
-                                } else {
-                                    errorReporter.warningReport(
-                                        "Cannot load " + deviceName +
-                                        " at: " + className,
-                                        null);
-                                }
-                            }
-                        }
-                        return( null );
-                    }
-                }
-            );
-        } catch ( PrivilegedActionException pae ) {
-            errorReporter.errorReport( LOAD_DEVICE_PROPERTIES_ERR_MSG, pae );
-        }
-        return( newManagers );
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.core.eventmodel;
+
+// External imports
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.IOException;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import org.j3d.device.input.DeviceManager;
+
+// Local imports
+import org.j3d.util.DefaultErrorReporter;
+import org.j3d.util.ErrorReporter;
+
+import org.web3d.vrml.util.KeySensorDevice;
+
+/**
+ * Partial implementation of a DeviceFactory, with plumbing in place
+ * for the ui toolkit specific implementation to create pointing and
+ * key sensor devices.
+ *
+ * @author Rex Melton
+ * @version $Revision: 1.6 $
+ */
+public abstract class DeviceFactory {
+
+    /** Name of the property file that defines the devices
+     *  to be loaded */
+    private static final String PROPERTY_FILE =
+        "xj3d-devices.properties";
+
+    /** Error loading device properties file message */
+    private static final String LOAD_DEVICE_PROPERTIES_ERR_MSG =
+        "Error getting device properties";
+
+    /** The identifier String of the ui toolkit type */
+    protected String toolkitID;
+
+    /** The identifier String of the renderer type */
+    protected String rendererID;
+
+    /** The toolkit specific object that is the source of device events */
+    protected Object canvas;
+
+    /** The renderer specific object, used for instantiating certain
+     *  DeviceManagers */
+    protected Object surface;
+
+    /** The class that handles external error messaging */
+    //protected static ErrorReporter errorReporter;
+    protected ErrorReporter errorReporter;
+
+    /** Protected Default Constructor */
+    protected DeviceFactory( ) {
+    }
+
+    /**
+     * Return the array of DeviceManagers that are available per the
+     * constructor parameters. The InputDevices instantiated will be
+     * initialized with the appropriate event listeners per the ui toolkit.
+     *
+     * @return the array of DeviceManagers. If no DeviceManagers are
+     * available, an empty (size 0) array is returned.
+     */
+    public abstract DeviceManager[] getDeviceManagers( );
+
+    /**
+     * Return the KeySensorDevice associated with the rendering surface
+     * initialized with the toolkit appropriate key event listener.
+     *
+     * @return the KeySensorDevice
+     */
+    public abstract KeySensorDevice getKeySensorDevice( );
+
+    /**
+     * Register an error reporter with the factory so that any errors
+     * generated can be directed appropriately. Setting a value of null
+     * will clear the currently set reporter and causes the factory to
+     * use the DefaultErrorReporter. If an error reporter is already set,
+     * the new value replaces the old.
+     *
+     * @param reporter The instance to use or null
+     */
+    public void setErrorReporter( ErrorReporter reporter ) {
+        errorReporter = ( reporter == null ) ?
+            DefaultErrorReporter.getDefaultReporter( ) : reporter;
+    }
+
+    /**
+     * Create and return the List of InputDevices defined in the
+     * the default properties file.
+     *
+     * @return the List of DeviceManagers. An empty (size 0) List will
+     * be returned if the properties file cannot be opened or if not
+     * valid DeviceManagers are created.
+     */
+    protected List<Object> createDevices( ) {
+        final List<Object> newManagers = new ArrayList<>();
+
+        try {
+            AccessController.doPrivileged(
+                new PrivilegedExceptionAction<Object>() {
+                    @Override
+                    public Object run() {
+                        String user_dir = System.getProperty("user.dir");
+                        InputStream is;
+                        String file = user_dir + File.separator + PROPERTY_FILE;
+
+                        // Using File.separator does not work for defLoc, not sure why
+                        String defLoc = "config/common/" + PROPERTY_FILE;
+
+                        try {
+                            is = new FileInputStream(file);
+                        } catch(FileNotFoundException fnfe) {
+                            // Fallback to default
+                            is = ClassLoader.getSystemResourceAsStream(defLoc);
+                        }
+
+                        // Fallback for WebStart
+                        if(is == null) {
+                            ClassLoader cl = DeviceFactory.class.getClassLoader();
+                            is = cl.getResourceAsStream(defLoc);
+                        }
+                        if(is == null) {
+                            errorReporter.warningReport("No property file found in " +
+                                defLoc, null);
+                        } else {
+                            Properties props = new Properties();
+                            try {
+                                props.load(is);
+                                is.close();
+                            } catch(IOException ioe) {
+                                errorReporter.warningReport(
+                                    "Error reading" + defLoc, null);
+                            }
+
+                            // Fetch the property defining the list of profiles
+                            String devList = "devices." + toolkitID +"."+ rendererID + ".list";
+                            String str = props.getProperty(devList);
+                            if(str == null) {
+                                errorReporter.warningReport("No devices list found: " +
+                                    devList, null);
+                                return null;
+                            }
+
+                            StringTokenizer strtok = new StringTokenizer(str);
+                            String keyword;
+                            String deviceName;
+                            String className;
+                            String paramsStr;
+                            int params;
+
+                            while (strtok.hasMoreTokens()) {
+                                params = 0;
+                                keyword = strtok.nextToken();
+                                deviceName = props.getProperty(keyword + ".name");
+                                className = props.getProperty(keyword + ".class");
+                                paramsStr = props.getProperty(keyword + ".params");
+
+                                Object[] constParams = new Object[params];
+
+                                if(paramsStr != null) {
+                                    params = Integer.parseInt(paramsStr);
+
+                                    if(params > 0) {
+                                        constParams = new Object[params];
+
+                                        for(int i=0; i < params; i++) {
+                                            paramsStr = props.getProperty(keyword + ".param." + i);
+                                            if(paramsStr != null) {
+                                                switch (paramsStr) {
+                                                    case "PARAM_CANVAS":
+                                                        constParams[i] = canvas;
+                                                        break;
+                                                    case "PARAM_SURFACE":
+                                                        constParams[i] = surface;
+                                                        break;
+                                                    default:
+                                                        errorReporter.warningReport(
+                                                                "Unhandled param in device: " +
+                                                                        deviceName, null);
+                                                        break;
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+
+                                Class<?> devClass;
+                                Class<?>[] paramTypes;
+
+                                Object dev=null;
+                                boolean found=false;
+                                try {
+                                    devClass = Class.forName(className);
+
+                                    Constructor<?>[] consts = devClass.getConstructors();
+
+                                    for (Constructor<?> const1 : consts) {
+                                        paramTypes = const1.getParameterTypes();
+                                        if (paramTypes.length == params) {
+                                            dev = const1.newInstance(constParams);
+                                            found = true;
+                                            break;
+                                        }
+                                    }
+                                } catch(ClassNotFoundException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+                                    errorReporter.warningReport(
+                                        "Error loading " + deviceName +
+                                        " at: " + className,
+                                        e);
+                                }
+
+                                if(found) {
+                                    newManagers.add(dev);
+                                } else {
+                                    errorReporter.warningReport(
+                                        "Cannot load " + deviceName +
+                                        " at: " + className,
+                                        null);
+                                }
+                            }
+                        }
+                        return( null );
+                    }
+                }
+            );
+        } catch ( PrivilegedActionException pae ) {
+            errorReporter.errorReport( LOAD_DEVICE_PROPERTIES_ERR_MSG, pae );
+        }
+        return( newManagers );
+    }
+}
diff --git a/src/java/org/xj3d/core/eventmodel/LayerManager.java b/src/java/org/xj3d/core/eventmodel/LayerManager.java
index 1cb9fb9e3e47304914d26c0fb272fb28c639a30f..ed189dc57dd89b6559dae65c1515c066141c2ea4 100644
--- a/src/java/org/xj3d/core/eventmodel/LayerManager.java
+++ b/src/java/org/xj3d/core/eventmodel/LayerManager.java
@@ -1,313 +1,313 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2005 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.core.eventmodel;
-
-// External imports
-import javax.vecmath.Vector3f;
-import javax.vecmath.AxisAngle4f;
-
-// Local imports
-import org.web3d.browser.NavigationStateListener;
-import org.web3d.browser.SensorStatusListener;
-import org.web3d.browser.ViewpointStatusListener;
-import org.j3d.util.ErrorReporter;
-import org.web3d.vrml.nodes.VRMLLayerNodeType;
-import org.web3d.vrml.nodes.VRMLViewportNodeType;
-import org.web3d.vrml.nodes.VRMLWorldRootNodeType;
-
-/**
- * An abstract representation of a class that would be responsible for
- * performing management of a single layer.
- * <p>
- *
- * The manager is responsible for all input and sensor handling for this
- * layer instance. Sensors and other interactions can be enabled on a per-layer
- * basis. Typically, for any scene, only one layer is the focus for navigation
- * input.
- *
- * @author Justin Couch
- * @version $Revision: 1.9 $
- */
-public interface LayerManager {
-
-    /**
-     * The layer contains a viewport that is currently undefined due to externproto
-     * resolution. In this case, treat the viewport as having zero width and height -
-     * ie invisible. This is defined to be the same value as
-     * {@link VRMLViewportNodeType#VIEWPORT_UNDEFINED}
-     */
-    int VIEWPORT_UNDEFINED = VRMLViewportNodeType.VIEWPORT_UNDEFINED;
-
-    /**
-     * The layer contains a viewport that takes up the full window space. This
-     * is defined to be the same value as
-     * {@link VRMLViewportNodeType#VIEWPORT_FULLWINDOW}
-     */
-    int VIEWPORT_FULLWINDOW = VRMLViewportNodeType.VIEWPORT_FULLWINDOW;
-
-    /**
-     * The layer contains a viewport that takes up a percentage of the window. This
-     * is defined to be the same value as
-     * {@link VRMLViewportNodeType#VIEWPORT_PROPORTIONAL}
-     */
-    int VIEWPORT_PROPORTIONAL = VRMLViewportNodeType.VIEWPORT_PROPORTIONAL;
-
-    /**
-     * The layer contains a viewport that takes up a fixed pixel size. This is
-     * defined to be the same value as
-     * {@link VRMLViewportNodeType#VIEWPORT_FIXED}
-     */
-    int VIEWPORT_FIXED = VRMLViewportNodeType.VIEWPORT_FIXED;
-
-    /**
-     * The layer contains a viewport that is configurable to use either fixed
-     * or proportional size on each dimension. This is defined to be the same
-     * value as {@link VRMLViewportNodeType#VIEWPORT_CUSTOM}
-     */
-    int VIEWPORT_CUSTOM = VRMLViewportNodeType.VIEWPORT_CUSTOM;
-
-    /**
-     * Register an error reporter with the engine so that any errors generated
-     * by the loading of script code can be reported in a nice, pretty fashion.
-     * Setting a value of null will clear the currently set reporter. If one
-     * is already set, the new value replaces the old.
-     *
-     * @param reporter The instance to use or null
-     */
-    void setErrorReporter(ErrorReporter reporter);
-
-    /**
-     * Complete the initialization of the layer manager now.
-     *
-     * @param sensors The sensor manager to start with from the global list
-     */
-    void initialise(SensorManager sensors);
-
-    /**
-     * Set or reset the layer ID to the new ID value.
-     *
-     * @param id A non-negative ID for the layer
-     */
-    void setLayerId(int id);
-
-    /**
-     * Set the specification version that should be handled by this manager.
-     * This is needed so that the correct version of the default bindables are
-     * instantiated before the rest of the world loads. For example, the default
-     * nav type for VRML is different to X3D, so this makes sure all the right
-     * spec stuff is catered for.
-     *
-     * @param major The spec major version number
-     * @param minor The spec minor version number
-     */
-    void setSpecVersion(int major, int minor);
-
-    /**
-     * Enable or disable this layer to be currently navigable layer. The
-     * navigable layer takes the input from the input devices and interacts
-     * with the currently bound viewpoint etc.
-     *
-     * @param state True to enable this layer as navigable
-     */
-    void setActiveNavigationLayer(boolean state);
-
-    /**
-     * Check to see if this is the active navigation layer.
-     *
-     * @return true if this is the currently active layer for navigation
-     */
-    boolean isActiveNavigationLayer();
-
-    /**
-     * Set the desired navigation mode. The mode string is one of the
-     * spec-defined strings for the NavigationInfo node in the VRML/X3D
-     * specification.
-     *
-     * @param mode The requested mode.
-     * @return Whether the mode is valid.
-     */
-    boolean setNavigationMode(String mode);
-
-    /**
-     * Get the user's location and orientation.  This will use the viewpoint
-     * bound in the active layer.
-     *
-     * @param pos The current user position
-     * @param ori The current user orientation
-     */
-    void getUserPosition(Vector3f pos, AxisAngle4f ori);
-
-    /**
-     * Move the user's location to see the entire world in this layer. Change
-     * the users orientation to look at the center of the world.
-     *
-     * @param animated Should the transition be animated.  Defaults to FALSE.
-     */
-    void fitToWorld(boolean animated);
-
-    /**
-     * Set the contents that this layer manages to be the ungrouped nodes
-     * of the scene. The code should take all the children nodes from this node
-     * that are not part of a layer and render them as this layer.
-     *
-     * @param root The root of the world to handle
-     */
-    void setManagedNodes(VRMLWorldRootNodeType root);
-
-    /**
-     * Set the contents that this layer manages the specific layer instance
-     * provided.
-     *
-     * @param layer The root of the layer to handle
-     */
-    void setManagedLayer(VRMLLayerNodeType layer);
-
-    /**
-     * Override the file field of view values with a value that suits
-     * the given output device. A value of 0 = no, otherwise use this
-     * instead of content
-     *
-     * @param fov The fov in degrees.
-     */
-    void setHardwareFOV(float fov);
-
-    /**
-     * Set whether stereo is enabled for all layers.
-     * @param enabled
-     */
-    void setStereoEnabled(boolean enabled);
-
-    /**
-     * Change the rendering style that the browser should currently be using
-     * for all layers. Various options are available based on the constants
-     * defined in this interface.
-     *
-     * @param style One of the RENDER_* constants from LayerRenderingManager
-     * @throws IllegalArgumentException A style constant that is not recognized
-     *   by the implementation was provided
-     */
-    void setRenderingStyle(int style)
-        throws IllegalArgumentException;
-
-    /**
-     * Get the currently set rendering style. The default style is
-     * RENDER_SHADED.
-     *
-     * @return one of the RENDER_ constants from LayerRenderingManager
-     */
-    int getRenderingStyle();
-
-    /**
-     * Perform the initial bind for a new scene. This is typically called some
-     * time just after the clear() method with a new scene. This will
-     * automatically reset the current navigation state for this layer to be
-     * inactive, even if it was previously active.
-     */
-    void initialBind();
-
-    /**
-     * Get the bindable node manager for the given node type. If the node type
-     * does not have a bindable manager for it, one will be created.
-     *
-     * @param type The type constant of the node type for the manager
-     * @return The bindable manager for it
-     * @see org.web3d.vrml.lang.TypeConstants
-     */
-    BindableNodeManager getBindableManager(int type);
-
-    /**
-     * Check to see if this is an unmanaged size layer. A layer that has no
-     * specific viewport set, or a percentage size.
-     *
-     * @return One of the VIEWPORT_* constants
-     */
-    int getViewportType();
-
-    /**
-     * Get the Viewport node that this layer uses. If the layer does not have
-     * a viewport set, then it returns null. The value is the real
-     * X3DViewportNode instance stripped from any surrounding proto shells etc.
-     *
-     * @return The current viewport node instance used by the layer
-     */
-    VRMLViewportNodeType getViewport();
-
-    /**
-     * Shutdown the node manager now. If this is using any external resources
-     * it should remove those now as the entire application is about to die
-     */
-    void shutdown();
-
-    /**
-     * Update the viewing matrix.  Call this when you want the LayerManager
-     * to update the viewing matrix.  Typically after all user input and events
-     * have resolved.
-     */
-    void updateViewMatrix();
-
-    /**
-     * Force clearing all currently managed nodes from this manager now. This
-     * is used to indicate that a new world is about to be loaded and
-     * everything should be cleaned out now. Everything also includes all the
-     * currently registered listener instances.
-     */
-    void clear();
-
-    /**
-     * Add a listener for navigation state changes.  A listener can only be added once.
-     * Duplicate requests are ignored.
-     *
-     * @param l The listener to add
-     */
-    void addNavigationStateListener(NavigationStateListener l);
-
-    /**
-     * Remove a navigation state listener. If the reference is null or not known,
-     * the request is silently ignored.
-     *
-     * @param l The listener to remove
-     */
-    void removeNavigationStateListener(NavigationStateListener l);
-
-    /**
-     * Add a listener for sensor state changes.  A listener can only be added once.
-     * Duplicate requests are ignored.
-     *
-     * @param l The listener to add
-     */
-    void addSensorStatusListener(SensorStatusListener l);
-
-    /**
-     * Remove a sensor state listener. If the reference is null or not known,
-     * the request is silently ignored.
-     *
-     * @param l The listener to remove
-     */
-    void removeSensorStatusListener(SensorStatusListener l);
-
-    /**
-     * Add a listener for viewpoint status changes.  A listener can only be added once.
-     * Duplicate requests are ignored.
-     *
-     * @param l The listener to add
-     */
-    void addViewpointStatusListener(ViewpointStatusListener l);
-
-    /**
-     * Remove a viewpoint state listener. If the reference is null or not known,
-     * the request is silently ignored.
-     *
-     * @param l The listener to remove
-     */
-    void removeViewpointStatusListener(ViewpointStatusListener l);
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2005 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.core.eventmodel;
+
+// External imports
+import javax.vecmath.Vector3f;
+import javax.vecmath.AxisAngle4f;
+
+// Local imports
+import org.web3d.browser.NavigationStateListener;
+import org.web3d.browser.SensorStatusListener;
+import org.web3d.browser.ViewpointStatusListener;
+import org.j3d.util.ErrorReporter;
+import org.web3d.vrml.nodes.VRMLLayerNodeType;
+import org.web3d.vrml.nodes.VRMLViewportNodeType;
+import org.web3d.vrml.nodes.VRMLWorldRootNodeType;
+
+/**
+ * An abstract representation of a class that would be responsible for
+ * performing management of a single layer.
+ * <p>
+ *
+ * The manager is responsible for all input and sensor handling for this
+ * layer instance. Sensors and other interactions can be enabled on a per-layer
+ * basis. Typically, for any scene, only one layer is the focus for navigation
+ * input.
+ *
+ * @author Justin Couch
+ * @version $Revision: 1.9 $
+ */
+public interface LayerManager {
+
+    /**
+     * The layer contains a viewport that is currently undefined due to externproto
+     * resolution. In this case, treat the viewport as having zero width and height -
+     * ie invisible. This is defined to be the same value as
+     * {@link VRMLViewportNodeType#VIEWPORT_UNDEFINED}
+     */
+    int VIEWPORT_UNDEFINED = VRMLViewportNodeType.VIEWPORT_UNDEFINED;
+
+    /**
+     * The layer contains a viewport that takes up the full window space. This
+     * is defined to be the same value as
+     * {@link VRMLViewportNodeType#VIEWPORT_FULLWINDOW}
+     */
+    int VIEWPORT_FULLWINDOW = VRMLViewportNodeType.VIEWPORT_FULLWINDOW;
+
+    /**
+     * The layer contains a viewport that takes up a percentage of the window. This
+     * is defined to be the same value as
+     * {@link VRMLViewportNodeType#VIEWPORT_PROPORTIONAL}
+     */
+    int VIEWPORT_PROPORTIONAL = VRMLViewportNodeType.VIEWPORT_PROPORTIONAL;
+
+    /**
+     * The layer contains a viewport that takes up a fixed pixel size. This is
+     * defined to be the same value as
+     * {@link VRMLViewportNodeType#VIEWPORT_FIXED}
+     */
+    int VIEWPORT_FIXED = VRMLViewportNodeType.VIEWPORT_FIXED;
+
+    /**
+     * The layer contains a viewport that is configurable to use either fixed
+     * or proportional size on each dimension. This is defined to be the same
+     * value as {@link VRMLViewportNodeType#VIEWPORT_CUSTOM}
+     */
+    int VIEWPORT_CUSTOM = VRMLViewportNodeType.VIEWPORT_CUSTOM;
+
+    /**
+     * Register an error reporter with the engine so that any errors generated
+     * by the loading of script code can be reported in a nice, pretty fashion.
+     * Setting a value of null will clear the currently set reporter. If one
+     * is already set, the new value replaces the old.
+     *
+     * @param reporter The instance to use or null
+     */
+    void setErrorReporter(ErrorReporter reporter);
+
+    /**
+     * Complete the initialization of the layer manager now.
+     *
+     * @param sensors The sensor manager to start with from the global list
+     */
+    void initialise(SensorManager sensors);
+
+    /**
+     * Set or reset the layer ID to the new ID value.
+     *
+     * @param id A non-negative ID for the layer
+     */
+    void setLayerId(int id);
+
+    /**
+     * Set the specification version that should be handled by this manager.
+     * This is needed so that the correct version of the default bindables are
+     * instantiated before the rest of the world loads. For example, the default
+     * nav type for VRML is different to X3D, so this makes sure all the right
+     * spec stuff is catered for.
+     *
+     * @param major The spec major version number
+     * @param minor The spec minor version number
+     */
+    void setSpecVersion(int major, int minor);
+
+    /**
+     * Enable or disable this layer to be currently navigable layer. The
+     * navigable layer takes the input from the input devices and interacts
+     * with the currently bound viewpoint etc.
+     *
+     * @param state True to enable this layer as navigable
+     */
+    void setActiveNavigationLayer(boolean state);
+
+    /**
+     * Check to see if this is the active navigation layer.
+     *
+     * @return true if this is the currently active layer for navigation
+     */
+    boolean isActiveNavigationLayer();
+
+    /**
+     * Set the desired navigation mode. The mode string is one of the
+     * spec-defined strings for the NavigationInfo node in the VRML/X3D
+     * specification.
+     *
+     * @param mode The requested mode.
+     * @return Whether the mode is valid.
+     */
+    boolean setNavigationMode(String mode);
+
+    /**
+     * Get the user's location and orientation.  This will use the viewpoint
+     * bound in the active layer.
+     *
+     * @param pos The current user position
+     * @param ori The current user orientation
+     */
+    void getUserPosition(Vector3f pos, AxisAngle4f ori);
+
+    /**
+     * Move the user's location to see the entire world in this layer. Change
+     * the users orientation to look at the center of the world.
+     *
+     * @param animated Should the transition be animated.  Defaults to FALSE.
+     */
+    void fitToWorld(boolean animated);
+
+    /**
+     * Set the contents that this layer manages to be the ungrouped nodes
+     * of the scene. The code should take all the children nodes from this node
+     * that are not part of a layer and render them as this layer.
+     *
+     * @param root The root of the world to handle
+     */
+    void setManagedNodes(VRMLWorldRootNodeType root);
+
+    /**
+     * Set the contents that this layer manages the specific layer instance
+     * provided.
+     *
+     * @param layer The root of the layer to handle
+     */
+    void setManagedLayer(VRMLLayerNodeType layer);
+
+    /**
+     * Override the file field of view values with a value that suits
+     * the given output device. A value of 0 = no, otherwise use this
+     * instead of content
+     *
+     * @param fov The fov in degrees.
+     */
+    void setHardwareFOV(float fov);
+
+    /**
+     * Set whether stereo is enabled for all layers.
+     * @param enabled
+     */
+    void setStereoEnabled(boolean enabled);
+
+    /**
+     * Change the rendering style that the browser should currently be using
+     * for all layers. Various options are available based on the constants
+     * defined in this interface.
+     *
+     * @param style One of the RENDER_* constants from LayerRenderingManager
+     * @throws IllegalArgumentException A style constant that is not recognized
+     *   by the implementation was provided
+     */
+    void setRenderingStyle(int style)
+        throws IllegalArgumentException;
+
+    /**
+     * Get the currently set rendering style. The default style is
+     * RENDER_SHADED.
+     *
+     * @return one of the RENDER_ constants from LayerRenderingManager
+     */
+    int getRenderingStyle();
+
+    /**
+     * Perform the initial bind for a new scene. This is typically called some
+     * time just after the clear() method with a new scene. This will
+     * automatically reset the current navigation state for this layer to be
+     * inactive, even if it was previously active.
+     */
+    void initialBind();
+
+    /**
+     * Get the bindable node manager for the given node type. If the node type
+     * does not have a bindable manager for it, one will be created.
+     *
+     * @param type The type constant of the node type for the manager
+     * @return The bindable manager for it
+     * @see org.web3d.vrml.lang.TypeConstants
+     */
+    BindableNodeManager getBindableManager(int type);
+
+    /**
+     * Check to see if this is an unmanaged size layer. A layer that has no
+     * specific viewport set, or a percentage size.
+     *
+     * @return One of the VIEWPORT_* constants
+     */
+    int getViewportType();
+
+    /**
+     * Get the Viewport node that this layer uses. If the layer does not have
+     * a viewport set, then it returns null. The value is the real
+     * X3DViewportNode instance stripped from any surrounding proto shells etc.
+     *
+     * @return The current viewport node instance used by the layer
+     */
+    VRMLViewportNodeType getViewport();
+
+    /**
+     * Shutdown the node manager now. If this is using any external resources
+     * it should remove those now as the entire application is about to die
+     */
+    void shutdown();
+
+    /**
+     * Update the viewing matrix.  Call this when you want the LayerManager
+     * to update the viewing matrix.  Typically after all user input and events
+     * have resolved.
+     */
+    void updateViewMatrix();
+
+    /**
+     * Force clearing all currently managed nodes from this manager now. This
+     * is used to indicate that a new world is about to be loaded and
+     * everything should be cleaned out now. Everything also includes all the
+     * currently registered listener instances.
+     */
+    void clear();
+
+    /**
+     * Add a listener for navigation state changes.  A listener can only be added once.
+     * Duplicate requests are ignored.
+     *
+     * @param l The listener to add
+     */
+    void addNavigationStateListener(NavigationStateListener l);
+
+    /**
+     * Remove a navigation state listener. If the reference is null or not known,
+     * the request is silently ignored.
+     *
+     * @param l The listener to remove
+     */
+    void removeNavigationStateListener(NavigationStateListener l);
+
+    /**
+     * Add a listener for sensor state changes.  A listener can only be added once.
+     * Duplicate requests are ignored.
+     *
+     * @param l The listener to add
+     */
+    void addSensorStatusListener(SensorStatusListener l);
+
+    /**
+     * Remove a sensor state listener. If the reference is null or not known,
+     * the request is silently ignored.
+     *
+     * @param l The listener to remove
+     */
+    void removeSensorStatusListener(SensorStatusListener l);
+
+    /**
+     * Add a listener for viewpoint status changes.  A listener can only be added once.
+     * Duplicate requests are ignored.
+     *
+     * @param l The listener to add
+     */
+    void addViewpointStatusListener(ViewpointStatusListener l);
+
+    /**
+     * Remove a viewpoint state listener. If the reference is null or not known,
+     * the request is silently ignored.
+     *
+     * @param l The listener to remove
+     */
+    void removeViewpointStatusListener(ViewpointStatusListener l);
+}
diff --git a/src/java/org/xj3d/core/eventmodel/LayerManagerFactory.java b/src/java/org/xj3d/core/eventmodel/LayerManagerFactory.java
index 542ce3a8f7f7c86cc941023958a9b38a7a3b059c..8724ed0d7d967ecb657d6e438a320fe1144ff650 100644
--- a/src/java/org/xj3d/core/eventmodel/LayerManagerFactory.java
+++ b/src/java/org/xj3d/core/eventmodel/LayerManagerFactory.java
@@ -1,51 +1,51 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2005 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.core.eventmodel;
-
-// External imports
-// none
-
-// Local imports
-import org.j3d.util.ErrorReporter;
-
-/**
- * Factory for generating renderer-specific instances of LayerManagers.
- * <p>
- *
- * Layer managers are inherently renderer-specific and this factory is used as
- * the glue between the generalised event model handling, and the
- * renderer-specific codes for per-layer handling
- *
- * @author Justin Couch
- * @version $Revision: 1.1 $
- */
-public interface LayerManagerFactory {
-
-    /**
-     * Create a new layer manager instance.
-     *
-     * @return a new clean layer manager
-     */
-    LayerManager createLayerManager();
-
-    /**
-     * Register an error reporter with the engine so that any errors generated
-     * by the loading of script code can be reported in a nice, pretty fashion.
-     * Setting a value of null will clear the currently set reporter. If one
-     * is already set, the new value replaces the old.
-     *
-     * @param reporter The instance to use or null
-     */
-    void setErrorReporter(ErrorReporter reporter);
-}
-
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2005 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.core.eventmodel;
+
+// External imports
+// none
+
+// Local imports
+import org.j3d.util.ErrorReporter;
+
+/**
+ * Factory for generating renderer-specific instances of LayerManagers.
+ * <p>
+ *
+ * Layer managers are inherently renderer-specific and this factory is used as
+ * the glue between the generalised event model handling, and the
+ * renderer-specific codes for per-layer handling
+ *
+ * @author Justin Couch
+ * @version $Revision: 1.1 $
+ */
+public interface LayerManagerFactory {
+
+    /**
+     * Create a new layer manager instance.
+     *
+     * @return a new clean layer manager
+     */
+    LayerManager createLayerManager();
+
+    /**
+     * Register an error reporter with the engine so that any errors generated
+     * by the loading of script code can be reported in a nice, pretty fashion.
+     * Setting a value of null will clear the currently set reporter. If one
+     * is already set, the new value replaces the old.
+     *
+     * @param reporter The instance to use or null
+     */
+    void setErrorReporter(ErrorReporter reporter);
+}
+
diff --git a/src/java/org/xj3d/core/eventmodel/LayerRenderingManager.java b/src/java/org/xj3d/core/eventmodel/LayerRenderingManager.java
index 65cfbadb45131beb7cf16ed04db7174475c20ca9..56b06a14a51f6004f4950690ae68ce2e649ec72c 100644
--- a/src/java/org/xj3d/core/eventmodel/LayerRenderingManager.java
+++ b/src/java/org/xj3d/core/eventmodel/LayerRenderingManager.java
@@ -21,6 +21,7 @@ import org.j3d.util.ErrorReporter;
 /**
  * A representation of a class that would be responsible for
  * performing management of all layers with a running the system.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/xj3d/core/eventmodel/NavigationManager.java b/src/java/org/xj3d/core/eventmodel/NavigationManager.java
index 283803e2b21fafff9115f1f74a4d10c00eceaf0b..633d05da4bd32e178665f3c4b3f2ed1bef43f322 100644
--- a/src/java/org/xj3d/core/eventmodel/NavigationManager.java
+++ b/src/java/org/xj3d/core/eventmodel/NavigationManager.java
@@ -1,136 +1,136 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2005 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.core.eventmodel;
-
-// External imports
-import java.util.List;
-
-// Local imports
-import org.j3d.util.ErrorReporter;
-import org.web3d.vrml.nodes.VRMLNavigationInfoNodeType;
-
-/**
- * An abstract representation of a class that would be responsible for
- * performing Viewpoint management.
- * <p>
- *
- * This interface represents a further abstracted view of viewpoint management
- * handling beyond the {@link org.web3d.browser.BrowserCore}. This gives you
- * all the handling that is normally seen at a user interface level. You should
- * use one or the other, but not both as implementations of this class will
- * also interact with BrowserCore.
- *
- * @author Alan Hudson
- * @version $Revision: 1.3 $
- */
-public interface NavigationManager {
-
-    /**
-     * Set the current bound navigation info to an arbitrary instance. This
-     * only works in the layer that the navigation info is a part of. If the
-     * layer is not the active layer, you will probably not see any response
-     * from this manager.
-     *
-     * @param nav The new current navigation info.
-     */
-    void setNavigationInfo(VRMLNavigationInfoNodeType nav);
-
-    /**
-     * Get the current active navigation info node. If there isn't one
-     * (eg there is no world loaded at all). Active is defined for the
-     * current active navigation layer.
-     *
-     * @return The current active navigation info node or null
-     */
-    VRMLNavigationInfoNodeType getNavigationInfo();
-
-    /**
-     * Get the list of active navigation modes for the current active
-     * navigation layer. This is a list of all the available options, not
-     * the single type that is currently being used right now. To find
-     * out which one of these modes is active, use
-     * {@link #getActiveNavgiationIndex()}. This is a read-only list.
-     *
-     * @return The list of all the available types
-     */
-    List<String> getActiveNavigationTypes();
-
-    /**
-     * Set the active navigation index of the current list. If the index is -1
-     * then all navigation is disabled. An index of out bounds for the current
-     * list throws an exception.
-     *
-     * @param idx The index to set as the active type
-     * @throws IllegalArgumentException The index is greater than the
-     *    available list size
-     */
-    void setActiveNavigationIndex(int idx)
-        throws IllegalArgumentException;
-
-    /**
-     * Fetch the index into the navigation type array of the actual type
-     * of navigation being used by the system. If no type is active or the
-     * type list includes "NONE" then this will return -1.
-     *
-     * @return The index of the active type
-     */
-    int getActiveNavgiationIndex();
-
-    /**
-     * Shutdown the node manager now. If this is using any external resources
-     * it should remove those now as the entire application is about to die
-     */
-    void shutdown();
-
-    /**
-     * Force clearing all currently managed nodes from this manager now. This
-     * is used to indicate that a new world is about to be loaded and
-     * everything should be cleaned out now.
-     */
-    void clear();
-
-    /**
-     * Register an error reporter with the engine so that any errors generated
-     * by the loading of script code can be reported in a nice, pretty fashion.
-     * Setting a value of null will clear the currently set reporter. If one
-     * is already set, the new value replaces the old.
-     *
-     * @param reporter The instance to use or null
-     */
-    void setErrorReporter(ErrorReporter reporter);
-
-    /**
-     * Gets the viewpoints for the currently active layer.
-     *
-     * @return A list of the viewpoint nodes
-     */
-    List<VRMLNavigationInfoNodeType> getActiveNavInfos();
-
-    /**
-     * Add a listener for viewpoint status messages. Adding the same listener
-     * instance more than once will be silently ignored. Null values are
-     * ignored.
-     *
-     * @param l The listener instance to add
-     */
-    void addNavigationListener(NavigationStatusListener l);
-
-    /**
-     * Remove a listener for viewpoint status messages. If this listener is
-     * not currently registered, the request will be silently ignored.
-     *
-     * @param l The listener instance to remove
-     */
-    void removeNavigationListener(NavigationStatusListener l);
-}
-
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2005 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.core.eventmodel;
+
+// External imports
+import java.util.List;
+
+// Local imports
+import org.j3d.util.ErrorReporter;
+import org.web3d.vrml.nodes.VRMLNavigationInfoNodeType;
+
+/**
+ * An abstract representation of a class that would be responsible for
+ * performing Viewpoint management.
+ * <p>
+ *
+ * This interface represents a further abstracted view of viewpoint management
+ * handling beyond the {@link org.web3d.browser.BrowserCore}. This gives you
+ * all the handling that is normally seen at a user interface level. You should
+ * use one or the other, but not both as implementations of this class will
+ * also interact with BrowserCore.
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.3 $
+ */
+public interface NavigationManager {
+
+    /**
+     * Set the current bound navigation info to an arbitrary instance. This
+     * only works in the layer that the navigation info is a part of. If the
+     * layer is not the active layer, you will probably not see any response
+     * from this manager.
+     *
+     * @param nav The new current navigation info.
+     */
+    void setNavigationInfo(VRMLNavigationInfoNodeType nav);
+
+    /**
+     * Get the current active navigation info node. If there isn't one
+     * (eg there is no world loaded at all). Active is defined for the
+     * current active navigation layer.
+     *
+     * @return The current active navigation info node or null
+     */
+    VRMLNavigationInfoNodeType getNavigationInfo();
+
+    /**
+     * Get the list of active navigation modes for the current active
+     * navigation layer. This is a list of all the available options, not
+     * the single type that is currently being used right now. To find
+     * out which one of these modes is active, use
+     * {@link #getActiveNavgiationIndex()}. This is a read-only list.
+     *
+     * @return The list of all the available types
+     */
+    List<String> getActiveNavigationTypes();
+
+    /**
+     * Set the active navigation index of the current list. If the index is -1
+     * then all navigation is disabled. An index of out bounds for the current
+     * list throws an exception.
+     *
+     * @param idx The index to set as the active type
+     * @throws IllegalArgumentException The index is greater than the
+     *    available list size
+     */
+    void setActiveNavigationIndex(int idx)
+        throws IllegalArgumentException;
+
+    /**
+     * Fetch the index into the navigation type array of the actual type
+     * of navigation being used by the system. If no type is active or the
+     * type list includes "NONE" then this will return -1.
+     *
+     * @return The index of the active type
+     */
+    int getActiveNavgiationIndex();
+
+    /**
+     * Shutdown the node manager now. If this is using any external resources
+     * it should remove those now as the entire application is about to die
+     */
+    void shutdown();
+
+    /**
+     * Force clearing all currently managed nodes from this manager now. This
+     * is used to indicate that a new world is about to be loaded and
+     * everything should be cleaned out now.
+     */
+    void clear();
+
+    /**
+     * Register an error reporter with the engine so that any errors generated
+     * by the loading of script code can be reported in a nice, pretty fashion.
+     * Setting a value of null will clear the currently set reporter. If one
+     * is already set, the new value replaces the old.
+     *
+     * @param reporter The instance to use or null
+     */
+    void setErrorReporter(ErrorReporter reporter);
+
+    /**
+     * Gets the viewpoints for the currently active layer.
+     *
+     * @return A list of the viewpoint nodes
+     */
+    List<VRMLNavigationInfoNodeType> getActiveNavInfos();
+
+    /**
+     * Add a listener for viewpoint status messages. Adding the same listener
+     * instance more than once will be silently ignored. Null values are
+     * ignored.
+     *
+     * @param l The listener instance to add
+     */
+    void addNavigationListener(NavigationStatusListener l);
+
+    /**
+     * Remove a listener for viewpoint status messages. If this listener is
+     * not currently registered, the request will be silently ignored.
+     *
+     * @param l The listener instance to remove
+     */
+    void removeNavigationListener(NavigationStatusListener l);
+}
+
diff --git a/src/java/org/xj3d/core/eventmodel/NavigationStatusListenerMulticaster.java b/src/java/org/xj3d/core/eventmodel/NavigationStatusListenerMulticaster.java
index 179784ea8fe894a20cd6b5b4ec8c60affd91ec7e..567b87c0a8b92efd8b276fe2642c4ea2c53e296a 100644
--- a/src/java/org/xj3d/core/eventmodel/NavigationStatusListenerMulticaster.java
+++ b/src/java/org/xj3d/core/eventmodel/NavigationStatusListenerMulticaster.java
@@ -1,362 +1,362 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.core.eventmodel;
-
-// External imports
-import java.util.List;
-
-// Local imports
-import org.j3d.util.DefaultErrorReporter;
-import org.j3d.util.ErrorReporter;
-
-import org.web3d.vrml.nodes.VRMLNavigationInfoNodeType;
-
-/**
- * A class which implements efficient and thread-safe multi-cast event
- * dispatching for the events defined in this package.
- * <p>
- *
- * This class will manage an immutable structure consisting of a chain of
- * event listeners and will dispatch events to those listeners.  Because
- * the structure is immutable, it is safe to use this API to add/remove
- * listeners during the process of an event dispatch operation.
- * <p>
- *
- * An example of how this class could be used to implement a new
- * component which fires "action" events:
- *
- * <pre><code>
- * public myComponent extends Component {
- *   NavigationStatusListener listener = null;
- *
- *   public void addNodeListener(NavigationStatusListener l) {
- *     listener = NavigationStatusListenerMulticaster.add(listener, l);
- *   }
- *
- *   public void removeNodeListener(NavigationStatusListener l) {
- *     listener = NavigationStatusListenerMulticaster.remove(listener, l);
- *   }
- *
- *   public void browerChanged(NavigationStatusEvent evt) {
- *     if(listener != null) {
- *       listener.browserChanged(evt);
- *   }
- * }
- * </code></pre>
- *
- * @author  Justin Couch
- * @version $Revision: 1.2 $
- */
-public class NavigationStatusListenerMulticaster
-    implements NavigationStatusListener {
-
-    /** Error message when the user code barfs */
-    private static final String NAV_SELECT_ERROR_MSG =
-        "Error sending navigation info selection message: ";
-
-    /** Error message when the user code barfs */
-    private static final String NAV_CHANGE_ERROR_MSG =
-        "Error sending navigation info change message: ";
-
-    /** Error message when the user code barfs */
-    private static final String NAV_STATE_ERROR_MSG =
-        "Error sending navigation state change message: ";
-
-    /** Error message when the user code barfs */
-    private static final String NAV_LIST_ERROR_MSG =
-        "Error sending navigation type listing message: ";
-
-    /** Default error message when sending the error message fails */
-    private static final String DEFAULT_ERR_MSG =
-        "Unknown error sending viewpoint event: ";
-
-    /** The node listeners in use by this class */
-    private final NavigationStatusListener a;
-
-    /** The node listeners in use by this class */
-    private final NavigationStatusListener b;
-
-    /** Reporter instance for handing out errors */
-    private static ErrorReporter errorReporter =
-        DefaultErrorReporter.getDefaultReporter();
-
-    /**
-     * Creates an event multicaster instance which chains listener-a
-     * with listener-b. Input parameters <code>a</code> and <code>b</code>
-     * should not be <code>null</code>, though implementations may vary in
-     * choosing whether or not to throw <code>NullPointerException</code>
-     * in that case.
-     * @param a listener-a
-     * @param b listener-b
-     */
-    NavigationStatusListenerMulticaster(NavigationStatusListener a,
-                                        NavigationStatusListener b) {
-        this.a = a;
-        this.b = b;
-    }
-
-    /**
-     * Removes a listener from this multicaster and returns the
-     * resulting multicast listener.
-     * @param oldl the listener to be removed
-     */
-    NavigationStatusListener remove(NavigationStatusListener oldl) {
-
-        if(oldl == a)
-            return b;
-
-        if(oldl == b)
-            return a;
-
-        NavigationStatusListener a2 = removeInternal(a, oldl);
-        NavigationStatusListener b2 = removeInternal(b, oldl);
-
-        if (a2 == a && b2 == b) {
-            return this;  // it's not here
-        }
-
-        return addInternal(a2, b2);
-    }
-
-    /**
-     * Register an error reporter with the engine so that any errors generated
-     * by the loading of script code can be reported in a nice, pretty fashion.
-     * Setting a value of null will clear the currently set reporter. If one
-     * is already set, the new value replaces the old.
-     *
-     * @param reporter The instance to use or null
-     */
-    public static void setErrorReporter(ErrorReporter reporter) {
-        errorReporter = reporter;
-
-        // Reset the default only if we are not shutting down the system.
-        if(reporter == null)
-            errorReporter = DefaultErrorReporter.getDefaultReporter();
-    }
-
-    /**
-     * Adds input-method-listener-a with input-method-listener-b and
-     * returns the resulting multicast listener.
-     * @param a input-method-listener-a
-     * @param b input-method-listener-b
-     * @return 
-     */
-    public static NavigationStatusListener add(NavigationStatusListener a,
-                                              NavigationStatusListener b) {
-        return addInternal(a, b);
-    }
-
-    /**
-     * Removes the old component-listener from component-listener-l and
-     * returns the resulting multicast listener.
-     * @param l component-listener-l
-     * @param oldl the component-listener being removed
-     * @return 
-     */
-    public static NavigationStatusListener remove(NavigationStatusListener l,
-                                                 NavigationStatusListener oldl) {
-        return removeInternal(l, oldl);
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by NavigationStatusListener
-    //----------------------------------------------------------
-
-    /**
-     * The list of available navigation states has changed to this new list.
-     * The list of states corresponds to the X3D-specification defined list
-     * and any additional browser-specific state names. If a state is not
-     * listed in this array, then the ability to activate it should be
-     * disabled (e.g. greying out the button that represents it). If no states
-     * are currently defined, this will contain the default string "NONE",
-     * which corresponds to disabling all user selection of navigation and
-     * even the ability to navigate.
-     *
-     * @param states An array of the available state strings.
-     */
-    @Override
-    public void availableNavigationInfoChanged(VRMLNavigationInfoNodeType[] states) {
-        try {
-            a.availableNavigationInfoChanged(states);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(NAV_CHANGE_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.availableNavigationInfoChanged(states);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(NAV_CHANGE_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-
-    /**
-     * Notification that the currently selected navigation state has changed
-     * to this new value. Selection may be due to the UI interaction,
-     * courtesy of a node being bound or the active navigation layer has
-     * changed.
-     *
-     * @param state The name of the state that is now the active state
-     */
-    @Override
-    public void selectedNavigationInfoChanged(VRMLNavigationInfoNodeType state) {
-        try {
-            a.selectedNavigationInfoChanged(state);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(NAV_SELECT_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.selectedNavigationInfoChanged(state);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(NAV_SELECT_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-
-    /**
-     * Notification that the navigation state of the currently selected
-     * navigation info has changed to the new state.
-     *
-     * @param idx The new state expressed as an index into the current
-     *     navModes list.
-     */
-    @Override
-    public void navigationStateChanged(int idx) {
-        try {
-            a.navigationStateChanged(idx);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(NAV_STATE_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.navigationStateChanged(idx);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(NAV_STATE_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-
-    /**
-     * Notification that the list of valid navigation modes of the current
-     * navigation info node has changed.
-     *
-     * @param modes The new modes
-     */
-    @Override
-    public void navigationListChanged(List<String> modes) {
-        try {
-            a.navigationListChanged(modes);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(NAV_LIST_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.navigationListChanged(modes);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(NAV_LIST_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-
-    //----------------------------------------------------------
-    // Local Methods
-    //----------------------------------------------------------
-
-    /**
-     * Returns the resulting multicast listener from adding listener-a
-     * and listener-b together.
-     * If listener-a is null, it returns listener-b;
-     * If listener-b is null, it returns listener-a
-     * If neither are null, then it creates and returns
-     *     a new NavigationStatusMulticaster instance which chains a with b.
-     * @param a event listener-a
-     * @param b event listener-b
-     */
-    private static NavigationStatusListener addInternal(NavigationStatusListener a,
-                                                        NavigationStatusListener b) {
-        if(a == null)
-            return b;
-
-        if(b == null)
-            return a;
-
-        return new NavigationStatusListenerMulticaster(a, b);
-    }
-
-    /**
-     * Returns the resulting multicast listener after removing the
-     * old listener from listener-l.
-     * If listener-l equals the old listener OR listener-l is null,
-     * returns null.
-     * Else if listener-l is an instance of NavigationStatusMulticaster,
-     * then it removes the old listener from it.
-     * Else, returns listener l.
-     * @param l the listener being removed from
-     * @param oldl the listener being removed
-     */
-    private static NavigationStatusListener removeInternal(NavigationStatusListener l,
-                                                          NavigationStatusListener oldl) {
-        if (l == oldl || l == null) {
-            return null;
-        } else if (l instanceof NavigationStatusListenerMulticaster) {
-            return ((NavigationStatusListenerMulticaster)l).remove(oldl);
-        } else {
-            return l;   // it's not here
-        }
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.core.eventmodel;
+
+// External imports
+import java.util.List;
+
+// Local imports
+import org.j3d.util.DefaultErrorReporter;
+import org.j3d.util.ErrorReporter;
+
+import org.web3d.vrml.nodes.VRMLNavigationInfoNodeType;
+
+/**
+ * A class which implements efficient and thread-safe multi-cast event
+ * dispatching for the events defined in this package.
+ * <p>
+ *
+ * This class will manage an immutable structure consisting of a chain of
+ * event listeners and will dispatch events to those listeners.  Because
+ * the structure is immutable, it is safe to use this API to add/remove
+ * listeners during the process of an event dispatch operation.
+ * <p>
+ *
+ * An example of how this class could be used to implement a new
+ * component which fires "action" events:
+ *
+ * <pre><code>
+ * public myComponent extends Component {
+ *   NavigationStatusListener listener = null;
+ *
+ *   public void addNodeListener(NavigationStatusListener l) {
+ *     listener = NavigationStatusListenerMulticaster.add(listener, l);
+ *   }
+ *
+ *   public void removeNodeListener(NavigationStatusListener l) {
+ *     listener = NavigationStatusListenerMulticaster.remove(listener, l);
+ *   }
+ *
+ *   public void browerChanged(NavigationStatusEvent evt) {
+ *     if(listener != null) {
+ *       listener.browserChanged(evt);
+ *   }
+ * }
+ * </code></pre>
+ *
+ * @author  Justin Couch
+ * @version $Revision: 1.2 $
+ */
+public class NavigationStatusListenerMulticaster
+    implements NavigationStatusListener {
+
+    /** Error message when the user code barfs */
+    private static final String NAV_SELECT_ERROR_MSG =
+        "Error sending navigation info selection message: ";
+
+    /** Error message when the user code barfs */
+    private static final String NAV_CHANGE_ERROR_MSG =
+        "Error sending navigation info change message: ";
+
+    /** Error message when the user code barfs */
+    private static final String NAV_STATE_ERROR_MSG =
+        "Error sending navigation state change message: ";
+
+    /** Error message when the user code barfs */
+    private static final String NAV_LIST_ERROR_MSG =
+        "Error sending navigation type listing message: ";
+
+    /** Default error message when sending the error message fails */
+    private static final String DEFAULT_ERR_MSG =
+        "Unknown error sending viewpoint event: ";
+
+    /** The node listeners in use by this class */
+    private final NavigationStatusListener a;
+
+    /** The node listeners in use by this class */
+    private final NavigationStatusListener b;
+
+    /** Reporter instance for handing out errors */
+    private static ErrorReporter errorReporter =
+        DefaultErrorReporter.getDefaultReporter();
+
+    /**
+     * Creates an event multicaster instance which chains listener-a
+     * with listener-b. Input parameters <code>a</code> and <code>b</code>
+     * should not be <code>null</code>, though implementations may vary in
+     * choosing whether or not to throw <code>NullPointerException</code>
+     * in that case.
+     * @param a listener-a
+     * @param b listener-b
+     */
+    NavigationStatusListenerMulticaster(NavigationStatusListener a,
+                                        NavigationStatusListener b) {
+        this.a = a;
+        this.b = b;
+    }
+
+    /**
+     * Removes a listener from this multicaster and returns the
+     * resulting multicast listener.
+     * @param oldl the listener to be removed
+     */
+    NavigationStatusListener remove(NavigationStatusListener oldl) {
+
+        if(oldl == a)
+            return b;
+
+        if(oldl == b)
+            return a;
+
+        NavigationStatusListener a2 = removeInternal(a, oldl);
+        NavigationStatusListener b2 = removeInternal(b, oldl);
+
+        if (a2 == a && b2 == b) {
+            return this;  // it's not here
+        }
+
+        return addInternal(a2, b2);
+    }
+
+    /**
+     * Register an error reporter with the engine so that any errors generated
+     * by the loading of script code can be reported in a nice, pretty fashion.
+     * Setting a value of null will clear the currently set reporter. If one
+     * is already set, the new value replaces the old.
+     *
+     * @param reporter The instance to use or null
+     */
+    public static void setErrorReporter(ErrorReporter reporter) {
+        errorReporter = reporter;
+
+        // Reset the default only if we are not shutting down the system.
+        if(reporter == null)
+            errorReporter = DefaultErrorReporter.getDefaultReporter();
+    }
+
+    /**
+     * Adds input-method-listener-a with input-method-listener-b and
+     * returns the resulting multicast listener.
+     * @param a input-method-listener-a
+     * @param b input-method-listener-b
+     * @return 
+     */
+    public static NavigationStatusListener add(NavigationStatusListener a,
+                                              NavigationStatusListener b) {
+        return addInternal(a, b);
+    }
+
+    /**
+     * Removes the old component-listener from component-listener-l and
+     * returns the resulting multicast listener.
+     * @param l component-listener-l
+     * @param oldl the component-listener being removed
+     * @return 
+     */
+    public static NavigationStatusListener remove(NavigationStatusListener l,
+                                                 NavigationStatusListener oldl) {
+        return removeInternal(l, oldl);
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by NavigationStatusListener
+    //----------------------------------------------------------
+
+    /**
+     * The list of available navigation states has changed to this new list.
+     * The list of states corresponds to the X3D-specification defined list
+     * and any additional browser-specific state names. If a state is not
+     * listed in this array, then the ability to activate it should be
+     * disabled (e.g. greying out the button that represents it). If no states
+     * are currently defined, this will contain the default string "NONE",
+     * which corresponds to disabling all user selection of navigation and
+     * even the ability to navigate.
+     *
+     * @param states An array of the available state strings.
+     */
+    @Override
+    public void availableNavigationInfoChanged(VRMLNavigationInfoNodeType[] states) {
+        try {
+            a.availableNavigationInfoChanged(states);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(NAV_CHANGE_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.availableNavigationInfoChanged(states);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(NAV_CHANGE_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+
+    /**
+     * Notification that the currently selected navigation state has changed
+     * to this new value. Selection may be due to the UI interaction,
+     * courtesy of a node being bound or the active navigation layer has
+     * changed.
+     *
+     * @param state The name of the state that is now the active state
+     */
+    @Override
+    public void selectedNavigationInfoChanged(VRMLNavigationInfoNodeType state) {
+        try {
+            a.selectedNavigationInfoChanged(state);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(NAV_SELECT_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.selectedNavigationInfoChanged(state);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(NAV_SELECT_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+
+    /**
+     * Notification that the navigation state of the currently selected
+     * navigation info has changed to the new state.
+     *
+     * @param idx The new state expressed as an index into the current
+     *     navModes list.
+     */
+    @Override
+    public void navigationStateChanged(int idx) {
+        try {
+            a.navigationStateChanged(idx);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(NAV_STATE_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.navigationStateChanged(idx);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(NAV_STATE_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+
+    /**
+     * Notification that the list of valid navigation modes of the current
+     * navigation info node has changed.
+     *
+     * @param modes The new modes
+     */
+    @Override
+    public void navigationListChanged(List<String> modes) {
+        try {
+            a.navigationListChanged(modes);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(NAV_LIST_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.navigationListChanged(modes);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(NAV_LIST_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+
+    //----------------------------------------------------------
+    // Local Methods
+    //----------------------------------------------------------
+
+    /**
+     * Returns the resulting multicast listener from adding listener-a
+     * and listener-b together.
+     * If listener-a is null, it returns listener-b;
+     * If listener-b is null, it returns listener-a
+     * If neither are null, then it creates and returns
+     *     a new NavigationStatusMulticaster instance which chains a with b.
+     * @param a event listener-a
+     * @param b event listener-b
+     */
+    private static NavigationStatusListener addInternal(NavigationStatusListener a,
+                                                        NavigationStatusListener b) {
+        if(a == null)
+            return b;
+
+        if(b == null)
+            return a;
+
+        return new NavigationStatusListenerMulticaster(a, b);
+    }
+
+    /**
+     * Returns the resulting multicast listener after removing the
+     * old listener from listener-l.
+     * If listener-l equals the old listener OR listener-l is null,
+     * returns null.
+     * Else if listener-l is an instance of NavigationStatusMulticaster,
+     * then it removes the old listener from it.
+     * Else, returns listener l.
+     * @param l the listener being removed from
+     * @param oldl the listener being removed
+     */
+    private static NavigationStatusListener removeInternal(NavigationStatusListener l,
+                                                          NavigationStatusListener oldl) {
+        if (l == oldl || l == null) {
+            return null;
+        } else if (l instanceof NavigationStatusListenerMulticaster) {
+            return ((NavigationStatusListenerMulticaster)l).remove(oldl);
+        } else {
+            return l;   // it's not here
+        }
+    }
+}
diff --git a/src/java/org/xj3d/core/eventmodel/NetworkProtocolHandler.java b/src/java/org/xj3d/core/eventmodel/NetworkProtocolHandler.java
index 2c2bb5593784a56b918ce6da31e597066f789415..d55e7f444bc74caa8162cdc8bf82f5891309a141 100644
--- a/src/java/org/xj3d/core/eventmodel/NetworkProtocolHandler.java
+++ b/src/java/org/xj3d/core/eventmodel/NetworkProtocolHandler.java
@@ -44,8 +44,7 @@ public interface NetworkProtocolHandler {
     void setErrorReporter(ErrorReporter reporter);
 
     /**
-     * Processes network traffic (DIS). Correct from Cartesian to DIS 
-     * coordinates.
+     * Process network traffic now.
      */
     void processNetworkTraffic();
 
diff --git a/src/java/org/xj3d/core/eventmodel/PickingManager.java b/src/java/org/xj3d/core/eventmodel/PickingManager.java
index 1dc9a4a932233cb342301846cd5b4fabc56f262e..0a208d1f396b2279e4e0650c119ae1480294f217 100644
--- a/src/java/org/xj3d/core/eventmodel/PickingManager.java
+++ b/src/java/org/xj3d/core/eventmodel/PickingManager.java
@@ -23,10 +23,12 @@ import org.web3d.vrml.nodes.VRMLPickingSensorNodeType;
 /**
  * An abstract representation of a class that would be responsible for
  * performing all the picking component by the class.
+ * <p>
  *
  * It is expected that the manager will be implemented by each renderer as
  * working out when sensors intersect and interact will require in-depth
  * knowledge of the rendering API.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/xj3d/core/eventmodel/Router.java b/src/java/org/xj3d/core/eventmodel/Router.java
index 7ae525585b1ced00c5f94094fedc22aae237a39a..cf9d7b59a9c18209c020082e02bf906c43398e44 100644
--- a/src/java/org/xj3d/core/eventmodel/Router.java
+++ b/src/java/org/xj3d/core/eventmodel/Router.java
@@ -22,12 +22,14 @@ import org.web3d.vrml.nodes.VRMLNodeType;
 
 /**
  * A runtime evaluator of routes for a single execution space.
+ * <p>
  *
  * The implementation provides a one-shot route processing mechanism. It does
  * not continuously evaluate routes. That is left to the caller code. Once the
  * processRoutes() method is called, it will loop through all available routes
  * exactly once and return to the caller. This is to conform with the
  * requirements of the event cascade processing defined in the VRML spec.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/xj3d/core/eventmodel/UserInputHandler.java b/src/java/org/xj3d/core/eventmodel/UserInputHandler.java
index 3fb785f52e051e18ec9e5a37e626cfd9c42326ad..69b05006de88470f44c8684699d1a543f9c7aab0 100644
--- a/src/java/org/xj3d/core/eventmodel/UserInputHandler.java
+++ b/src/java/org/xj3d/core/eventmodel/UserInputHandler.java
@@ -1,267 +1,267 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.core.eventmodel;
-
-// External imports
-import javax.vecmath.Vector3f;
-import javax.vecmath.AxisAngle4f;
-
-import org.j3d.device.input.TrackerState;
-
-// Local imports
-import org.web3d.vrml.nodes.VRMLClock;
-import org.web3d.vrml.nodes.VRMLNavigationInfoNodeType;
-import org.web3d.browser.NavigationStateListener;
-import org.web3d.browser.SensorStatusListener;
-
-/**
- * A complete handler for all user input information within a scene.
- * <p>
- *
- * The handler takes care of all the handling needed for sensors, anchors,
- * navigation and keyboard. However, it does not define a way of sourcing
- * those events as it assumes that a user will either delegate or extend this
- * class with more specific information such as an AWT listener or Java3D
- * behavior.
- * <p>
- *
- * The current key handling does not allow keyboard navigation of the world.
- * It passes all key events directly through to the current key sensor if one
- * is registered.
- *
- * @author Alan Hudson
- * @version $Revision: 1.7 $
- */
-public interface UserInputHandler extends OriginListener {
-
-    /**
-     * Process a tracker press event. This may be used to start a touchSensor,
-     * start of a drag sensor or navigation
-     *
-     * @param tracker The id of the tracker calling this handler
-     * @param evt The event that caused the method to be called
-     */
-    void trackerPressed(int tracker, TrackerState evt);
-
-    /**
-     * Process a tracker press event. This may be used to start a touchtracker,
-     * start of a drag tracker or navigation
-     *
-     * @param tracker The id of the tracker calling this handler
-     * @param evt The event that caused the method to be called
-     */
-    void trackerMoved(int tracker, TrackerState evt);
-
-    /**
-     * Process a tracker press event. This may be used to start a touchtracker,
-     * start of a drag tracker or navigation
-     *
-     * @param tracker The id of the tracker calling this handler
-     * @param evt The event that caused the method to be called
-     */
-    void trackerDragged(int tracker, TrackerState evt);
-
-    /**
-     * Process a tracker press event. This may be used to start a touchtracker,
-     * start of a drag tracker or navigation
-     *
-     * @param tracker The id of the tracker calling this handler
-     * @param evt The event that caused the method to be called
-     */
-    void trackerReleased(int tracker, TrackerState evt);
-
-    /**
-     * Process a tracker click event. The click is used only on touch trackers
-     * and anchors. We treat it like a cross between a select and unselect.
-     *
-     * @param tracker The id of the tracker calling this handler
-     * @param evt The event that caused the method to be called
-     */
-    void trackerClicked(int tracker, TrackerState evt);
-
-    /**
-     * Process a tracker orientation event. This is for trackers like HMDs that
-     * can change orientation without changing position or other state.
-     *
-     * @param tracker The id of the tracker calling this handler
-     * @param evt The event that caused the method to be called
-     */
-    void trackerOrientation(int tracker, TrackerState evt);
-
-    /**
-     * Process any navigation velocity.  Call every frame while a drag
-     * is active.
-     */
-    void processNavigation();
-
-    /**
-     * Process the buttons on a tracker.  No other state will be read.
-     *
-     * @param tracker The id of the tracker calling this handler
-     * @param state The current state.
-     */
-    void trackerButton(int tracker, TrackerState state);
-
-    /**
-     * Process the wheel on a tracker.  No other state will be read.
-     *
-     * @param tracker The id of the tracker calling this handler
-     * @param state The current state.
-     */
-    void trackerWheel(int tracker, TrackerState state);
-
-    /**
-     * Did the last tracker interaction intersect any active sensors.
-     *
-     * @return true if the tracker intersection an active sensor.
-     */
-    boolean trackerIntersected();
-
-    /**
-     * Sets whether this tracker is eligible to active a sensor.
-     *
-     * @param val Whether its eligible
-     */
-    void setActivateSensors(boolean val);
-
-    /**
-     * Set the desired navigation mode.
-     *
-     * @param mode The requested mode.
-     * @return Whether the mode is valid.
-     */
-    boolean setNavigationMode(String mode);
-
-    /**
-     * Set the navigation info that is used for this scene. The canvas can
-     * then use it to build any user interface interactions it desires. A
-     * value of null will remove the info and is typically used when the
-     * canvas is about to be removed from a universe.
-     *
-     * @param navInfo The new navigation information to be used
-     */
-    void setNavigationInfo(VRMLNavigationInfoNodeType navInfo);
-
-    /**
-     * Add a navigationStateListener. Duplicates and null will be ignored.
-     *
-     * @param l The listener to add
-     */
-    void addNavigationStateListener(NavigationStateListener l);
-
-    /**
-     * Remove a navigationStateListener.
-     *
-     * @param l The listener to remove
-     */
-    void removeNavigationStateListener(NavigationStateListener l);
-
-    /**
-     * Add a sensorStatusListener. Duplicates and null will be ignored.
-     *
-     * @param l The listener to add
-     */
-    void addSensorStatusListener(SensorStatusListener l);
-
-    /**
-     * Remove a sensorStatusListener.
-     *
-     * @param l The listener to remove
-     */
-    void removeSensorStatusListener(SensorStatusListener l);
-
-    /**
-     * Should pointing devices be tested for.
-     *
-     * @param enabled Test for intersection when true
-     */
-    void setTestPointingDevices(boolean enabled);
-
-    /**
-     * Set the world scale applied.  This will scale down navinfo parameters
-     * to fit into the world.
-     *
-     * @param scale The new world scale.
-     */
-    void setWorldScale(float scale);
-
-    /**
-     * Get the current user orientation.
-     *
-     * @param ori The orientation vector to fill in
-     */
-    void getOrientation(AxisAngle4f ori);
-
-    /**
-     * Get the current user position.
-     *
-     * @param pos The position vector to fill in
-     */
-    void getPosition(Vector3f pos);
-
-    /**
-     * Set the center of rotation explicitly to this place. Coordinates must
-     * be in the coordinate space of the current view transform group. The
-     * provided array must be of least length 3. Center of rotation is used
-     * in examine mode.
-     *
-     * @param center The new center to use
-     */
-    void setCenterOfRotation(float[] center);
-
-    /**
-     * Get the currently set navigation state.
-     *
-     * @return true for the current state
-     */
-    boolean getNavigationEnabled();
-
-    /**
-     * Enable or disable navigation processing sub-section of the
-     * user input processing. By default the navigation processing is enabled.
-     * Navigation also means responding to changes in the environment, even
-     * without there being user input to process.
-     *
-     * @param state true to enable navigation
-     */
-    void setNavigationEnabled(boolean state);
-
-    /**
-     * The layer that contains this handler has just been made the active
-     * navigation layer, so send out to the navigation state listeners the
-     * current navigation state for this layer. This allows the UI to update
-     * based on the currently active layer.
-     */
-    void sendCurrentNavState();
-
-    /**
-     * Set the clock we are going to operate from when generating events. A
-     * null value will remove the clock.
-     *
-     * @param clk The new clock to use
-     */
-    void setVRMLClock(VRMLClock clk);
-
-    /**
-     * Clear all the values, listeners etc, except for the clock. Returns the
-     * input handler back to being empty, with no state set.
-     */
-    void clear();
-
-    /**
-     * Set the manager for handling dynamic origin calculation.
-     *
-     * @param manager Reference to the manager instance to use or null
-     */
-    void setOriginManager(OriginManager manager);
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.core.eventmodel;
+
+// External imports
+import javax.vecmath.Vector3f;
+import javax.vecmath.AxisAngle4f;
+
+import org.j3d.device.input.TrackerState;
+
+// Local imports
+import org.web3d.vrml.nodes.VRMLClock;
+import org.web3d.vrml.nodes.VRMLNavigationInfoNodeType;
+import org.web3d.browser.NavigationStateListener;
+import org.web3d.browser.SensorStatusListener;
+
+/**
+ * A complete handler for all user input information within a scene.
+ * <p>
+ *
+ * The handler takes care of all the handling needed for sensors, anchors,
+ * navigation and keyboard. However, it does not define a way of sourcing
+ * those events as it assumes that a user will either delegate or extend this
+ * class with more specific information such as an AWT listener or Java3D
+ * behavior.
+ * <p>
+ *
+ * The current key handling does not allow keyboard navigation of the world.
+ * It passes all key events directly through to the current key sensor if one
+ * is registered.
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.7 $
+ */
+public interface UserInputHandler extends OriginListener {
+
+    /**
+     * Process a tracker press event. This may be used to start a touchSensor,
+     * start of a drag sensor or navigation
+     *
+     * @param tracker The id of the tracker calling this handler
+     * @param evt The event that caused the method to be called
+     */
+    void trackerPressed(int tracker, TrackerState evt);
+
+    /**
+     * Process a tracker press event. This may be used to start a touchtracker,
+     * start of a drag tracker or navigation
+     *
+     * @param tracker The id of the tracker calling this handler
+     * @param evt The event that caused the method to be called
+     */
+    void trackerMoved(int tracker, TrackerState evt);
+
+    /**
+     * Process a tracker press event. This may be used to start a touchtracker,
+     * start of a drag tracker or navigation
+     *
+     * @param tracker The id of the tracker calling this handler
+     * @param evt The event that caused the method to be called
+     */
+    void trackerDragged(int tracker, TrackerState evt);
+
+    /**
+     * Process a tracker press event. This may be used to start a touchtracker,
+     * start of a drag tracker or navigation
+     *
+     * @param tracker The id of the tracker calling this handler
+     * @param evt The event that caused the method to be called
+     */
+    void trackerReleased(int tracker, TrackerState evt);
+
+    /**
+     * Process a tracker click event. The click is used only on touch trackers
+     * and anchors. We treat it like a cross between a select and unselect.
+     *
+     * @param tracker The id of the tracker calling this handler
+     * @param evt The event that caused the method to be called
+     */
+    void trackerClicked(int tracker, TrackerState evt);
+
+    /**
+     * Process a tracker orientation event. This is for trackers like HMDs that
+     * can change orientation without changing position or other state.
+     *
+     * @param tracker The id of the tracker calling this handler
+     * @param evt The event that caused the method to be called
+     */
+    void trackerOrientation(int tracker, TrackerState evt);
+
+    /**
+     * Process any navigation velocity.  Call every frame while a drag
+     * is active.
+     */
+    void processNavigation();
+
+    /**
+     * Process the buttons on a tracker.  No other state will be read.
+     *
+     * @param tracker The id of the tracker calling this handler
+     * @param state The current state.
+     */
+    void trackerButton(int tracker, TrackerState state);
+
+    /**
+     * Process the wheel on a tracker.  No other state will be read.
+     *
+     * @param tracker The id of the tracker calling this handler
+     * @param state The current state.
+     */
+    void trackerWheel(int tracker, TrackerState state);
+
+    /**
+     * Did the last tracker interaction intersect any active sensors.
+     *
+     * @return true if the tracker intersection an active sensor.
+     */
+    boolean trackerIntersected();
+
+    /**
+     * Sets whether this tracker is eligible to active a sensor.
+     *
+     * @param val Whether its eligible
+     */
+    void setActivateSensors(boolean val);
+
+    /**
+     * Set the desired navigation mode.
+     *
+     * @param mode The requested mode.
+     * @return Whether the mode is valid.
+     */
+    boolean setNavigationMode(String mode);
+
+    /**
+     * Set the navigation info that is used for this scene. The canvas can
+     * then use it to build any user interface interactions it desires. A
+     * value of null will remove the info and is typically used when the
+     * canvas is about to be removed from a universe.
+     *
+     * @param navInfo The new navigation information to be used
+     */
+    void setNavigationInfo(VRMLNavigationInfoNodeType navInfo);
+
+    /**
+     * Add a navigationStateListener. Duplicates and null will be ignored.
+     *
+     * @param l The listener to add
+     */
+    void addNavigationStateListener(NavigationStateListener l);
+
+    /**
+     * Remove a navigationStateListener.
+     *
+     * @param l The listener to remove
+     */
+    void removeNavigationStateListener(NavigationStateListener l);
+
+    /**
+     * Add a sensorStatusListener. Duplicates and null will be ignored.
+     *
+     * @param l The listener to add
+     */
+    void addSensorStatusListener(SensorStatusListener l);
+
+    /**
+     * Remove a sensorStatusListener.
+     *
+     * @param l The listener to remove
+     */
+    void removeSensorStatusListener(SensorStatusListener l);
+
+    /**
+     * Should pointing devices be tested for.
+     *
+     * @param enabled Test for intersection when true
+     */
+    void setTestPointingDevices(boolean enabled);
+
+    /**
+     * Set the world scale applied.  This will scale down navinfo parameters
+     * to fit into the world.
+     *
+     * @param scale The new world scale.
+     */
+    void setWorldScale(float scale);
+
+    /**
+     * Get the current user orientation.
+     *
+     * @param ori The orientation vector to fill in
+     */
+    void getOrientation(AxisAngle4f ori);
+
+    /**
+     * Get the current user position.
+     *
+     * @param pos The position vector to fill in
+     */
+    void getPosition(Vector3f pos);
+
+    /**
+     * Set the center of rotation explicitly to this place. Coordinates must
+     * be in the coordinate space of the current view transform group. The
+     * provided array must be of least length 3. Center of rotation is used
+     * in examine mode.
+     *
+     * @param center The new center to use
+     */
+    void setCenterOfRotation(float[] center);
+
+    /**
+     * Get the currently set navigation state.
+     *
+     * @return true for the current state
+     */
+    boolean getNavigationEnabled();
+
+    /**
+     * Enable or disable navigation processing sub-section of the
+     * user input processing. By default the navigation processing is enabled.
+     * Navigation also means responding to changes in the environment, even
+     * without there being user input to process.
+     *
+     * @param state true to enable navigation
+     */
+    void setNavigationEnabled(boolean state);
+
+    /**
+     * The layer that contains this handler has just been made the active
+     * navigation layer, so send out to the navigation state listeners the
+     * current navigation state for this layer. This allows the UI to update
+     * based on the currently active layer.
+     */
+    void sendCurrentNavState();
+
+    /**
+     * Set the clock we are going to operate from when generating events. A
+     * null value will remove the clock.
+     *
+     * @param clk The new clock to use
+     */
+    void setVRMLClock(VRMLClock clk);
+
+    /**
+     * Clear all the values, listeners etc, except for the clock. Returns the
+     * input handler back to being empty, with no state set.
+     */
+    void clear();
+
+    /**
+     * Set the manager for handling dynamic origin calculation.
+     *
+     * @param manager Reference to the manager instance to use or null
+     */
+    void setOriginManager(OriginManager manager);
+}
diff --git a/src/java/org/xj3d/core/eventmodel/ViewpointManager.java b/src/java/org/xj3d/core/eventmodel/ViewpointManager.java
index 944e071efc31b40a5778a75000847b9a44f9df79..733c09887c96b59ec722febeda962bd9e951439b 100644
--- a/src/java/org/xj3d/core/eventmodel/ViewpointManager.java
+++ b/src/java/org/xj3d/core/eventmodel/ViewpointManager.java
@@ -1,174 +1,174 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2005 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.core.eventmodel;
-
-// External imports
-import java.util.List;
-
-// Local imports
-import org.j3d.util.ErrorReporter;
-import org.web3d.vrml.nodes.VRMLViewpointNodeType;
-
-/**
- * An abstract representation of a class that would be responsible for
- * performing Viewpoint management.
- * <p>
- *
- * This interface represents a further abstracted view of viewpoint management
- * handling beyond the {@link org.web3d.browser.BrowserCore}. This gives you
- * all the handling that is normally seen at a user interface level. You should
- * use one or the other, but not both as implementations of this class will
- * also interact with BrowserCore.
- *
- * @author Alan Hudson
- * @version $Revision: 1.7 $
- */
-public interface ViewpointManager {
-
-    /**
-     * Update the viewpoint. Called at the beginning of the event model.
-     *
-     * @param time The time of the current event model.
-     */
-    void updateViewpoint(long time);
-
-    /**
-     * Shutdown the node manager now. If this is using any external resources
-     * it should remove those now as the entire application is about to die
-     */
-    void shutdown();
-
-    /**
-     * Register an error reporter with the engine so that any errors generated
-     * by the loading of script code can be reported in a nice, pretty fashion.
-     * Setting a value of null will clear the currently set reporter. If one
-     * is already set, the new value replaces the old.
-     *
-     * @param reporter The instance to use or null
-     */
-    void setErrorReporter(ErrorReporter reporter);
-
-    /**
-     * Set the current viewpoint to an arbitrary instance.
-     *
-     * @param viewpoint The new current viewpoint.
-     */
-    void setViewpoint(VRMLViewpointNodeType viewpoint);
-
-    /**
-     * Go to the first declared viewpoint at the next available opportunity.
-     * This corresponds to the SAI Browser.firstViewpoint() call.
-     */
-    void firstViewpoint();
-
-    /**
-     * Go to the first declared viewpoint in the specified layer at the
-     * next available opportunity. This corresponds to the SAI
-     * Browser.firstViewpoint() call.
-     *
-     * @param layer The ID of the layer. Must be between 0 and the maximum
-     *   layer number
-     */
-    void firstViewpoint(int layer);
-
-    /**
-     * Go to the last declared viewpoint at the next available opportunity.
-     * This corresponds to the SAI Browser.lastViewpoint() call.
-     */
-    void lastViewpoint();
-
-    /**
-     * Go to the last declared viewpoint of the specified layer at the next
-     * available opportunity. This corresponds to the SAI
-     * Browser.lastViewpoint() call.
-     *
-     * @param layer The ID of the layer. Must be between 0 and the maximum
-     *   layer number
-     */
-    void lastViewpoint(int layer);
-
-    /**
-     * Reset the viewpoint back to its original values.
-     */
-    void resetViewpoint();
-
-    /**
-     * Go to the next viewpoint at the next available opportunity. It looks at
-     * the added list for the index of the current viewpoint and moves to the
-     * next index it can find. This corresponds to the SAI
-     * Browser.nextViewpoint() call.
-     */
-    void nextViewpoint();
-
-    /**
-     * Go to the next viewpoint at the next available opportunity. It looks at
-     * the added list for the index of the current viewpoint and moves to the
-     * next index it can find for the specific layer ID. This corresponds to the
-     * SAI Browser.previousViewpoint() call.
-     *
-     * @param layer The ID of the layer. Must be between 0 and the maximum
-     *   layer number
-     */
-    void nextViewpoint(int layer);
-
-    /**
-     * Go to the previous viewpoint at the next available opportunity. It looks at
-     * the added list for the index of the current viewpoint and moves to the
-     * previous index it can find. This corresponds to the SAI
-     * Browser.previousViewpoint() call.
-     */
-    void previousViewpoint();
-
-    /**
-     * Go to the previous viewpoint at the next available opportunity. It looks at
-     * the added list for the index of the current viewpoint and moves to the
-     * previous index it can find for the specific layer ID. This corresponds to the
-     * SAI Browser.previousViewpoint() call.
-     *
-     * @param layer The ID of the layer. Must be between 0 and the maximum
-     *   layer number
-     */
-    void previousViewpoint(int layer);
-
-    /**
-     * Force clearing all currently managed nodes from this manager now. This
-     * is used to indicate that a new world is about to be loaded and
-     * everything should be cleaned out now.
-     */
-    void clear();
-
-    /**
-     * Gets the viewpoints for the currently active layer.
-     *
-     * @return A list of the viewpoint nodes for the currently active layer
-     */
-    List<VRMLViewpointNodeType> getActiveViewpoints();
-
-    /**
-     * Add a listener for viewpoint status messages. Adding the same listener
-     * instance more than once will be silently ignored. Null values are
-     * ignored.
-     *
-     * @param l The listener instance to add
-     */
-    void addViewpointListener(ViewpointStatusListener l);
-
-    /**
-     * Remove a listener for viewpoint status messages. If this listener is
-     * not currently registered, the request will be silently ignored.
-     *
-     * @param l The listener instance to remove
-     */
-    void removeViewpointListener(ViewpointStatusListener l);
-}
-
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2005 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.core.eventmodel;
+
+// External imports
+import java.util.List;
+
+// Local imports
+import org.j3d.util.ErrorReporter;
+import org.web3d.vrml.nodes.VRMLViewpointNodeType;
+
+/**
+ * An abstract representation of a class that would be responsible for
+ * performing Viewpoint management.
+ * <p>
+ *
+ * This interface represents a further abstracted view of viewpoint management
+ * handling beyond the {@link org.web3d.browser.BrowserCore}. This gives you
+ * all the handling that is normally seen at a user interface level. You should
+ * use one or the other, but not both as implementations of this class will
+ * also interact with BrowserCore.
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.7 $
+ */
+public interface ViewpointManager {
+
+    /**
+     * Update the viewpoint. Called at the beginning of the event model.
+     *
+     * @param time The time of the current event model.
+     */
+    void updateViewpoint(long time);
+
+    /**
+     * Shutdown the node manager now. If this is using any external resources
+     * it should remove those now as the entire application is about to die
+     */
+    void shutdown();
+
+    /**
+     * Register an error reporter with the engine so that any errors generated
+     * by the loading of script code can be reported in a nice, pretty fashion.
+     * Setting a value of null will clear the currently set reporter. If one
+     * is already set, the new value replaces the old.
+     *
+     * @param reporter The instance to use or null
+     */
+    void setErrorReporter(ErrorReporter reporter);
+
+    /**
+     * Set the current viewpoint to an arbitrary instance.
+     *
+     * @param viewpoint The new current viewpoint.
+     */
+    void setViewpoint(VRMLViewpointNodeType viewpoint);
+
+    /**
+     * Go to the first declared viewpoint at the next available opportunity.
+     * This corresponds to the SAI Browser.firstViewpoint() call.
+     */
+    void firstViewpoint();
+
+    /**
+     * Go to the first declared viewpoint in the specified layer at the
+     * next available opportunity. This corresponds to the SAI
+     * Browser.firstViewpoint() call.
+     *
+     * @param layer The ID of the layer. Must be between 0 and the maximum
+     *   layer number
+     */
+    void firstViewpoint(int layer);
+
+    /**
+     * Go to the last declared viewpoint at the next available opportunity.
+     * This corresponds to the SAI Browser.lastViewpoint() call.
+     */
+    void lastViewpoint();
+
+    /**
+     * Go to the last declared viewpoint of the specified layer at the next
+     * available opportunity. This corresponds to the SAI
+     * Browser.lastViewpoint() call.
+     *
+     * @param layer The ID of the layer. Must be between 0 and the maximum
+     *   layer number
+     */
+    void lastViewpoint(int layer);
+
+    /**
+     * Reset the viewpoint back to its original values.
+     */
+    void resetViewpoint();
+
+    /**
+     * Go to the next viewpoint at the next available opportunity. It looks at
+     * the added list for the index of the current viewpoint and moves to the
+     * next index it can find. This corresponds to the SAI
+     * Browser.nextViewpoint() call.
+     */
+    void nextViewpoint();
+
+    /**
+     * Go to the next viewpoint at the next available opportunity. It looks at
+     * the added list for the index of the current viewpoint and moves to the
+     * next index it can find for the specific layer ID. This corresponds to the
+     * SAI Browser.previousViewpoint() call.
+     *
+     * @param layer The ID of the layer. Must be between 0 and the maximum
+     *   layer number
+     */
+    void nextViewpoint(int layer);
+
+    /**
+     * Go to the previous viewpoint at the next available opportunity. It looks at
+     * the added list for the index of the current viewpoint and moves to the
+     * previous index it can find. This corresponds to the SAI
+     * Browser.previousViewpoint() call.
+     */
+    void previousViewpoint();
+
+    /**
+     * Go to the previous viewpoint at the next available opportunity. It looks at
+     * the added list for the index of the current viewpoint and moves to the
+     * previous index it can find for the specific layer ID. This corresponds to the
+     * SAI Browser.previousViewpoint() call.
+     *
+     * @param layer The ID of the layer. Must be between 0 and the maximum
+     *   layer number
+     */
+    void previousViewpoint(int layer);
+
+    /**
+     * Force clearing all currently managed nodes from this manager now. This
+     * is used to indicate that a new world is about to be loaded and
+     * everything should be cleaned out now.
+     */
+    void clear();
+
+    /**
+     * Gets the viewpoints for the currently active layer.
+     *
+     * @return A list of the viewpoint nodes for the currently active layer
+     */
+    List<VRMLViewpointNodeType> getActiveViewpoints();
+
+    /**
+     * Add a listener for viewpoint status messages. Adding the same listener
+     * instance more than once will be silently ignored. Null values are
+     * ignored.
+     *
+     * @param l The listener instance to add
+     */
+    void addViewpointListener(ViewpointStatusListener l);
+
+    /**
+     * Remove a listener for viewpoint status messages. If this listener is
+     * not currently registered, the request will be silently ignored.
+     *
+     * @param l The listener instance to remove
+     */
+    void removeViewpointListener(ViewpointStatusListener l);
+}
+
diff --git a/src/java/org/xj3d/core/eventmodel/ViewpointStatusListenerMulticaster.java b/src/java/org/xj3d/core/eventmodel/ViewpointStatusListenerMulticaster.java
index 002498cb2445115baedff1dc9593820c6954cd4e..8b4d636cbaa54e340d3c065d7bb39e5649c0d3c7 100644
--- a/src/java/org/xj3d/core/eventmodel/ViewpointStatusListenerMulticaster.java
+++ b/src/java/org/xj3d/core/eventmodel/ViewpointStatusListenerMulticaster.java
@@ -1,375 +1,375 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.core.eventmodel;
-
-// External imports
-// none
-
-// Local imports
-import org.j3d.util.DefaultErrorReporter;
-import org.j3d.util.ErrorReporter;
-
-import org.web3d.vrml.nodes.VRMLViewpointNodeType;
-
-/**
- * A class which implements efficient and thread-safe multi-cast event
- * dispatching for the events defined in this package.
- * <p>
- *
- * This class will manage an immutable structure consisting of a chain of
- * event listeners and will dispatch events to those listeners.  Because
- * the structure is immutable, it is safe to use this API to add/remove
- * listeners during the process of an event dispatch operation.
- * <p>
- *
- * An example of how this class could be used to implement a new
- * component which fires "action" events:
- *
- * <pre><code>
- * public myComponent extends Component {
- *   ViewpointStatusListener listener = null;
- *
- *   public void addNodeListener(ViewpointStatusListener l) {
- *     listener = ViewpointStatusListenerMulticaster.add(listener, l);
- *   }
- *
- *   public void removeNodeListener(ViewpointStatusListener l) {
- *     listener = ViewpointStatusListenerMulticaster.remove(listener, l);
- *   }
- *
- *   public void browerChanged(ViewpointStatusEvent evt) {
- *     if(listener != null) {
- *       listener.browserChanged(evt);
- *   }
- * }
- * </code></pre>
- *
- * @author  Justin Couch
- * @version $Revision: 1.3 $
- */
-public class ViewpointStatusListenerMulticaster
-    implements ViewpointStatusListener {
-
-    /** Error message when the user code barfs */
-    private static final String VP_REMOVE_ERROR_MSG =
-        "Error sending viewpoint remove message: ";
-
-    /** Error message when the user code barfs */
-    private static final String VP_ADD_ERROR_MSG =
-        "Error sending viewpoint add message: ";
-
-    /** Error message when the user code barfs */
-    private static final String VP_CHANGE_ERROR_MSG =
-        "Error sending viewpoint list change message: ";
-
-    /** Error message when the user code barfs */
-    private static final String VP_SELECT_ERROR_MSG =
-        "Error sending viewpoint change selection message: ";
-
-    /** Default error message when sending the error message fails */
-    private static final String DEFAULT_ERR_MSG =
-        "Unknown error sending viewpoint event: ";
-
-    /** The node listeners in use by this class */
-    private final ViewpointStatusListener a;
-
-    /** The node listeners in use by this class */
-    private final ViewpointStatusListener b;
-
-    /** Reporter instance for handing out errors */
-    private static ErrorReporter errorReporter =
-        DefaultErrorReporter.getDefaultReporter();
-
-    /**
-     * Creates an event multicaster instance which chains listener-a
-     * with listener-b. Input parameters <code>a</code> and <code>b</code>
-     * should not be <code>null</code>, though implementations may vary in
-     * choosing whether or not to throw <code>NullPointerException</code>
-     * in that case.
-     * @param a listener-a
-     * @param b listener-b
-     */
-    ViewpointStatusListenerMulticaster(ViewpointStatusListener a,
-                                  ViewpointStatusListener b) {
-        this.a = a;
-        this.b = b;
-    }
-
-    /**
-     * Removes a listener from this multicaster and returns the
-     * resulting multicast listener.
-     * @param oldl the listener to be removed
-     */
-    ViewpointStatusListener remove(ViewpointStatusListener oldl) {
-
-        if(oldl == a)
-            return b;
-
-        if(oldl == b)
-            return a;
-
-        ViewpointStatusListener a2 = removeInternal(a, oldl);
-        ViewpointStatusListener b2 = removeInternal(b, oldl);
-
-        if (a2 == a && b2 == b) {
-            return this;  // it's not here
-        }
-
-        return addInternal(a2, b2);
-    }
-
-    /**
-     * Register an error reporter with the engine so that any errors generated
-     * by the loading of script code can be reported in a nice, pretty fashion.
-     * Setting a value of null will clear the currently set reporter. If one
-     * is already set, the new value replaces the old.
-     *
-     * @param reporter The instance to use or null
-     */
-    public static void setErrorReporter(ErrorReporter reporter) {
-        errorReporter = reporter;
-
-        // Reset the default only if we are not shutting down the system.
-        if(reporter == null)
-            errorReporter = DefaultErrorReporter.getDefaultReporter();
-    }
-
-    /**
-     * Adds input-method-listener-a with input-method-listener-b and
-     * returns the resulting multicast listener.
-     * @param a input-method-listener-a
-     * @param b input-method-listener-b
-     * @return 
-     */
-    public static ViewpointStatusListener add(ViewpointStatusListener a,
-                                              ViewpointStatusListener b) {
-        return addInternal(a, b);
-    }
-
-    /**
-     * Removes the old component-listener from component-listener-l and
-     * returns the resulting multicast listener.
-     * @param l component-listener-l
-     * @param oldl the component-listener being removed
-     * @return 
-     */
-    public static ViewpointStatusListener remove(ViewpointStatusListener l,
-                                                 ViewpointStatusListener oldl) {
-        return removeInternal(l, oldl);
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by ViewpointStatusListener
-    //----------------------------------------------------------
-
-    /**
-     * The list of active viewpoints have been changed to this new list. A new
-     * list can be given due to either a new world being loaded, or the active
-     * navigation layer has been changed. This method is not called if a single
-     * viewpoint is added or removed from the scene.
-     * <p>
-     *
-     * If the scene contains no viewpoints at all (except the default bindable),
-     * then this will be called with a null parameter.
-     * <p>
-     *
-     * On scene or navigation layer change, it is guaranteed that this method
-     * will be called before the notification of the actual bound viewpoint.
-     *
-     * @param viewpoints An array of exactly the number of viewpoints in the list
-     */
-    @Override
-    public void availableViewpointsChanged(VRMLViewpointNodeType[] viewpoints) {
-        try {
-            a.availableViewpointsChanged(viewpoints);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(VP_CHANGE_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.availableViewpointsChanged(viewpoints);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(VP_CHANGE_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-
-    /**
-     * Notification that the selected viewpoint has been changed to this
-     * new instance. There are many different reasons this could happen -
-     * new node bound, world changed or even active navigation layer has
-     * changed and this is the default in that new layer.
-     * <p>
-     *
-     * If the file contains no viewpoints or the default viewpoint is
-     * bound (due to unbinding all real viewpoints on the stack) then this
-     * will be called with a null parameter.
-     * <p>
-     *
-     * It is guaranteed that this will always contain something from the
-     * currently active viewpoint list. If all change, that callback will be
-     * called before this one, to ensure consistency.
-     *
-     * @param vp The viewpoint instance that is now selected or null
-     */
-    @Override
-    public void selectedViewpointChanged(VRMLViewpointNodeType vp) {
-        try {
-            a.selectedViewpointChanged(vp);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(VP_SELECT_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.selectedViewpointChanged(vp);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(VP_SELECT_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-
-    /**
-     * Notification that this viewpoint has been appended to the list of
-     * available viewpoints.
-     *
-     * @param vp The viewpoint instance that was added
-     */
-    @Override
-    public void viewpointAdded(VRMLViewpointNodeType vp) {
-        try {
-            a.viewpointAdded(vp);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(VP_ADD_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.viewpointAdded(vp);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(VP_ADD_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-
-    /**
-     * Notification that this viewpoint has been removed from the list of
-     * available viewpoints.
-     *
-     * @param vp The viewpoint instance that was added
-     */
-    @Override
-    public void viewpointRemoved(VRMLViewpointNodeType vp) {
-        try {
-            a.viewpointRemoved(vp);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(VP_REMOVE_ERROR_MSG + a,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-
-        try {
-            b.viewpointRemoved(vp);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(VP_REMOVE_ERROR_MSG + b,
-                                          (Exception)th);
-            else {
-                System.err.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-
-    //----------------------------------------------------------
-    // Local Methods
-    //----------------------------------------------------------
-
-    /**
-     * Returns the resulting multicast listener from adding listener-a
-     * and listener-b together.
-     * If listener-a is null, it returns listener-b;
-     * If listener-b is null, it returns listener-a
-     * If neither are null, then it creates and returns
-     *     a new ViewpointStatusMulticaster instance which chains a with b.
-     * @param a event listener-a
-     * @param b event listener-b
-     */
-    private static ViewpointStatusListener addInternal(ViewpointStatusListener a,
-                                                     ViewpointStatusListener b) {
-        if(a == null)
-            return b;
-
-        if(b == null)
-            return a;
-
-        return new ViewpointStatusListenerMulticaster(a, b);
-    }
-
-    /**
-     * Returns the resulting multicast listener after removing the
-     * old listener from listener-l.
-     * If listener-l equals the old listener OR listener-l is null,
-     * returns null.
-     * Else if listener-l is an instance of ViewpointStatusMulticaster,
-     * then it removes the old listener from it.
-     * Else, returns listener l.
-     * @param l the listener being removed from
-     * @param oldl the listener being removed
-     */
-    private static ViewpointStatusListener removeInternal(ViewpointStatusListener l,
-                                                          ViewpointStatusListener oldl) {
-        if (l == oldl || l == null) {
-            return null;
-        } else if (l instanceof ViewpointStatusListenerMulticaster) {
-            return ((ViewpointStatusListenerMulticaster)l).remove(oldl);
-        } else {
-            return l;   // it's not here
-        }
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.core.eventmodel;
+
+// External imports
+// none
+
+// Local imports
+import org.j3d.util.DefaultErrorReporter;
+import org.j3d.util.ErrorReporter;
+
+import org.web3d.vrml.nodes.VRMLViewpointNodeType;
+
+/**
+ * A class which implements efficient and thread-safe multi-cast event
+ * dispatching for the events defined in this package.
+ * <p>
+ *
+ * This class will manage an immutable structure consisting of a chain of
+ * event listeners and will dispatch events to those listeners.  Because
+ * the structure is immutable, it is safe to use this API to add/remove
+ * listeners during the process of an event dispatch operation.
+ * <p>
+ *
+ * An example of how this class could be used to implement a new
+ * component which fires "action" events:
+ *
+ * <pre><code>
+ * public myComponent extends Component {
+ *   ViewpointStatusListener listener = null;
+ *
+ *   public void addNodeListener(ViewpointStatusListener l) {
+ *     listener = ViewpointStatusListenerMulticaster.add(listener, l);
+ *   }
+ *
+ *   public void removeNodeListener(ViewpointStatusListener l) {
+ *     listener = ViewpointStatusListenerMulticaster.remove(listener, l);
+ *   }
+ *
+ *   public void browerChanged(ViewpointStatusEvent evt) {
+ *     if(listener != null) {
+ *       listener.browserChanged(evt);
+ *   }
+ * }
+ * </code></pre>
+ *
+ * @author  Justin Couch
+ * @version $Revision: 1.3 $
+ */
+public class ViewpointStatusListenerMulticaster
+    implements ViewpointStatusListener {
+
+    /** Error message when the user code barfs */
+    private static final String VP_REMOVE_ERROR_MSG =
+        "Error sending viewpoint remove message: ";
+
+    /** Error message when the user code barfs */
+    private static final String VP_ADD_ERROR_MSG =
+        "Error sending viewpoint add message: ";
+
+    /** Error message when the user code barfs */
+    private static final String VP_CHANGE_ERROR_MSG =
+        "Error sending viewpoint list change message: ";
+
+    /** Error message when the user code barfs */
+    private static final String VP_SELECT_ERROR_MSG =
+        "Error sending viewpoint change selection message: ";
+
+    /** Default error message when sending the error message fails */
+    private static final String DEFAULT_ERR_MSG =
+        "Unknown error sending viewpoint event: ";
+
+    /** The node listeners in use by this class */
+    private final ViewpointStatusListener a;
+
+    /** The node listeners in use by this class */
+    private final ViewpointStatusListener b;
+
+    /** Reporter instance for handing out errors */
+    private static ErrorReporter errorReporter =
+        DefaultErrorReporter.getDefaultReporter();
+
+    /**
+     * Creates an event multicaster instance which chains listener-a
+     * with listener-b. Input parameters <code>a</code> and <code>b</code>
+     * should not be <code>null</code>, though implementations may vary in
+     * choosing whether or not to throw <code>NullPointerException</code>
+     * in that case.
+     * @param a listener-a
+     * @param b listener-b
+     */
+    ViewpointStatusListenerMulticaster(ViewpointStatusListener a,
+                                  ViewpointStatusListener b) {
+        this.a = a;
+        this.b = b;
+    }
+
+    /**
+     * Removes a listener from this multicaster and returns the
+     * resulting multicast listener.
+     * @param oldl the listener to be removed
+     */
+    ViewpointStatusListener remove(ViewpointStatusListener oldl) {
+
+        if(oldl == a)
+            return b;
+
+        if(oldl == b)
+            return a;
+
+        ViewpointStatusListener a2 = removeInternal(a, oldl);
+        ViewpointStatusListener b2 = removeInternal(b, oldl);
+
+        if (a2 == a && b2 == b) {
+            return this;  // it's not here
+        }
+
+        return addInternal(a2, b2);
+    }
+
+    /**
+     * Register an error reporter with the engine so that any errors generated
+     * by the loading of script code can be reported in a nice, pretty fashion.
+     * Setting a value of null will clear the currently set reporter. If one
+     * is already set, the new value replaces the old.
+     *
+     * @param reporter The instance to use or null
+     */
+    public static void setErrorReporter(ErrorReporter reporter) {
+        errorReporter = reporter;
+
+        // Reset the default only if we are not shutting down the system.
+        if(reporter == null)
+            errorReporter = DefaultErrorReporter.getDefaultReporter();
+    }
+
+    /**
+     * Adds input-method-listener-a with input-method-listener-b and
+     * returns the resulting multicast listener.
+     * @param a input-method-listener-a
+     * @param b input-method-listener-b
+     * @return 
+     */
+    public static ViewpointStatusListener add(ViewpointStatusListener a,
+                                              ViewpointStatusListener b) {
+        return addInternal(a, b);
+    }
+
+    /**
+     * Removes the old component-listener from component-listener-l and
+     * returns the resulting multicast listener.
+     * @param l component-listener-l
+     * @param oldl the component-listener being removed
+     * @return 
+     */
+    public static ViewpointStatusListener remove(ViewpointStatusListener l,
+                                                 ViewpointStatusListener oldl) {
+        return removeInternal(l, oldl);
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by ViewpointStatusListener
+    //----------------------------------------------------------
+
+    /**
+     * The list of active viewpoints have been changed to this new list. A new
+     * list can be given due to either a new world being loaded, or the active
+     * navigation layer has been changed. This method is not called if a single
+     * viewpoint is added or removed from the scene.
+     * <p>
+     *
+     * If the scene contains no viewpoints at all (except the default bindable),
+     * then this will be called with a null parameter.
+     * <p>
+     *
+     * On scene or navigation layer change, it is guaranteed that this method
+     * will be called before the notification of the actual bound viewpoint.
+     *
+     * @param viewpoints An array of exactly the number of viewpoints in the list
+     */
+    @Override
+    public void availableViewpointsChanged(VRMLViewpointNodeType[] viewpoints) {
+        try {
+            a.availableViewpointsChanged(viewpoints);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(VP_CHANGE_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.availableViewpointsChanged(viewpoints);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(VP_CHANGE_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+
+    /**
+     * Notification that the selected viewpoint has been changed to this
+     * new instance. There are many different reasons this could happen -
+     * new node bound, world changed or even active navigation layer has
+     * changed and this is the default in that new layer.
+     * <p>
+     *
+     * If the file contains no viewpoints or the default viewpoint is
+     * bound (due to unbinding all real viewpoints on the stack) then this
+     * will be called with a null parameter.
+     * <p>
+     *
+     * It is guaranteed that this will always contain something from the
+     * currently active viewpoint list. If all change, that callback will be
+     * called before this one, to ensure consistency.
+     *
+     * @param vp The viewpoint instance that is now selected or null
+     */
+    @Override
+    public void selectedViewpointChanged(VRMLViewpointNodeType vp) {
+        try {
+            a.selectedViewpointChanged(vp);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(VP_SELECT_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.selectedViewpointChanged(vp);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(VP_SELECT_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+
+    /**
+     * Notification that this viewpoint has been appended to the list of
+     * available viewpoints.
+     *
+     * @param vp The viewpoint instance that was added
+     */
+    @Override
+    public void viewpointAdded(VRMLViewpointNodeType vp) {
+        try {
+            a.viewpointAdded(vp);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(VP_ADD_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.viewpointAdded(vp);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(VP_ADD_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+
+    /**
+     * Notification that this viewpoint has been removed from the list of
+     * available viewpoints.
+     *
+     * @param vp The viewpoint instance that was added
+     */
+    @Override
+    public void viewpointRemoved(VRMLViewpointNodeType vp) {
+        try {
+            a.viewpointRemoved(vp);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(VP_REMOVE_ERROR_MSG + a,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+
+        try {
+            b.viewpointRemoved(vp);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(VP_REMOVE_ERROR_MSG + b,
+                                          (Exception)th);
+            else {
+                System.err.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+
+    //----------------------------------------------------------
+    // Local Methods
+    //----------------------------------------------------------
+
+    /**
+     * Returns the resulting multicast listener from adding listener-a
+     * and listener-b together.
+     * If listener-a is null, it returns listener-b;
+     * If listener-b is null, it returns listener-a
+     * If neither are null, then it creates and returns
+     *     a new ViewpointStatusMulticaster instance which chains a with b.
+     * @param a event listener-a
+     * @param b event listener-b
+     */
+    private static ViewpointStatusListener addInternal(ViewpointStatusListener a,
+                                                     ViewpointStatusListener b) {
+        if(a == null)
+            return b;
+
+        if(b == null)
+            return a;
+
+        return new ViewpointStatusListenerMulticaster(a, b);
+    }
+
+    /**
+     * Returns the resulting multicast listener after removing the
+     * old listener from listener-l.
+     * If listener-l equals the old listener OR listener-l is null,
+     * returns null.
+     * Else if listener-l is an instance of ViewpointStatusMulticaster,
+     * then it removes the old listener from it.
+     * Else, returns listener l.
+     * @param l the listener being removed from
+     * @param oldl the listener being removed
+     */
+    private static ViewpointStatusListener removeInternal(ViewpointStatusListener l,
+                                                          ViewpointStatusListener oldl) {
+        if (l == oldl || l == null) {
+            return null;
+        } else if (l instanceof ViewpointStatusListenerMulticaster) {
+            return ((ViewpointStatusListenerMulticaster)l).remove(oldl);
+        } else {
+            return l;   // it's not here
+        }
+    }
+}
diff --git a/src/java/org/xj3d/core/loading/ContentLoadManager.java b/src/java/org/xj3d/core/loading/ContentLoadManager.java
index d585f3f56b73b3171ca2b23a00e39edf172176bd..c171f2366cb6507cc39c280d869fd0ce1e042512 100644
--- a/src/java/org/xj3d/core/loading/ContentLoadManager.java
+++ b/src/java/org/xj3d/core/loading/ContentLoadManager.java
@@ -24,12 +24,14 @@ import org.web3d.vrml.util.NodeArray;
 /**
  * An abstract definition of managers for loading files that are external to
  * the currently loading file eg Textures, inlines and protos.
+ * <p>
  *
  * The loader is given a scene and told to start loading the contents. During
  * this time items progress from pending to loading to loaded. The load manager
  * is cancelable so that a particular scene can be interrupted part way through
  * loading. The manager is designed to load multiple scenes in parallel or to
  * have parallel instances of this manager loading data.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/xj3d/core/loading/ContentLoader.java b/src/java/org/xj3d/core/loading/ContentLoader.java
index 47d2d5a9246ffe8088703754952048ffe098d9ba..73cfc18025b09b600d3f1952f35508d89e249abe 100644
--- a/src/java/org/xj3d/core/loading/ContentLoader.java
+++ b/src/java/org/xj3d/core/loading/ContentLoader.java
@@ -14,6 +14,8 @@ package org.xj3d.core.loading;
 
 // External imports
 import java.util.Map;
+
+// Local imports
 import org.j3d.util.DefaultErrorReporter;
 import org.j3d.util.ErrorReporter;
 
@@ -36,7 +38,7 @@ class ContentLoader implements Runnable {
 
     /** Message for an unrecognized message */
     private static final String UNKNOWN_ERROR_MSG =
-        "ContentLoader: Unknown error in content loading process";
+        "Unknown error in content loading process";
 
     /** The threading running this loader */
     private Thread th;
@@ -119,8 +121,6 @@ class ContentLoader implements Runnable {
             } catch(Exception e) {
                 // Any other exception
                 errorReporter.errorReport(UNKNOWN_ERROR_MSG, e);
-                System.err.println(e.getMessage());
-                System.err.println(e.getStackTrace());
                 inProgress.remove(currentRequest.url);
                 continue;
             }
diff --git a/src/java/org/xj3d/core/loading/LoadDetails.java b/src/java/org/xj3d/core/loading/LoadDetails.java
index f41eee4ca119d20a6848aca5dd37175b3fd349ba..35cc46858967ac65dd96898783c1b47d1e724fb2 100644
--- a/src/java/org/xj3d/core/loading/LoadDetails.java
+++ b/src/java/org/xj3d/core/loading/LoadDetails.java
@@ -20,6 +20,7 @@ package org.xj3d.core.loading;
 
 /**
  * A simple data holder class for information about a URL to load.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.3 $
diff --git a/src/java/org/xj3d/core/loading/ScriptLoadStatusListener.java b/src/java/org/xj3d/core/loading/ScriptLoadStatusListener.java
index 2f9f28f0ca6fdf7811ae2fe854cfe17f59373c18..a98798197bee81bae537ed0bcbc8d72a5a044635 100644
--- a/src/java/org/xj3d/core/loading/ScriptLoadStatusListener.java
+++ b/src/java/org/xj3d/core/loading/ScriptLoadStatusListener.java
@@ -21,12 +21,14 @@ import org.web3d.vrml.nodes.VRMLScriptNodeType;
 /**
  * An internal listener to allow the ScriptLoader and ScriptManager to
  * communicate load state for the scripts.
+ * <p>
  *
  * The listener interface is used rather than a common array because the
  * loader is typically operating on a separate thread and having a queue
  * between the two will have multi-threaded issues. Using this listener
  * reduces the multi-threaded issues to just one class and thus making it
  * easy to manage.
+ * <p>
  *
  *
  * @author Justin Couch
diff --git a/src/java/org/xj3d/impl/core/eventmodel/DefaultFrameStateManager.java b/src/java/org/xj3d/impl/core/eventmodel/DefaultFrameStateManager.java
index 369fa3e79e8ccb789960c8ad76da3adee0385caf..d9a9d48c7af0c7d8b0d7f703b9cdacd535a4bfad 100644
--- a/src/java/org/xj3d/impl/core/eventmodel/DefaultFrameStateManager.java
+++ b/src/java/org/xj3d/impl/core/eventmodel/DefaultFrameStateManager.java
@@ -32,8 +32,9 @@ import org.web3d.vrml.util.NodeArray;
 import org.web3d.vrml.util.NodeTemplateArray;
 
 /**
- * A generalized implementation of the frame state manager interface that can
+ * A generalised implementation of the frame state manager interface that can
  * be used with any renderer.
+ * <p>
  *
  * @author Justin Couch, Alan Hudson
  * @version $Revision: 1.5 $
diff --git a/src/java/org/xj3d/impl/core/eventmodel/DefaultHumanoidManager.java b/src/java/org/xj3d/impl/core/eventmodel/DefaultHumanoidManager.java
index bbe7ce78912ce0bdc5e76b545378a319f85d993a..b5cffe1c9f1a86057558e875ea893aec4c3bbb8d 100644
--- a/src/java/org/xj3d/impl/core/eventmodel/DefaultHumanoidManager.java
+++ b/src/java/org/xj3d/impl/core/eventmodel/DefaultHumanoidManager.java
@@ -97,11 +97,23 @@ public class DefaultHumanoidManager implements NodeManager {
             errorReporter = DefaultErrorReporter.getDefaultReporter();
     }
 
+    /**
+     * Get the list of component names that this manager would normally manage.
+     * The component definition is asssumed to be the same across all versions
+     * of the specifications that the browser supports. The level of the
+     * component is assumed to be the lowest level supported (ie if the given
+     * level fails, then levels above this cannot be supported, but those below
+     * can still be).
+     * <p>
+     * Mostly this is used for when initialization fails and we wish to disable
+     * support for loading of nodes in that component.
+     *
+     * @return The collection of components that this manager supports
+     */
     @Override
     public ComponentInfo[] getSupportedComponents() {
         return new ComponentInfo[] {
-            new ComponentInfo("H-Anim", 1),
-            new ComponentInfo("HAnim", 1) // HAnim in X3Dv4, backwards compatible
+            new ComponentInfo("H-Anim", 1) // TODO HAnim in X3Dv4
         };
     }
 
@@ -178,11 +190,26 @@ public class DefaultHumanoidManager implements NodeManager {
         humanoids.remove(node);
     }
 
+    /**
+     * Run the pre-event modelling for this frame now. This is a blocking call
+     * and does not return until the event model is complete for this frame.
+     * The time should be system clock time, not VRML time.
+     *
+     * @param time The timestamp of this frame to evaluate
+     */
     @Override
     public void executePreEventModel(long time) {
         // do nothing
     }
 
+
+    /**
+     * Run the post-event modelling for this frame now. This is a blocking call
+     * and does not return until the event model is complete for this frame.
+     * The time should be system clock time, not VRML time.
+     *
+     * @param time The timestamp of this frame to evaluate
+     */
     @Override
     public void executePostEventModel(long time) {
         int size = humanoids.size();
diff --git a/src/java/org/xj3d/impl/core/eventmodel/DefaultNavigationManager.java b/src/java/org/xj3d/impl/core/eventmodel/DefaultNavigationManager.java
index 8809469207a3cf3709fa452aae4b2ebfb657c901..924235c678de3515cd25a46df398b2c5bf7dca5d 100644
--- a/src/java/org/xj3d/impl/core/eventmodel/DefaultNavigationManager.java
+++ b/src/java/org/xj3d/impl/core/eventmodel/DefaultNavigationManager.java
@@ -1,334 +1,334 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2005 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.impl.core.eventmodel;
-
-// External imports
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-// Local imports
-import org.web3d.browser.BrowserCore;
-import org.web3d.browser.NavigationStateListener;
-
-import org.j3d.util.DefaultErrorReporter;
-import org.j3d.util.ErrorReporter;
-import org.web3d.vrml.nodes.VRMLNodeType;
-import org.web3d.vrml.nodes.VRMLNavigationInfoNodeType;
-
-import org.xj3d.core.eventmodel.NavigationManager;
-import org.xj3d.core.eventmodel.NavigationStatusListener;
-import org.xj3d.core.eventmodel.NavigationStatusListenerMulticaster;
-
-/**
- * An abstract representation of a class that would be responsible for
- * performing Viewpoint management.
- * <p>
- *
- * This interface represents a further abstracted view of viewpoint management
- * handling beyond the {@link org.web3d.browser.BrowserCore}. This gives you
- * all the handling that is normally seen at a user interface level. You should
- * use one or the other, but not both as implementations of this class will
- * also interact with BrowserCore.
- * <p>
- *
- * <b>Note:</b> This code does not current handle the navigation info nodes. It
- * only deals with the string type list as that is all we currently have
- * available from the browser internals.
- *
- * @author Justin Couch
- * @version $Revision: 1.3 $
- */
-public class DefaultNavigationManager
-    implements NavigationManager, NavigationStateListener {
-
-    /** Error message when the user code barfs */
-    private static final String REMOVE_ERROR_MSG =
-        "Error sending viewpoint remove message: ";
-
-    /** Error message when the user code barfs */
-    private static final String NAV_SELECT_ERROR_MSG =
-        "Error sending navigation info selection message: ";
-
-    /** Error message when the user code barfs */
-    private static final String NAV_CHANGE_ERROR_MSG =
-        "Error sending navigation info change message: ";
-
-    /** Error message when the user code barfs */
-    private static final String NAV_STATE_ERROR_MSG =
-        "Error sending navigation state change message: ";
-
-    /** Error message when the user code barfs */
-    private static final String NAV_LIST_ERROR_MSG =
-        "Error sending navigation type listing message: ";
-
-    /** Default error message when sending the error messsage fails */
-    private static final String DEFAULT_ERR_MSG =
-        "Unknown error sending navigation state change event: ";
-
-    /** Message when the user sets an invalid navigation type index */
-    private static final String ACTIVE_IDX_SIZE_MSG =
-        "The navigation type index selected is out of range for " +
-        "the currently available types in the system: ";
-
-    /** Reporter instance for handing out errors */
-    private ErrorReporter errorReporter;
-
-    /** The listener(s) for navigation status events */
-    private NavigationStatusListener listeners;
-
-    /** List of current navigation types */
-    private List<String> navigationTypes;
-
-    /** The active index in navigationTypes */
-    private int activeNavigationType;
-
-    /** The current active navigation info node */
-    private VRMLNavigationInfoNodeType activeNavInfo;
-
-    /** The list of active navinfo nodes */
-    private List<VRMLNavigationInfoNodeType> activeNavInfoList;
-
-    /** The browser core reference for VP management */
-    private BrowserCore browserCore;
-
-    /**
-     * Create a new instance of this manager that works with the given
-     * browser core representation.
-     *
-     * @param core The browser core to work with
-     */
-    public DefaultNavigationManager(BrowserCore core) {
-        navigationTypes = new ArrayList<>();
-        activeNavInfoList = new ArrayList<>();
-        activeNavigationType = -1;
-
-        errorReporter = DefaultErrorReporter.getDefaultReporter();
-        browserCore = core;
-        browserCore.addNavigationStateListener(this);
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by NavigationManager
-    //----------------------------------------------------------
-
-    /**
-     * Set the current navigation info.
-     *
-     * @param nav The new current navigation info.
-     */
-    @Override
-    public void setNavigationInfo(VRMLNavigationInfoNodeType nav) {
-        activeNavInfo = nav;
-    }
-
-    /**
-     * Get the current active navigation info node. If there isn't one
-     * (eg there is no world loaded at all). Active is defined for the
-     * current active navigation layer.
-     *
-     * @return The current active navigation info node or null
-     */
-    @Override
-    public VRMLNavigationInfoNodeType getNavigationInfo() {
-        return activeNavInfo;
-    }
-
-    /**
-     * Get the list of active navigation modes for the current active
-     * navigation layer. This is a list of all the available options, not
-     * the single type that is currently being used right now. To find
-     * out which one of these modes is active, use
-     * {@link #getActiveNavgiationIndex()}. This is a read-only list.
-     *
-     * @return The list of all the available types
-     */
-    @Override
-    public List<String> getActiveNavigationTypes() {
-        return Collections.unmodifiableList(navigationTypes);
-    }
-
-    /**
-     * Set the active navigation index of the current list. If the index is -1
-     * then all navigation is disabled. An index of out bounds for the current
-     * list throws an exception.
-     *
-     * @param idx The index to set as the active type
-     * @throws IllegalArgumentException The index is greater than the
-     *    available list size
-     */
-    @Override
-    public void setActiveNavigationIndex(int idx)
-        throws IllegalArgumentException {
-
-        if(idx >= navigationTypes.size() || idx < -1)
-            throw new IllegalArgumentException(ACTIVE_IDX_SIZE_MSG + idx);
-
-        activeNavigationType = idx;
-
-        sendNavTypeIndex(idx);
-    }
-
-    /**
-     * Fetch the index into the navigation type array of the actual type
-     * of navigation being used by the system. If no type is active or the
-     * type list includes "NONE" then this will return -1.
-     *
-     * @return The index of the active type
-     */
-    @Override
-    public int getActiveNavgiationIndex() {
-        return activeNavigationType;
-    }
-
-    /**
-     * Force clearing all currently managed nodes from this manager now. This
-     * is used to indicate that a new world is about to be loaded and
-     * everything should be cleaned out now.
-     */
-    @Override
-    public void clear() {
-    }
-
-    /**
-     * Shutdown the node manager now. If this is using any external resources
-     * it should remove those now as the entire application is about to die
-     */
-    @Override
-    public void shutdown() {
-        browserCore.removeNavigationStateListener(this);
-    }
-
-    /**
-     * Register an error reporter with the engine so that any errors generated
-     * by the loading of script code can be reported in a nice, pretty fashion.
-     * Setting a value of null will clear the currently set reporter. If one
-     * is already set, the new value replaces the old.
-     *
-     * @param reporter The instance to use or null
-     */
-    @Override
-    public void setErrorReporter(ErrorReporter reporter) {
-        errorReporter = reporter;
-
-        // Reset the default only if we are not shutting down the system.
-        if(reporter == null)
-            errorReporter = DefaultErrorReporter.getDefaultReporter();
-    }
-
-    /**
-     * Gets the viewpoints for the currently active layer.
-     *
-     * @return A list of the viewpoint nodes
-     */
-    @Override
-    public List<VRMLNavigationInfoNodeType> getActiveNavInfos() {
-        return Collections.unmodifiableList(activeNavInfoList);
-    }
-
-    /**
-     * Add a listener for viewpoint status messages. Adding the same listener
-     * instance more than once will be silently ignored. Null values are
-     * ignored.
-     *
-     * @param l The listener instance to add
-     */
-    @Override
-    public void addNavigationListener(NavigationStatusListener l) {
-        listeners = NavigationStatusListenerMulticaster.add(listeners, l);
-    }
-
-    /**
-     * Remove a listener for viewpoint status messages. If this listener is
-     * not currently registered, the request will be silently ignored.
-     *
-     * @param l The listener instance to remove
-     */
-    @Override
-    public void removeNavigationListener(NavigationStatusListener l) {
-        listeners = NavigationStatusListenerMulticaster.remove(listeners, l);
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by NavigationStateListener
-    //----------------------------------------------------------
-
-    /**
-     * Notification that the navigation state has changed to the new state.
-     *
-     * @param idx The new state expressed as an index into the current navModes list.
-     */
-    @Override
-    public void navigationStateChanged(int idx) {
-        activeNavigationType = idx;
-
-        sendNavTypeIndex(idx);
-    }
-
-    /**
-     * Notification that the list of valid navigation modes has changed.
-     *
-     * @param modes The new modes
-     * @param numTypes The number of elements in the list
-     */
-    @Override
-    public void navigationListChanged(String[] modes, int numTypes) {
-        navigationTypes.clear();
-
-        for(int i = 0; i < numTypes; i++)
-            navigationTypes.add(modes[i]);
-
-        // Send it on down the pipe.
-        if(listeners != null) {
-            List<String> mode_list =
-                Collections.unmodifiableList(navigationTypes);
-
-            try {
-                listeners.navigationListChanged(mode_list);
-            } catch(Throwable th) {
-                if(th instanceof Exception)
-                    errorReporter.errorReport(NAV_LIST_ERROR_MSG + listeners,
-                                                  (Exception)th);
-                else {
-                    System.out.println(DEFAULT_ERR_MSG + th);
-                    th.printStackTrace(System.err);
-                }
-            }
-        }
-    }
-
-    //----------------------------------------------------------
-    // Local Methods
-    //----------------------------------------------------------
-
-    /**
-     * Send out to the listeners the active navigation type list.
-     */
-    private void sendNavTypeIndex(int idx) {
-        if(listeners == null)
-            return;
-
-        try {
-            listeners.navigationStateChanged(idx);
-        } catch(Throwable th) {
-            if(th instanceof Exception)
-                errorReporter.errorReport(NAV_STATE_ERROR_MSG + listeners,
-                                          (Exception)th);
-            else {
-                System.out.println(DEFAULT_ERR_MSG + th);
-                th.printStackTrace(System.err);
-            }
-        }
-    }
-}
-
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2005 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.impl.core.eventmodel;
+
+// External imports
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+// Local imports
+import org.web3d.browser.BrowserCore;
+import org.web3d.browser.NavigationStateListener;
+
+import org.j3d.util.DefaultErrorReporter;
+import org.j3d.util.ErrorReporter;
+import org.web3d.vrml.nodes.VRMLNodeType;
+import org.web3d.vrml.nodes.VRMLNavigationInfoNodeType;
+
+import org.xj3d.core.eventmodel.NavigationManager;
+import org.xj3d.core.eventmodel.NavigationStatusListener;
+import org.xj3d.core.eventmodel.NavigationStatusListenerMulticaster;
+
+/**
+ * An abstract representation of a class that would be responsible for
+ * performing Viewpoint management.
+ * <p>
+ *
+ * This interface represents a further abstracted view of viewpoint management
+ * handling beyond the {@link org.web3d.browser.BrowserCore}. This gives you
+ * all the handling that is normally seen at a user interface level. You should
+ * use one or the other, but not both as implementations of this class will
+ * also interact with BrowserCore.
+ * <p>
+ *
+ * <b>Note:</b> This code does not current handle the navigation info nodes. It
+ * only deals with the string type list as that is all we currently have
+ * available from the browser internals.
+ *
+ * @author Justin Couch
+ * @version $Revision: 1.3 $
+ */
+public class DefaultNavigationManager
+    implements NavigationManager, NavigationStateListener {
+
+    /** Error message when the user code barfs */
+    private static final String REMOVE_ERROR_MSG =
+        "Error sending viewpoint remove message: ";
+
+    /** Error message when the user code barfs */
+    private static final String NAV_SELECT_ERROR_MSG =
+        "Error sending navigation info selection message: ";
+
+    /** Error message when the user code barfs */
+    private static final String NAV_CHANGE_ERROR_MSG =
+        "Error sending navigation info change message: ";
+
+    /** Error message when the user code barfs */
+    private static final String NAV_STATE_ERROR_MSG =
+        "Error sending navigation state change message: ";
+
+    /** Error message when the user code barfs */
+    private static final String NAV_LIST_ERROR_MSG =
+        "Error sending navigation type listing message: ";
+
+    /** Default error message when sending the error messsage fails */
+    private static final String DEFAULT_ERR_MSG =
+        "Unknown error sending navigation state change event: ";
+
+    /** Message when the user sets an invalid navigation type index */
+    private static final String ACTIVE_IDX_SIZE_MSG =
+        "The navigation type index selected is out of range for " +
+        "the currently available types in the system: ";
+
+    /** Reporter instance for handing out errors */
+    private ErrorReporter errorReporter;
+
+    /** The listener(s) for navigation status events */
+    private NavigationStatusListener listeners;
+
+    /** List of current navigation types */
+    private List<String> navigationTypes;
+
+    /** The active index in navigationTypes */
+    private int activeNavigationType;
+
+    /** The current active navigation info node */
+    private VRMLNavigationInfoNodeType activeNavInfo;
+
+    /** The list of active navinfo nodes */
+    private List<VRMLNavigationInfoNodeType> activeNavInfoList;
+
+    /** The browser core reference for VP management */
+    private BrowserCore browserCore;
+
+    /**
+     * Create a new instance of this manager that works with the given
+     * browser core representation.
+     *
+     * @param core The browser core to work with
+     */
+    public DefaultNavigationManager(BrowserCore core) {
+        navigationTypes = new ArrayList<>();
+        activeNavInfoList = new ArrayList<>();
+        activeNavigationType = -1;
+
+        errorReporter = DefaultErrorReporter.getDefaultReporter();
+        browserCore = core;
+        browserCore.addNavigationStateListener(this);
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by NavigationManager
+    //----------------------------------------------------------
+
+    /**
+     * Set the current navigation info.
+     *
+     * @param nav The new current navigation info.
+     */
+    @Override
+    public void setNavigationInfo(VRMLNavigationInfoNodeType nav) {
+        activeNavInfo = nav;
+    }
+
+    /**
+     * Get the current active navigation info node. If there isn't one
+     * (eg there is no world loaded at all). Active is defined for the
+     * current active navigation layer.
+     *
+     * @return The current active navigation info node or null
+     */
+    @Override
+    public VRMLNavigationInfoNodeType getNavigationInfo() {
+        return activeNavInfo;
+    }
+
+    /**
+     * Get the list of active navigation modes for the current active
+     * navigation layer. This is a list of all the available options, not
+     * the single type that is currently being used right now. To find
+     * out which one of these modes is active, use
+     * {@link #getActiveNavgiationIndex()}. This is a read-only list.
+     *
+     * @return The list of all the available types
+     */
+    @Override
+    public List<String> getActiveNavigationTypes() {
+        return Collections.unmodifiableList(navigationTypes);
+    }
+
+    /**
+     * Set the active navigation index of the current list. If the index is -1
+     * then all navigation is disabled. An index of out bounds for the current
+     * list throws an exception.
+     *
+     * @param idx The index to set as the active type
+     * @throws IllegalArgumentException The index is greater than the
+     *    available list size
+     */
+    @Override
+    public void setActiveNavigationIndex(int idx)
+        throws IllegalArgumentException {
+
+        if(idx >= navigationTypes.size() || idx < -1)
+            throw new IllegalArgumentException(ACTIVE_IDX_SIZE_MSG + idx);
+
+        activeNavigationType = idx;
+
+        sendNavTypeIndex(idx);
+    }
+
+    /**
+     * Fetch the index into the navigation type array of the actual type
+     * of navigation being used by the system. If no type is active or the
+     * type list includes "NONE" then this will return -1.
+     *
+     * @return The index of the active type
+     */
+    @Override
+    public int getActiveNavgiationIndex() {
+        return activeNavigationType;
+    }
+
+    /**
+     * Force clearing all currently managed nodes from this manager now. This
+     * is used to indicate that a new world is about to be loaded and
+     * everything should be cleaned out now.
+     */
+    @Override
+    public void clear() {
+    }
+
+    /**
+     * Shutdown the node manager now. If this is using any external resources
+     * it should remove those now as the entire application is about to die
+     */
+    @Override
+    public void shutdown() {
+        browserCore.removeNavigationStateListener(this);
+    }
+
+    /**
+     * Register an error reporter with the engine so that any errors generated
+     * by the loading of script code can be reported in a nice, pretty fashion.
+     * Setting a value of null will clear the currently set reporter. If one
+     * is already set, the new value replaces the old.
+     *
+     * @param reporter The instance to use or null
+     */
+    @Override
+    public void setErrorReporter(ErrorReporter reporter) {
+        errorReporter = reporter;
+
+        // Reset the default only if we are not shutting down the system.
+        if(reporter == null)
+            errorReporter = DefaultErrorReporter.getDefaultReporter();
+    }
+
+    /**
+     * Gets the viewpoints for the currently active layer.
+     *
+     * @return A list of the viewpoint nodes
+     */
+    @Override
+    public List<VRMLNavigationInfoNodeType> getActiveNavInfos() {
+        return Collections.unmodifiableList(activeNavInfoList);
+    }
+
+    /**
+     * Add a listener for viewpoint status messages. Adding the same listener
+     * instance more than once will be silently ignored. Null values are
+     * ignored.
+     *
+     * @param l The listener instance to add
+     */
+    @Override
+    public void addNavigationListener(NavigationStatusListener l) {
+        listeners = NavigationStatusListenerMulticaster.add(listeners, l);
+    }
+
+    /**
+     * Remove a listener for viewpoint status messages. If this listener is
+     * not currently registered, the request will be silently ignored.
+     *
+     * @param l The listener instance to remove
+     */
+    @Override
+    public void removeNavigationListener(NavigationStatusListener l) {
+        listeners = NavigationStatusListenerMulticaster.remove(listeners, l);
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by NavigationStateListener
+    //----------------------------------------------------------
+
+    /**
+     * Notification that the navigation state has changed to the new state.
+     *
+     * @param idx The new state expressed as an index into the current navModes list.
+     */
+    @Override
+    public void navigationStateChanged(int idx) {
+        activeNavigationType = idx;
+
+        sendNavTypeIndex(idx);
+    }
+
+    /**
+     * Notification that the list of valid navigation modes has changed.
+     *
+     * @param modes The new modes
+     * @param numTypes The number of elements in the list
+     */
+    @Override
+    public void navigationListChanged(String[] modes, int numTypes) {
+        navigationTypes.clear();
+
+        for(int i = 0; i < numTypes; i++)
+            navigationTypes.add(modes[i]);
+
+        // Send it on down the pipe.
+        if(listeners != null) {
+            List<String> mode_list =
+                Collections.unmodifiableList(navigationTypes);
+
+            try {
+                listeners.navigationListChanged(mode_list);
+            } catch(Throwable th) {
+                if(th instanceof Exception)
+                    errorReporter.errorReport(NAV_LIST_ERROR_MSG + listeners,
+                                                  (Exception)th);
+                else {
+                    System.out.println(DEFAULT_ERR_MSG + th);
+                    th.printStackTrace(System.err);
+                }
+            }
+        }
+    }
+
+    //----------------------------------------------------------
+    // Local Methods
+    //----------------------------------------------------------
+
+    /**
+     * Send out to the listeners the active navigation type list.
+     */
+    private void sendNavTypeIndex(int idx) {
+        if(listeners == null)
+            return;
+
+        try {
+            listeners.navigationStateChanged(idx);
+        } catch(Throwable th) {
+            if(th instanceof Exception)
+                errorReporter.errorReport(NAV_STATE_ERROR_MSG + listeners,
+                                          (Exception)th);
+            else {
+                System.out.println(DEFAULT_ERR_MSG + th);
+                th.printStackTrace(System.err);
+            }
+        }
+    }
+}
+
diff --git a/src/java/org/xj3d/impl/core/eventmodel/DefaultNetworkManager.java b/src/java/org/xj3d/impl/core/eventmodel/DefaultNetworkManager.java
index 5dfa35fb626927dbffa1acaaa7cb370ed8fc7460..a5f7030b260983380d42f23ca297606b8c22733b 100644
--- a/src/java/org/xj3d/impl/core/eventmodel/DefaultNetworkManager.java
+++ b/src/java/org/xj3d/impl/core/eventmodel/DefaultNetworkManager.java
@@ -29,9 +29,11 @@ import org.xj3d.core.eventmodel.NetworkProtocolHandler;
 
 /**
  * The manager of network interactions.
+ * <p>
  *
  * Does not perform networking itself, but manages the different
  * protocol handlers.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.3 $
diff --git a/src/java/org/xj3d/impl/core/eventmodel/DefaultScriptManager.java b/src/java/org/xj3d/impl/core/eventmodel/DefaultScriptManager.java
index f9406e8c818cccfd0bbf7b53f9581554f54e54db..2f8a0d9b2707cce134b77b7b125501ceda182c11 100644
--- a/src/java/org/xj3d/impl/core/eventmodel/DefaultScriptManager.java
+++ b/src/java/org/xj3d/impl/core/eventmodel/DefaultScriptManager.java
@@ -31,6 +31,7 @@ import org.xj3d.core.loading.ScriptLoadStatusListener;
 /**
  * Default implementation of the ScriptManager interface that implements VRML97
  * and X3D semantics.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/xj3d/impl/core/eventmodel/OriginManagerFactory.java b/src/java/org/xj3d/impl/core/eventmodel/OriginManagerFactory.java
index e9e411751b056ecabd05892174bd641643158c92..1ab4c94357b96c646a95d2f7fc653f5f707a97e9 100644
--- a/src/java/org/xj3d/impl/core/eventmodel/OriginManagerFactory.java
+++ b/src/java/org/xj3d/impl/core/eventmodel/OriginManagerFactory.java
@@ -1,84 +1,84 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2009
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.impl.core.eventmodel;
-
-// External imports
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-// Local imports
-import org.web3d.vrml.nodes.FrameStateManager;
-import org.xj3d.core.eventmodel.OriginManager;
-
-/**
- * Factory class for obtaining an OriginManager instance for a browser.
- * The OriginManager's are unique per browser instance and are identified
- * by the browser's FrameStateManager.
- *
- * @author Rex Melton
- * @version $Revision: 1.5 $
- */
-public class OriginManagerFactory {
-
-    /** Store of OriginManagers, keyed by FrameStateManager */
-    private static Map<FrameStateManager, OriginManager> map;
-
-    /** Protected Constructor */
-    private OriginManagerFactory() {
-    }
-
-    /**
-     * Return the OriginManager for the argument FrameStateManager.
-     * If none exists, create one.
-     *
-     * @param fsm The browser's FrameStateManager.
-     * @return An OriginManager
-     */
-    public static OriginManager getInstance(FrameStateManager fsm) {
-        OriginManager om = null;
-
-        if (fsm == null) {
-            if (map.size() > 0) {
-                // alan: Proto's nodes have no frame state manager till they
-                // are instanced into a real renderer.  Just return something
-                // sensable as it won't get used.
-                Iterator<OriginManager> i = map.values().iterator();
-                om = i.next();
-            }
-        }
-
-        if (map == null) {
-            map = new HashMap<>();
-        } else {
-            om = map.get(fsm);
-        }
-
-        if (om == null) {
-            om = new DefaultOriginManager();
-            map.put(fsm, om);
-        }
-        return om;
-    }
-
-    /**
-     * Delete the OriginManager for the argument FrameStateManager.
-     *
-     * @param fsm The browser's FrameStateManager.
-     */
-    public static void removeInstance(FrameStateManager fsm) {
-        if (map != null) {
-            map.remove(fsm);
-        }
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2009
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.impl.core.eventmodel;
+
+// External imports
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+// Local imports
+import org.web3d.vrml.nodes.FrameStateManager;
+import org.xj3d.core.eventmodel.OriginManager;
+
+/**
+ * Factory class for obtaining an OriginManager instance for a browser.
+ * The OriginManager's are unique per browser instance and are identified
+ * by the browser's FrameStateManager.
+ *
+ * @author Rex Melton
+ * @version $Revision: 1.5 $
+ */
+public class OriginManagerFactory {
+
+    /** Store of OriginManagers, keyed by FrameStateManager */
+    private static Map<FrameStateManager, OriginManager> map;
+
+    /** Protected Constructor */
+    private OriginManagerFactory() {
+    }
+
+    /**
+     * Return the OriginManager for the argument FrameStateManager.
+     * If none exists, create one.
+     *
+     * @param fsm The browser's FrameStateManager.
+     * @return An OriginManager
+     */
+    public static OriginManager getInstance(FrameStateManager fsm) {
+        OriginManager om = null;
+
+        if (fsm == null) {
+            if (map.size() > 0) {
+                // alan: Proto's nodes have no frame state manager till they
+                // are instanced into a real renderer.  Just return something
+                // sensable as it won't get used.
+                Iterator<OriginManager> i = map.values().iterator();
+                om = i.next();
+            }
+        }
+
+        if (map == null) {
+            map = new HashMap<>();
+        } else {
+            om = map.get(fsm);
+        }
+
+        if (om == null) {
+            om = new DefaultOriginManager();
+            map.put(fsm, om);
+        }
+        return om;
+    }
+
+    /**
+     * Delete the OriginManager for the argument FrameStateManager.
+     *
+     * @param fsm The browser's FrameStateManager.
+     */
+    public static void removeInstance(FrameStateManager fsm) {
+        if (map != null) {
+            map.remove(fsm);
+        }
+    }
+}
diff --git a/src/java/org/xj3d/impl/core/loading/ContentLoadHandler.java b/src/java/org/xj3d/impl/core/loading/ContentLoadHandler.java
index cc6f3ef981954cf0e079251263d30c5c05861665..7270fcdfa4ba6355498f804e42f4fb831fc45bf9 100644
--- a/src/java/org/xj3d/impl/core/loading/ContentLoadHandler.java
+++ b/src/java/org/xj3d/impl/core/loading/ContentLoadHandler.java
@@ -14,15 +14,20 @@ package org.xj3d.impl.core.loading;
 
 // External imports
 import java.io.*;
-import java.net.MalformedURLException;
+
 import java.util.HashSet;
 import java.util.Set;
 import java.util.Vector;
+
 import org.ietf.uri.*;
+import org.ietf.uri.URIUtils;
+
+// Local imports
 import org.j3d.util.ErrorReporter;
 import org.web3d.vrml.lang.BasicScene;
 import org.web3d.vrml.lang.InvalidFieldException;
 import org.web3d.vrml.nodes.*;
+
 import org.xj3d.core.loading.CacheDetails;
 import org.xj3d.core.loading.FileCache;
 import org.xj3d.core.loading.LoadDetails;
@@ -48,24 +53,24 @@ class ContentLoadHandler extends BaseLoadHandler
 
     /** Message for an unrecognized message */
     private static final String UNKNOWN_ERROR_MSG =
-        "ContentLoadHandler: Unknown error in content loading process";
+        "Unknown error in content loading process";
 
     /** Message for errors in setContent() */
     private static final String CONTENT_ERROR_MSG =
-        "ContentLoadHandler: Error setting external content:";
+        "Error setting external content:";
 
     /** Message for errors in setContent() */
     private static final String CONTENT_WARNING_MSG =
-        "ContentLoadHandler: Problem setting external content:";
+        "Problem setting external content:";
 
     /** Message for errors attempting to write to an invalid field index */
     private static final String INVALID_FIELD_MSG =
-        "ContentLoadHandler: Internal error caused by attempting to send content to an invalid " +
+        "Internal error caused by attempting to send content to an invalid " +
         "field index: ";
 
     /** Message for no valid URLS in the load process */
     private static final String NO_URLS_MSG =
-        "ContentLoadHandler: Cannot resolve any URLS for URL: ";
+        "Cannot resolve any URLS for URL: ";
 
     /** The cache representation that this loader is using */
     private FileCache fileCache;
@@ -98,13 +103,13 @@ class ContentLoadHandler extends BaseLoadHandler
     /**
      * Process this load request now.
      *
-     * @param errorReporter The errorReporter to send all messages to
+     * @param reporter The errorReporter to send all messages to
      * @param url The list of URLs to load
      * @param loadList The list of LoadDetails objects to sent the fulfilled
      *    requests to
      */
     @Override
-    public void processLoadRequest(ErrorReporter errorReporter,
+    public void processLoadRequest(ErrorReporter reporter,
                                    String[] url,
                                    Vector<LoadDetails> loadList) {
 
@@ -165,28 +170,6 @@ class ContentLoadHandler extends BaseLoadHandler
             if((index = file_url.lastIndexOf('#')) != -1) {
                 file_url = file_url.substring(0, index);
             }
-            
-            try {
-
-                // try a file first
-                File f = new File(file_url); // TODO Xj3D not changing to local directory of file being loaded
-                if (f.exists()) {
-                    if (f.isDirectory()) {
-                        errorReporter.errorReport("File is a directory", null);
-                        return;
-                    } else {
-                        file_url = f.toURI().toURL().toExternalForm(); // = url; TODO avoid munging? 
-                    }
-                } else {
-                    
-                    // Try a URL
-                    URL url_obj = new URL(file_url);
-                    file_url = url_obj.toExternalForm();
-                }
-            } catch (MalformedURLException e) {
-                System.err.println("exception " + e.getMessage() + "\n");
-                e.printStackTrace(System.err);
-            }
 
             // Check the cache first to see if we have something here
             CacheDetails cached_version =
@@ -229,6 +212,7 @@ class ContentLoadHandler extends BaseLoadHandler
                         String errorMsg;
 
                         if (e instanceof IllegalArgumentException) {
+
                             // from the setContent method
                             errorMsg = CONTENT_ERROR_MSG;
                         } else if (e instanceof InvalidFieldException) {
@@ -236,13 +220,11 @@ class ContentLoadHandler extends BaseLoadHandler
                         } else {
                             errorMsg = UNKNOWN_ERROR_MSG;
                         }
-                        errorReporter.errorReport(errorMsg, e);
-                        System.err.println(e.getMessage());
-                        System.err.println(e.getStackTrace());
+                        reporter.errorReport(errorMsg, e);
                     }
                 }
             } else {
-                content_found = loadExternal(errorReporter,
+                content_found = loadExternal(reporter,
                         url[i],
                         file_url,
                         loadList);
@@ -263,7 +245,7 @@ class ContentLoadHandler extends BaseLoadHandler
             }
 
             if(url != null && url.length > 0)
-                errorReporter.warningReport(NO_URLS_MSG + url[0], null);
+                reporter.warningReport(NO_URLS_MSG + url[0], null);
         }
 
         // Cleanup so we don't hold any references longer than we need to
@@ -444,11 +426,6 @@ class ContentLoadHandler extends BaseLoadHandler
             String msg = "Success finding file: " + source_urls[latestCheckedIndex].toExternalForm() + "\n";
             reporter.messageReport(msg);
         }
-        else if (!content_found && (latestCheckedIndex > -1))
-        {
-            String msg = "Failure finding file: " + source_urls[latestCheckedIndex].toExternalForm() + "\n";
-            reporter.messageReport(msg);
-        }
 
         return content_found;
     }
diff --git a/src/java/org/xj3d/impl/core/loading/DefaultLoadManager.java b/src/java/org/xj3d/impl/core/loading/DefaultLoadManager.java
index 7bc3a8e660f154fa87944c73914ecde0396c466e..f33d79e093008a20759a3199a93ee965f9148fb2 100644
--- a/src/java/org/xj3d/impl/core/loading/DefaultLoadManager.java
+++ b/src/java/org/xj3d/impl/core/loading/DefaultLoadManager.java
@@ -20,12 +20,14 @@ import org.xj3d.core.loading.FileCache;
 
 /**
  * A simplistic manager for loading files that does no caching.
+ * <p>
  *
  * The loader is given a scene and told to start loading the contents. During
  * this time items progress from pending to loading to loaded. The load manager
  * is cancelable so that a particular scene can be interrupted part way through
  * loading. The manager is designed to load multiple scenes in parallel or to
  * have parallel instances of this manager loading data.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.1 $
diff --git a/src/java/org/xj3d/impl/core/loading/DefaultWorldLoader.java b/src/java/org/xj3d/impl/core/loading/DefaultWorldLoader.java
index 0fcece32484c71715ad21970a8b3ef3232054a8a..bd300a5937b7395520355f7c0cf14313506df167 100644
--- a/src/java/org/xj3d/impl/core/loading/DefaultWorldLoader.java
+++ b/src/java/org/xj3d/impl/core/loading/DefaultWorldLoader.java
@@ -14,19 +14,22 @@ package org.xj3d.impl.core.loading;
 
 // External imports
 import java.io.IOException;
+
+// Local imports
+import org.web3d.browser.BrowserCore;
 import org.j3d.util.DefaultErrorReporter;
 import org.j3d.util.ErrorReporter;
 import org.j3d.util.IntHashMap;
 import org.j3d.util.ObjectArray;
-import org.web3d.browser.BrowserCore;
 import org.web3d.vrml.lang.VRMLException;
 import org.web3d.vrml.nodes.FrameStateManager;
-import org.web3d.vrml.nodes.VRMLNodeType;
 import org.web3d.vrml.nodes.VRMLScene;
+import org.web3d.vrml.nodes.VRMLNodeType;
 import org.web3d.vrml.parser.VRMLParserFactory;
+import org.web3d.vrml.sav.VRMLReader;
 import org.web3d.vrml.sav.InputSource;
 import org.web3d.vrml.sav.VRMLParseException;
-import org.web3d.vrml.sav.VRMLReader;
+
 import org.xj3d.core.loading.SceneBuilder;
 import org.xj3d.core.loading.SceneBuilderFactory;
 import org.xj3d.core.loading.WorldLoader;
@@ -156,14 +159,7 @@ class DefaultWorldLoader implements WorldLoader {
         bldr.releaseScene();
 
         VRMLNodeType rootSpace = (VRMLNodeType) scene.getRootNode();
-        if (rootSpace == null)
-        {
-            System.out.println("*** Xj3D DefaultWorldLoader rootSpace is null");
-        }
-        else
-        {
-            rootSpace.setFrameStateManager(stateManager);
-        }
+        rootSpace.setFrameStateManager(stateManager);
 
         // release back to the cache
         releaseBuilder(renderer, bldr);
diff --git a/src/java/org/xj3d/impl/core/loading/WorldLoadHandler.java b/src/java/org/xj3d/impl/core/loading/WorldLoadHandler.java
index 7e4ccef8596cdb9fc3025465338b5505d34d8a3f..f19454fe34dd0e3aefcca063f2a94fd22f1fbdf0 100644
--- a/src/java/org/xj3d/impl/core/loading/WorldLoadHandler.java
+++ b/src/java/org/xj3d/impl/core/loading/WorldLoadHandler.java
@@ -14,21 +14,28 @@ package org.xj3d.impl.core.loading;
 
 // External imports
 import java.io.IOException;
-import java.util.List;
 import java.util.Vector;
+
+//import org.ietf.uri.URL;
+import java.util.List;
 import org.ietf.uri.URL;
+
 import org.ietf.uri.event.ProgressEvent;
 import org.ietf.uri.event.ProgressListener;
-import org.j3d.util.ErrorReporter;
+
+// Local imports
+import org.xj3d.io.ReadProgressListener;
 import org.web3d.vrml.lang.*;
 import org.web3d.vrml.nodes.*;
+
+import org.j3d.util.ErrorReporter;
 import org.web3d.vrml.sav.InputSource;
 import org.web3d.vrml.sav.VRMLParseException;
+
 import org.xj3d.core.loading.FileCache;
 import org.xj3d.core.loading.LoadDetails;
 import org.xj3d.core.loading.LoadRequestHandler;
 import org.xj3d.core.loading.WorldLoader;
-import org.xj3d.io.ReadProgressListener;
 
 /**
  * Independent thread used to load a world from a list of URLs and then
@@ -148,7 +155,7 @@ public class WorldLoadHandler
                 InputSource is;
                 final_url = url;
                 try {
-                    if (url.startsWith("http://") || url.startsWith("https://"))
+                    if (url.contains("http") || url.contains("https"))
                         is = new InputSource(new URL(final_url));
                     else // file: or something else local?
                         is = new InputSource(final_url);
diff --git a/src/java/org/xj3d/io/ReadProgressListener.java b/src/java/org/xj3d/io/ReadProgressListener.java
index e26836f57e5828c46592f949a6b9e2b34676a903..026a271492297d69bcb818171aeaf5d6529a1172 100644
--- a/src/java/org/xj3d/io/ReadProgressListener.java
+++ b/src/java/org/xj3d/io/ReadProgressListener.java
@@ -1,40 +1,41 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2004 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.io;
-
-// External imports
-// None
-
-// Local imports
-// None
-
-/**
- * Listens for updates to read status on a stream.
- * @author Alan Hudson
- * @version $Revision: 1.2 $
- */
-public interface ReadProgressListener {
-
-    /**
-     * Notification of where the stream is at.  The value is
-     * dependent on the type, absolute or relative.
-     *
-     * @param value The new value
-     */
-    void progressUpdate(long value);
-
-    /**
-     * The stream has closed.
-     */
-    void streamClosed();
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2004 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.io;
+
+// External imports
+// None
+
+// Local imports
+// None
+
+/**
+ * Listens for updates to read status on a stream.
+ * <p>
+ * @author Alan Hudson
+ * @version $Revision: 1.2 $
+ */
+public interface ReadProgressListener {
+
+    /**
+     * Notification of where the stream is at.  The value is
+     * dependent on the type, absolute or relative.
+     *
+     * @param value The new value
+     */
+    void progressUpdate(long value);
+
+    /**
+     * The stream has closed.
+     */
+    void streamClosed();
+}
diff --git a/src/java/org/xj3d/io/ReportableInputStream.java b/src/java/org/xj3d/io/ReportableInputStream.java
index 56e99aa25b61d49f126560e0b165733f8f64d63e..59cc45e8e653f027a92b995389189613aa5ba798 100644
--- a/src/java/org/xj3d/io/ReportableInputStream.java
+++ b/src/java/org/xj3d/io/ReportableInputStream.java
@@ -1,167 +1,167 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2004 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.io;
-
-// External imports
-import java.io.InputStream;
-import java.io.FilterInputStream;
-import java.io.IOException;
-
-// Local imports
-// None
-
-/**
- * Listens for updates to read status on a stream.
- * 
- * @author Alan Hudson
- * @version $Revision: 1.3 $
- */
-public class ReportableInputStream extends FilterInputStream {
-
-    /** The number of bytes read since last update*/
-    private int bytesRead;
-
-    /** The total number of bytes read */
-    private int totalBytesRead;
-
-    /** Whether to report relative or absolute values */
-    private boolean relative;
-
-    /** The frequency(bytes) to report updates */
-    private int updateSize;
-
-    /** The Progress Listener */
-    private ReadProgressListener listener;
-
-    /**
-     * Constructor.
-     *
-     * @param relative Whether the update size is relative or absolute.
-     * @param updateSize The size in bytes to issue updates.
-     *        This will be approximately honored.
-     * @param listener The progress listener
-     * @param in The input source
-     */
-    public ReportableInputStream(boolean relative, int updateSize,
-        ReadProgressListener listener, InputStream in) {
-
-        super(in);
-
-        bytesRead = 0;
-        this.relative = relative;
-        this.updateSize = updateSize;
-        this.listener = listener;
-
-    }
-
-    @Override
-    public void close() throws IOException {
-        super.close();
-
-        if (listener != null)
-            listener.streamClosed();
-    }
-
-    @Override
-    public int read() throws IOException {
-        int i = super.read();
-
-        if(i != -1) {
-            bytesRead++;
-        }
-
-        if (bytesRead >= updateSize) {
-            totalBytesRead += bytesRead;
-
-            if (relative)
-                listener.progressUpdate(bytesRead);
-            else
-                listener.progressUpdate(totalBytesRead);
-
-            bytesRead = 0;
-        }
-
-        return i;
-    }
-
-    @Override
-    public int read(byte[] b) throws IOException {
-        int i = super.read(b,0,b.length);
-
-        if(i!=-1) {
-            bytesRead += i;
-        }
-
-        if (bytesRead >= updateSize) {
-            totalBytesRead += bytesRead;
-
-            if (relative)
-                listener.progressUpdate(bytesRead);
-            else
-                listener.progressUpdate(totalBytesRead);
-
-            bytesRead = 0;
-        }
-
-        return i;
-    }
-
-    @Override
-    public int read(byte[] b, int off, int len) throws IOException {
-        int i = super.read(b,off,len);
-
-        if(i!=-1) {
-            bytesRead += i;
-        }
-
-        if (bytesRead >= updateSize) {
-            totalBytesRead += bytesRead;
-
-            if (relative)
-                listener.progressUpdate(bytesRead);
-            else
-                listener.progressUpdate(totalBytesRead);
-
-            bytesRead = 0;
-        }
-
-        return i;
-    }
-
-    @Override
-    public void reset() throws IOException {
-        super.reset();
-        totalBytesRead = 0;
-        bytesRead = 0;
-    }
-
-    @Override
-    public long skip(long n) throws IOException {
-        long result = skip(n);
-
-        bytesRead += n;
-
-        if (bytesRead >= updateSize) {
-            totalBytesRead += bytesRead;
-
-            if (relative)
-                listener.progressUpdate(bytesRead);
-            else
-                listener.progressUpdate(totalBytesRead);
-
-            bytesRead = 0;
-        }
-
-        return result;
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2004 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.io;
+
+// External imports
+import java.io.InputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+
+// Local imports
+// None
+
+/**
+ * Listens for updates to read status on a stream.
+ * <p>
+ * @author Alan Hudson
+ * @version $Revision: 1.3 $
+ */
+public class ReportableInputStream extends FilterInputStream {
+
+    /** The number of bytes read since last update*/
+    private int bytesRead;
+
+    /** The total number of bytes read */
+    private int totalBytesRead;
+
+    /** Whether to report relative or absolute values */
+    private boolean relative;
+
+    /** The frequency(bytes) to report updates */
+    private int updateSize;
+
+    /** The Progress Listener */
+    private ReadProgressListener listener;
+
+    /**
+     * Constructor.
+     *
+     * @param relative Whether the update size is relative or absolute.
+     * @param updateSize The size in bytes to issue updates.
+     *        This will be approximately honored.
+     * @param listener The progress listener
+     * @param in The input source
+     */
+    public ReportableInputStream(boolean relative, int updateSize,
+        ReadProgressListener listener, InputStream in) {
+
+        super(in);
+
+        bytesRead = 0;
+        this.relative = relative;
+        this.updateSize = updateSize;
+        this.listener = listener;
+
+    }
+
+    @Override
+    public void close() throws IOException {
+        super.close();
+
+        if (listener != null)
+            listener.streamClosed();
+    }
+
+    @Override
+    public int read() throws IOException {
+        int i = super.read();
+
+        if(i != -1) {
+            bytesRead++;
+        }
+
+        if (bytesRead >= updateSize) {
+            totalBytesRead += bytesRead;
+
+            if (relative)
+                listener.progressUpdate(bytesRead);
+            else
+                listener.progressUpdate(totalBytesRead);
+
+            bytesRead = 0;
+        }
+
+        return i;
+    }
+
+    @Override
+    public int read(byte[] b) throws IOException {
+        int i = super.read(b,0,b.length);
+
+        if(i!=-1) {
+            bytesRead += i;
+        }
+
+        if (bytesRead >= updateSize) {
+            totalBytesRead += bytesRead;
+
+            if (relative)
+                listener.progressUpdate(bytesRead);
+            else
+                listener.progressUpdate(totalBytesRead);
+
+            bytesRead = 0;
+        }
+
+        return i;
+    }
+
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        int i = super.read(b,off,len);
+
+        if(i!=-1) {
+            bytesRead += i;
+        }
+
+        if (bytesRead >= updateSize) {
+            totalBytesRead += bytesRead;
+
+            if (relative)
+                listener.progressUpdate(bytesRead);
+            else
+                listener.progressUpdate(totalBytesRead);
+
+            bytesRead = 0;
+        }
+
+        return i;
+    }
+
+    @Override
+    public void reset() throws IOException {
+        super.reset();
+        totalBytesRead = 0;
+        bytesRead = 0;
+    }
+
+    @Override
+    public long skip(long n) throws IOException {
+        long result = skip(n);
+
+        bytesRead += n;
+
+        if (bytesRead >= updateSize) {
+            totalBytesRead += bytesRead;
+
+            if (relative)
+                listener.progressUpdate(bytesRead);
+            else
+                listener.progressUpdate(totalBytesRead);
+
+            bytesRead = 0;
+        }
+
+        return result;
+    }
+}
diff --git a/src/java/org/xj3d/io/ReportableInputStreamReader.java b/src/java/org/xj3d/io/ReportableInputStreamReader.java
index a24bc53ca7b092471a2e2d5182b699c9c878fe31..131b14677e95f4079357b1b6411478a5c31b464c 100644
--- a/src/java/org/xj3d/io/ReportableInputStreamReader.java
+++ b/src/java/org/xj3d/io/ReportableInputStreamReader.java
@@ -1,165 +1,165 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2004 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.io;
-
-// External imports
-import java.io.*;
-
-// Local imports
-// None
-
-/**
- * Listens for updates to read status on a stream.
- * 
- * @author Alan Hudson
- * @version $Revision: 1.3 $
- */
-public class ReportableInputStreamReader extends FilterReader {
-
-    /** The number of bytes read since last update*/
-    private int bytesRead;
-
-    /** The total number of bytes read */
-    private int totalBytesRead;
-
-    /** Whether to report relative or absolute values */
-    private boolean relative;
-
-    /** The frequency(bytes) to report updates */
-    private int updateSize;
-
-    /** The Progress Listener */
-    private ReadProgressListener listener;
-
-    /**
-     * Construct an instance of the reader that wraps a stream and has a listener
-     * already associated with it.
-     *
-     * @param relative Whether the update size is relative or absolute.
-     * @param updateSize The size in bytes to issue updates.
-     *        This will be approximately honored.
-     * @param listener The progress listener
-     * @param in The input source
-     */
-    public ReportableInputStreamReader(boolean relative, int updateSize,
-        ReadProgressListener listener, InputStream in) {
-
-        super(new InputStreamReader(in));
-
-        bytesRead = 0;
-        this.relative = relative;
-        this.updateSize = updateSize;
-        this.listener = listener;
-    }
-
-    @Override
-    public void close() throws IOException {
-        super.close();
-
-        if (listener != null)
-            listener.streamClosed();
-    }
-
-    @Override
-    public int read() throws IOException {
-        int i = super.read();
-
-        if(i != -1) {
-            bytesRead++;
-        }
-
-        if (bytesRead >= updateSize) {
-            totalBytesRead += bytesRead;
-
-            if (relative)
-                listener.progressUpdate(bytesRead);
-            else
-                listener.progressUpdate(totalBytesRead);
-
-            bytesRead = 0;
-        }
-
-        return i;
-    }
-
-    @Override
-    public int read(char[] b) throws IOException {
-        int i = super.read(b,0,b.length);
-
-        if(i!=-1) {
-            bytesRead += i;
-        }
-
-        if (bytesRead >= updateSize) {
-            totalBytesRead += bytesRead;
-
-            if (relative)
-                listener.progressUpdate(bytesRead);
-            else
-                listener.progressUpdate(totalBytesRead);
-
-            bytesRead = 0;
-        }
-
-        return i;
-    }
-
-    @Override
-    public int read(char[] b, int off, int len) throws IOException {
-        int i = super.read(b,off,len);
-
-        if(i != -1) {
-            bytesRead += i;
-        }
-
-        if (bytesRead >= updateSize) {
-            totalBytesRead += bytesRead;
-
-            if (relative)
-                listener.progressUpdate(bytesRead);
-            else
-                listener.progressUpdate(totalBytesRead);
-
-            bytesRead = 0;
-        }
-
-        return i;
-    }
-
-    @Override
-    public void reset() throws IOException {
-        super.reset();
-        totalBytesRead = 0;
-        bytesRead = 0;
-    }
-
-    @Override
-    public long skip(long n) throws IOException {
-        long result = skip(n);
-
-        bytesRead += n;
-
-        if (bytesRead >= updateSize) {
-            totalBytesRead += bytesRead;
-
-            if (relative)
-                listener.progressUpdate(bytesRead);
-            else
-                listener.progressUpdate(totalBytesRead);
-
-            bytesRead = 0;
-        }
-
-        return result;
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2004 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.io;
+
+// External imports
+import java.io.*;
+
+// Local imports
+// None
+
+/**
+ * Listens for updates to read status on a stream.
+ * <p>
+ * @author Alan Hudson
+ * @version $Revision: 1.3 $
+ */
+public class ReportableInputStreamReader extends FilterReader {
+
+    /** The number of bytes read since last update*/
+    private int bytesRead;
+
+    /** The total number of bytes read */
+    private int totalBytesRead;
+
+    /** Whether to report relative or absolute values */
+    private boolean relative;
+
+    /** The frequency(bytes) to report updates */
+    private int updateSize;
+
+    /** The Progress Listener */
+    private ReadProgressListener listener;
+
+    /**
+     * Construct an instance of the reader that wraps a stream and has a listener
+     * already associated with it.
+     *
+     * @param relative Whether the update size is relative or absolute.
+     * @param updateSize The size in bytes to issue updates.
+     *        This will be approximately honored.
+     * @param listener The progress listener
+     * @param in The input source
+     */
+    public ReportableInputStreamReader(boolean relative, int updateSize,
+        ReadProgressListener listener, InputStream in) {
+
+        super(new InputStreamReader(in));
+
+        bytesRead = 0;
+        this.relative = relative;
+        this.updateSize = updateSize;
+        this.listener = listener;
+    }
+
+    @Override
+    public void close() throws IOException {
+        super.close();
+
+        if (listener != null)
+            listener.streamClosed();
+    }
+
+    @Override
+    public int read() throws IOException {
+        int i = super.read();
+
+        if(i != -1) {
+            bytesRead++;
+        }
+
+        if (bytesRead >= updateSize) {
+            totalBytesRead += bytesRead;
+
+            if (relative)
+                listener.progressUpdate(bytesRead);
+            else
+                listener.progressUpdate(totalBytesRead);
+
+            bytesRead = 0;
+        }
+
+        return i;
+    }
+
+    @Override
+    public int read(char[] b) throws IOException {
+        int i = super.read(b,0,b.length);
+
+        if(i!=-1) {
+            bytesRead += i;
+        }
+
+        if (bytesRead >= updateSize) {
+            totalBytesRead += bytesRead;
+
+            if (relative)
+                listener.progressUpdate(bytesRead);
+            else
+                listener.progressUpdate(totalBytesRead);
+
+            bytesRead = 0;
+        }
+
+        return i;
+    }
+
+    @Override
+    public int read(char[] b, int off, int len) throws IOException {
+        int i = super.read(b,off,len);
+
+        if(i != -1) {
+            bytesRead += i;
+        }
+
+        if (bytesRead >= updateSize) {
+            totalBytesRead += bytesRead;
+
+            if (relative)
+                listener.progressUpdate(bytesRead);
+            else
+                listener.progressUpdate(totalBytesRead);
+
+            bytesRead = 0;
+        }
+
+        return i;
+    }
+
+    @Override
+    public void reset() throws IOException {
+        super.reset();
+        totalBytesRead = 0;
+        bytesRead = 0;
+    }
+
+    @Override
+    public long skip(long n) throws IOException {
+        long result = skip(n);
+
+        bytesRead += n;
+
+        if (bytesRead >= updateSize) {
+            totalBytesRead += bytesRead;
+
+            if (relative)
+                listener.progressUpdate(bytesRead);
+            else
+                listener.progressUpdate(totalBytesRead);
+
+            bytesRead = 0;
+        }
+
+        return result;
+    }
+}
diff --git a/src/java/org/xj3d/io/ReportableReader.java b/src/java/org/xj3d/io/ReportableReader.java
index 250386b360a0e9a6cdcd364f385cb5823ee4597a..2180cea2a364790d4cd9762e71746c22bb92a346 100644
--- a/src/java/org/xj3d/io/ReportableReader.java
+++ b/src/java/org/xj3d/io/ReportableReader.java
@@ -1,164 +1,164 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2004 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.io;
-
-// External imports
-import java.io.*;
-
-// Local imports
-
-/**
- * Listens for updates to read status on a stream.
- * 
- * @author Alan Hudson
- * @version $Revision: 1.3 $
- */
-public class ReportableReader extends FilterReader {
-
-    /** The number of bytes read since last update*/
-    private int bytesRead;
-
-    /** The total number of bytes read */
-    private int totalBytesRead;
-
-    /** Whether to report relative or absolute values */
-    private boolean relative;
-
-    /** The frequency(bytes) to report updates */
-    private int updateSize;
-
-    /** The Progress Listener */
-    private ReadProgressListener listener;
-
-    /**
-     * Constructor.
-     *
-     * @param relative Whether the update size is relative or absolute.
-     * @param updateSize The size in bytes to issue updates.
-     *        This will be approximately honored.
-     * @param listener The progress listener
-     * @param in The input source
-     */
-    public ReportableReader(boolean relative, int updateSize,
-        ReadProgressListener listener, Reader in) {
-
-        super(in);
-
-        bytesRead = 0;
-        this.relative = relative;
-        this.updateSize = updateSize;
-        this.listener = listener;
-    }
-
-    @Override
-    public void close() throws IOException {
-        super.close();
-
-        if (listener != null)
-            listener.streamClosed();
-    }
-
-
-    @Override
-    public int read() throws IOException {
-        int i = super.read();
-
-        if(i != -1) {
-            bytesRead++;
-        }
-
-        if (bytesRead >= updateSize) {
-            totalBytesRead += bytesRead;
-
-            if (relative)
-                listener.progressUpdate(bytesRead);
-            else
-                listener.progressUpdate(totalBytesRead);
-
-            bytesRead = 0;
-        }
-
-        return i;
-    }
-
-    @Override
-    public int read(char[] b) throws IOException {
-        int i = super.read(b,0,b.length);
-
-        if(i!=-1) {
-            bytesRead += i;
-        }
-
-        if (bytesRead >= updateSize) {
-            totalBytesRead += bytesRead;
-
-            if (relative)
-                listener.progressUpdate(bytesRead);
-            else
-                listener.progressUpdate(totalBytesRead);
-
-            bytesRead = 0;
-        }
-
-        return i;
-    }
-
-    @Override
-    public int read(char[] b, int off, int len) throws IOException {
-        int i = super.read(b,off,len);
-
-        if(i != -1) {
-            bytesRead += i;
-        }
-
-        if (bytesRead >= updateSize) {
-            totalBytesRead += bytesRead;
-
-            if (relative)
-                listener.progressUpdate(bytesRead);
-            else
-                listener.progressUpdate(totalBytesRead);
-
-            bytesRead = 0;
-        }
-
-        return i;
-    }
-
-    @Override
-    public void reset() throws IOException {
-        super.reset();
-        totalBytesRead = 0;
-        bytesRead = 0;
-    }
-
-    @Override
-    public long skip(long n) throws IOException {
-        long result = skip(n);
-
-        bytesRead += n;
-
-        if (bytesRead >= updateSize) {
-            totalBytesRead += bytesRead;
-
-            if (relative)
-                listener.progressUpdate(bytesRead);
-            else
-                listener.progressUpdate(totalBytesRead);
-
-            bytesRead = 0;
-        }
-
-        return result;
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2004 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.io;
+
+// External imports
+import java.io.*;
+
+// Local imports
+
+/**
+ * Listens for updates to read status on a stream.
+ * <p>
+ * @author Alan Hudson
+ * @version $Revision: 1.3 $
+ */
+public class ReportableReader extends FilterReader {
+
+    /** The number of bytes read since last update*/
+    private int bytesRead;
+
+    /** The total number of bytes read */
+    private int totalBytesRead;
+
+    /** Whether to report relative or absolute values */
+    private boolean relative;
+
+    /** The frequency(bytes) to report updates */
+    private int updateSize;
+
+    /** The Progress Listener */
+    private ReadProgressListener listener;
+
+    /**
+     * Constructor.
+     *
+     * @param relative Whether the update size is relative or absolute.
+     * @param updateSize The size in bytes to issue updates.
+     *        This will be approximately honored.
+     * @param listener The progress listener
+     * @param in The input source
+     */
+    public ReportableReader(boolean relative, int updateSize,
+        ReadProgressListener listener, Reader in) {
+
+        super(in);
+
+        bytesRead = 0;
+        this.relative = relative;
+        this.updateSize = updateSize;
+        this.listener = listener;
+    }
+
+    @Override
+    public void close() throws IOException {
+        super.close();
+
+        if (listener != null)
+            listener.streamClosed();
+    }
+
+
+    @Override
+    public int read() throws IOException {
+        int i = super.read();
+
+        if(i != -1) {
+            bytesRead++;
+        }
+
+        if (bytesRead >= updateSize) {
+            totalBytesRead += bytesRead;
+
+            if (relative)
+                listener.progressUpdate(bytesRead);
+            else
+                listener.progressUpdate(totalBytesRead);
+
+            bytesRead = 0;
+        }
+
+        return i;
+    }
+
+    @Override
+    public int read(char[] b) throws IOException {
+        int i = super.read(b,0,b.length);
+
+        if(i!=-1) {
+            bytesRead += i;
+        }
+
+        if (bytesRead >= updateSize) {
+            totalBytesRead += bytesRead;
+
+            if (relative)
+                listener.progressUpdate(bytesRead);
+            else
+                listener.progressUpdate(totalBytesRead);
+
+            bytesRead = 0;
+        }
+
+        return i;
+    }
+
+    @Override
+    public int read(char[] b, int off, int len) throws IOException {
+        int i = super.read(b,off,len);
+
+        if(i != -1) {
+            bytesRead += i;
+        }
+
+        if (bytesRead >= updateSize) {
+            totalBytesRead += bytesRead;
+
+            if (relative)
+                listener.progressUpdate(bytesRead);
+            else
+                listener.progressUpdate(totalBytesRead);
+
+            bytesRead = 0;
+        }
+
+        return i;
+    }
+
+    @Override
+    public void reset() throws IOException {
+        super.reset();
+        totalBytesRead = 0;
+        bytesRead = 0;
+    }
+
+    @Override
+    public long skip(long n) throws IOException {
+        long result = skip(n);
+
+        bytesRead += n;
+
+        if (bytesRead >= updateSize) {
+            totalBytesRead += bytesRead;
+
+            if (relative)
+                listener.progressUpdate(bytesRead);
+            else
+                listener.progressUpdate(totalBytesRead);
+
+            bytesRead = 0;
+        }
+
+        return result;
+    }
+}
diff --git a/src/java/org/xj3d/loaders/ogl/Web3DLoader.java b/src/java/org/xj3d/loaders/ogl/Web3DLoader.java
index 4f5fa3918797308016987f67f1170e04f8f150b9..22d7ba730f69aaa341ca4e824bcf58da18d6f8c9 100644
--- a/src/java/org/xj3d/loaders/ogl/Web3DLoader.java
+++ b/src/java/org/xj3d/loaders/ogl/Web3DLoader.java
@@ -22,6 +22,7 @@ import org.web3d.net.protocol.Web3DResourceFactory;
 /**
  * A Aviatrix3D file loader implementation for reading all Web3D file formats
  * building a scene graph with them.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/xj3d/sai/BrowserConfig.java b/src/java/org/xj3d/sai/BrowserConfig.java
index 5f32272324ba52d3391d8a4e5b2dba6d64b924e1..71a6f3aa55d6b646ac5b5eeaa5351d28eb68d2c2 100644
--- a/src/java/org/xj3d/sai/BrowserConfig.java
+++ b/src/java/org/xj3d/sai/BrowserConfig.java
@@ -1,563 +1,563 @@
-/*****************************************************************************
- *                     Yumetech, Inc Copyright (c) 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- *****************************************************************************/
-
-package org.xj3d.sai;
-
-// External Imports
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.StringTokenizer;
-
-// Local Imports
-// None
-
-/**
- * Utility class to load, qualify and store SAI and EAI browser configuration
- * parameters, including the properties defining the browser 'skin'.
- * Used by the various BrowserFactoryImpl's as a common parameter loader.
- *
- * @author Rex Melton
- * @version $Revision: 1.2 $
- */
-public class BrowserConfig {
-
-    //////////////////////////////////////////////////////////////////////////////////////
-    // Known Xj3D parameter Strings
-
-    // Parameters defined in spec
-    private static final String ANTIALIASED_PARAM = "Antialiased";
-    private static final String PRIMITIVE_QUALITY_PARAM = "PrimitiveQuality";
-    private static final String SHADING_PARAM = "Shading";
-    private static final String TEXTURE_QUALITY_PARAM = "TextureQuality";
-
-    // Parameters common to Xj3D factory impls
-    private static final String NAV_SHOW_PARAM = "Xj3D_NavbarShown";
-    private static final String NAV_POS_PARAM = "Xj3D_NavbarPosition";
-    private static final String LOC_SHOW_PARAM = "Xj3D_LocationShown";
-    private static final String LOC_POS_PARAM = "Xj3D_LocationPosition";
-    private static final String LOC_READONLY_PARAM = "Xj3D_LocationReadOnly";
-    private static final String SHOW_CONSOLE_PARAM = "Xj3D_ShowConsole";
-    private static final String OPEN_BUTTON_SHOW_PARAM = "Xj3D_OpenButtonShown";
-    private static final String RELOAD_BUTTON_SHOW_PARAM = "Xj3D_ReloadButtonShown";
-    private static final String STATUS_BAR_SHOW_PARAM = "Xj3D_StatusBarShown";
-    private static final String FPS_SHOW_PARAM = "Xj3D_FPSShown";
-    private static final String CONTENT_DIRECTORY_PARAM = "Xj3D_ContentDirectory";
-    private static final String ANTIALIASING_QUALITY_PARAM = "Xj3D_AntialiasingQuality";
-    private static final String DIMENSIONS_PARAM = "Xj3D_PreferredDimensions";
-    private static final String DISABLE_AUDIO_PARAM = "Xj3D_DisableAudio";
-
-    // AWT / Swing toolkit specific parameter
-    private static final String SWING_PARAM = "Xj3D_InterfaceType";
-
-    // SAI only parameters
-    private static final String SKIN_PROPERTIES = "Xj3D_Skin_Properties";
-    private static final String SKIN_RESOURCES = "Xj3D_Skin_Resources";
-
-    // Rendering configuration parameters
-    private static final String CULLING_MODE = "Xj3D_Culling_Mode";
-    private static final String FORCE_LIGHTING = "Xj3D_ForceLighting";
-
-    //////////////////////////////////////////////////////////////////////////////////////
-
-    /** Error message for passing a null String in loadURL */
-    private static final String NULL_PARAMETER_ERROR = "Null parameter strings not allowed.";
-
-    /** Error message for malformed parameter String in loadURL */
-    private static final String MALFORMED_PARAMETER_STRING_ERROR =
-        "Malformed parameter string."+
-        "  Expecting strings of the form A=B";
-
-    /** Property file defining the appearance of the browser */
-    private static final String SKIN_PROPERTY_FILE = "xj3d-skin.properties";
-
-    /** Set of quality params */
-    private static Set<String> qualitySet;
-
-    /** Set of culling mode params */
-    private static Set<String> cullingSet;
-
-    /** Should the browser be restricted to VRML97 only. Default false. */
-    public boolean vrml97Only;
-
-    /** The type of GUI interface that should be created */
-    public BrowserInterfaceTypes interfaceType;
-
-    /** Should the navigation bar be visible. Default true. */
-    public boolean showDash;
-
-    /** Placement of the navigation bar if visible. Default false. */
-    public boolean dashTop;
-
-    /** Should the location bar be visible. Default true. */
-    public boolean showUrl;
-
-    /** Placement of the location bar if visible. Default true. */
-    public boolean urlTop;
-
-    /** Should the location bar be read only. Default false. */
-    public boolean urlReadOnly;
-
-    /** Should the console be visible. Default false. */
-    public boolean showConsole;
-
-    /** Should the open button, on the location bar, be visible. Default false. */
-    public boolean showOpenButton;
-
-    /** Should the reload button, on the location bar, be visible. Default false. */
-    public boolean showReloadButton;
-
-    /** Should StatusBar be shown. Default false. */
-    public boolean showStatusBar;
-
-    /** Should StatusBar have a frames-per-second display. Default false. */
-    public boolean showFPS;
-
-    /** Initial directory to use for locating content. Defaults to System.getProperty("user.dir")*/
-    public String contentDirectory;
-
-    /** Antialiasing enabled. Default false. */
-    public boolean antialiased;
-
-    /** Antialiasing quality. "low"|"medium"|"high". Default "low". */
-    public String antialiasingQuality;
-
-    /** Primitive geometry quality. "low"|"medium"|"high". Default "medium". */
-    public String primitiveQuality;
-
-    /** Texture quality. "low"|"medium"|"high". Default "medium". */
-    public String textureQuality;
-
-    /** Properties object defining appearance of browser panel. Defaults to an empty Properties object. */
-    public Properties browserSkin;
-
-    /** Map object containing default resources referred to by the skinProperties. Default null. */
-    public Map<String, Object> resourceMap;
-
-    /** Culling Mode. "none"|"frustum". Default "frustum". */
-    public String cullingMode;
-
-    /** Should we force objects with no appearance to have a material for lighting */
-    public boolean forceLighting;
-
-    /** The preferred width of the window. */
-    public int preferredWidth;
-
-    /** The preferred height of the window. */
-    public int preferredHeight;
-
-    /** Should audio be disabled. Default false. */
-    public boolean disableAudio;
-
-    /**
-     * Create a BrowserConfig instance initialized with defaults.
-     */
-    public BrowserConfig() {
-
-        vrml97Only = false;
-
-        // In the case of testing w/ EAI, NEWT does not work and LIGHTWEIGHT is
-        // a performance hit
-        interfaceType = BrowserInterfaceTypes.PARTIAL_LIGHTWEIGHT;
-        showDash = true;
-        dashTop = false;
-        showUrl = true;
-        urlTop = true;
-        urlReadOnly = false;
-        showConsole = false;
-        showOpenButton = false;
-        showReloadButton = false;
-        showStatusBar = false;
-        disableAudio = false;
-        showFPS = false;
-        antialiased = false;
-        antialiasingQuality = "low";
-        primitiveQuality = "medium";
-        textureQuality = "medium";
-        cullingMode = "frustum";
-        forceLighting = false;
-
-        browserSkin = new Properties();
-        contentDirectory = System.getProperty("user.dir");
-    }
-
-    /**
-     * Create a BrowserConfig instance initialized with defaults which will be
-     * overridden by any parameters passed in the argument array.
-     *
-     * @param params Parameters to control the look and feel.
-     * @throws IllegalArgumentException if a parameter in the argument Map is invalid.
-     */
-    public BrowserConfig(String[] params) {
-        this(); // invoke default constructor
-
-        if((params != null) && (params.length != 0)) {
-            Map<String, Object> paramMap = parseParameters(params);
-            initialize(paramMap, false);
-        } else {
-            initialize(null, false);
-        }
-    }
-
-    /**
-     * Create a BrowserConfig instance initialized with defaults which will be
-     * overridden by any parameters passed in the argument Map.
-     *
-     * @param params Parameters to control the look and feel.
-     * @throws IllegalArgumentException if a parameter in the argument Map is invalid.
-     */
-    public BrowserConfig(Map<String, Object> params) {
-        this(); // invoke default constructor
-        initialize(params, true);
-    }
-
-    //-----------------------------------------------------------------------
-    // Local Methods
-    //-----------------------------------------------------------------------
-
-    /**
-     * Overridden the default parameters with values from the argument Map.
-     *
-     * @param params Parameters to control the look and feel.
-     * @param isSAI Indication of the source of the parameters. <code>false</code> if
-     * the Map values are derived from an EAI String[] and must be cast to
-     * their type (if the required type is not a String). <code>true</code> if the
-     * Map has been passed from the SAI constructor - and are already in their required
-     * types.
-     * @throws IllegalArgumentException if a parameter in the argument Map is invalid.
-     */
-    @SuppressWarnings("unchecked")
-    private void initialize(Map<String, Object> params, boolean isSAI) {
-
-        if((params != null) && (!params.isEmpty())) {
-
-            if(qualitySet == null) {
-                qualitySet = new HashSet<>(3);
-                qualitySet.add("low");
-                qualitySet.add("medium");
-                qualitySet.add("high");
-            }
-
-            if(cullingSet == null) {
-                cullingSet = new HashSet<>(2);
-                cullingSet.add("none");
-                cullingSet.add("frustum");
-            }
-
-            String stringVal = getStringValue(params, SWING_PARAM, isSAI);
-            if(stringVal != null) {
-
-                // AWT is not very fucntional and very limited in capability
-                if(stringVal.equalsIgnoreCase("awt"))
-                    interfaceType = BrowserInterfaceTypes.HEAVYWEIGHT;
-                else if(stringVal.equalsIgnoreCase("swing"))
-                    interfaceType = BrowserInterfaceTypes.PARTIAL_LIGHTWEIGHT;
-                else if(stringVal.equalsIgnoreCase("swing-lightweight"))
-                    interfaceType = BrowserInterfaceTypes.LIGHTWEIGHT;
-                else if(stringVal.equalsIgnoreCase("newt"))
-                    interfaceType = BrowserInterfaceTypes.NEWT;
-                else if(stringVal.equalsIgnoreCase("offscreen"))
-                    interfaceType = BrowserInterfaceTypes.OFFSCREEN;
-            }
-
-            Boolean booleanVal = getBooleanValue(params, NAV_SHOW_PARAM, isSAI);
-            if(booleanVal != null) {
-                showDash = booleanVal;
-            }
-
-            stringVal = getStringValue(params, NAV_POS_PARAM, isSAI);
-            if(stringVal != null) {
-                dashTop = stringVal.equalsIgnoreCase("top");
-            }
-
-            booleanVal = getBooleanValue(params, LOC_SHOW_PARAM, isSAI);
-            if(booleanVal != null) {
-                showUrl = booleanVal;
-            }
-
-            stringVal = getStringValue(params, LOC_POS_PARAM, isSAI);
-            if(stringVal != null) {
-                urlTop = stringVal.equalsIgnoreCase("top");
-            }
-
-            booleanVal = getBooleanValue(params, LOC_READONLY_PARAM, isSAI);
-            if(booleanVal != null) {
-                urlReadOnly = booleanVal;
-            }
-
-            booleanVal = getBooleanValue(params, SHOW_CONSOLE_PARAM, isSAI);
-            if(booleanVal != null) {
-                showConsole = booleanVal;
-            }
-
-            booleanVal = getBooleanValue(params, OPEN_BUTTON_SHOW_PARAM, isSAI);
-            if(booleanVal != null) {
-                showOpenButton = booleanVal;
-            }
-
-            booleanVal = getBooleanValue(params, RELOAD_BUTTON_SHOW_PARAM, isSAI);
-            if(booleanVal != null) {
-                showReloadButton = booleanVal;
-            }
-
-            booleanVal = getBooleanValue(params, STATUS_BAR_SHOW_PARAM, isSAI);
-            if(booleanVal != null) {
-                showStatusBar = booleanVal;
-            }
-
-            booleanVal = getBooleanValue(params, FPS_SHOW_PARAM, isSAI);
-            if(booleanVal != null) {
-                showFPS = booleanVal;
-            }
-
-            stringVal = getStringValue(params, CONTENT_DIRECTORY_PARAM, isSAI);
-            if(stringVal != null) {
-                contentDirectory = stringVal;
-            }
-
-            booleanVal = getBooleanValue(params, ANTIALIASED_PARAM, isSAI);
-            if(booleanVal != null) {
-                antialiased = booleanVal;
-            }
-
-            booleanVal = getBooleanValue(params, FORCE_LIGHTING, isSAI);
-            if(booleanVal != null) {
-                forceLighting = booleanVal;
-            }
-
-            stringVal = getStringValue(params, PRIMITIVE_QUALITY_PARAM, isSAI);
-            if(stringVal != null) {
-                if(!qualitySet.contains(stringVal)) {
-                    throw new IllegalArgumentException(
-                        "BrowserConfig: " + PRIMITIVE_QUALITY_PARAM + " must be low, medium or high");
-                }
-                primitiveQuality = stringVal;
-            }
-
-            stringVal = getStringValue(params, TEXTURE_QUALITY_PARAM, isSAI);
-            if(stringVal != null) {
-                if(!qualitySet.contains(stringVal)) {
-                    throw new IllegalArgumentException(
-                        "BrowserConfig: " + TEXTURE_QUALITY_PARAM + " must be low, medium or high");
-                }
-                textureQuality = stringVal;
-            }
-
-            stringVal = getStringValue(params, ANTIALIASING_QUALITY_PARAM, isSAI);
-            if(stringVal != null) {
-                if(!qualitySet.contains(stringVal)) {
-                    throw new IllegalArgumentException(
-                        "BrowserConfig: " + ANTIALIASING_QUALITY_PARAM + " must be low, medium or high");
-                }
-                antialiasingQuality = stringVal;
-            }
-
-            Object obj = params.get(SKIN_PROPERTIES);
-            if(obj != null && !(obj instanceof Properties)) {
-                throw new IllegalArgumentException(
-                    "BrowserConfig: " + SKIN_PROPERTIES + " must be a Properties object");
-            }
-            else {
-                browserSkin = (Properties)obj;
-            }
-
-            obj = params.get(SKIN_RESOURCES);
-            if(obj != null && !(obj instanceof Map)) {
-                throw new IllegalArgumentException(
-                    "BrowserConfig: "+ SKIN_RESOURCES + " must be a Map object");
-            }
-            else {
-                // unchecked cast warning suppressed
-                resourceMap = (Map<String, Object>)obj;
-            }
-
-            stringVal = getStringValue(params, CULLING_MODE, isSAI);
-            if(stringVal != null) {
-                if(!cullingSet.contains(stringVal)) {
-                    throw new IllegalArgumentException(
-                        "BrowserConfig: " + CULLING_MODE + " must be none or frustum");
-                }
-                cullingMode = stringVal;
-            }
-
-            stringVal = getStringValue(params, DIMENSIONS_PARAM, isSAI);
-            if(stringVal != null) {
-               StringTokenizer strtok = new StringTokenizer(stringVal, "x");
-               String width_str = strtok.nextToken();
-               String height_str = strtok.nextToken();
-
-               try {
-                   preferredWidth = Integer.parseInt(width_str);
-               } catch(NumberFormatException nfe) {
-                   // Should do something here, but no error reporter.
-                   nfe.printStackTrace(System.err);
-               }
-
-               try {
-                   preferredHeight = Integer.parseInt(height_str);
-               } catch(NumberFormatException nfe) {
-                   // Should do something here, but no error reporter.
-                   nfe.printStackTrace(System.err);
-               }
-            }
-
-            booleanVal = getBooleanValue(params, DISABLE_AUDIO_PARAM, isSAI);
-            if(booleanVal != null) {
-                disableAudio = booleanVal;
-            }
-        }
-
-        if(browserSkin == null) {
-            loadBrowserSkin();
-        }
-        if(contentDirectory == null) {
-            contentDirectory = System.getProperty("user.dir");
-        }
-    }
-
-    /**
-     * Extract the specified parameter from the argument Map, qualify and return it.
-     *
-     * @param params The Map containing the parameters
-     * @param paramName The key of the parameter in the Map
-     * @param isSAI The 'qualification' switch
-     * @return The qualified parameter value, or null if it does not exist.
-     * @throws IllegalArgumentException if the parameter isSAI, and is not an instanceof Boolean.
-     */
-    private Boolean getBooleanValue(Map params, String paramName, boolean isSAI) {
-        Boolean booleanVal = null;
-        Object obj = params.get(paramName);
-        if(obj != null) {
-            if(isSAI) {
-                if(!(obj instanceof Boolean)) {
-                    throw new IllegalArgumentException("BrowserConfig: " + paramName + " must be a Boolean");
-                } else {
-                    booleanVal = (Boolean)obj;
-                }
-            } else {
-                booleanVal = Boolean.valueOf((String)obj);
-            }
-        }
-        return(booleanVal);
-    }
-
-    /**
-     * Extract the specified parameter from the argument Map, qualify and return it.
-     *
-     * @param params The Map containing the parameters
-     * @param paramName The key of the parameter in the Map
-     * @param isSAI The 'qualification' switch
-     * @return The qualified parameter value, or null if it does not exist.
-     * @throws IllegalArgumentException if the parameter isSAI, and is not an instanceof String.
-     */
-    private String getStringValue(Map params, String paramName, boolean isSAI) {
-        String stringVal = null;
-        Object obj = params.get(paramName);
-        if(obj != null) {
-            if(isSAI) {
-                if(!(obj instanceof String)) {
-                    throw new IllegalArgumentException("BrowserConfig: " + paramName + " must be a String");
-                }
-            }
-            stringVal = (String)obj;
-        }
-        return(stringVal);
-    }
-
-    /**
-     * Parse the strings from the parameter array and place them into a map
-     * so it is easy to look them up. Assumes the list is non-null.
-     *
-     * @param params The given parameter list
-     * @return a map of the parsed parameters
-     */
-    private Map<String, Object> parseParameters(String[] params) {
-        Map<String, Object> ret_val = new HashMap<>();
-
-        for(String param : params) {
-            if(param==null)
-                throw new IllegalArgumentException(NULL_PARAMETER_ERROR);
-            int index = param.indexOf('=');
-            if(index<1)
-                throw new IllegalArgumentException(MALFORMED_PARAMETER_STRING_ERROR);
-            ret_val.put(param.substring(0, index),
-                param.substring(index + 1));
-        }
-
-        return ret_val;
-    }
-
-    /**
-     * Load the browser skin properties. These properties are
-     * passed along to configure the appearance of the user
-     * interface components associated with the X3DComponent.
-     */
-    private void loadBrowserSkin() {
-        try {
-            browserSkin = AccessController.doPrivileged((PrivilegedExceptionAction<Properties>) () -> {
-                InputStream is;
-                Properties props = new Properties();
-                String search_path;
-                
-                String user_dirname = System.getProperty("user.dir");
-                String user_filename = user_dirname + File.separator + SKIN_PROPERTY_FILE;
-                // Using File.separator does not work for defLoc, not sure why
-                String default_filename = "config/common/" + SKIN_PROPERTY_FILE;
-                try {
-                    is = new FileInputStream(user_filename);
-                    search_path = user_filename;
-                } catch(FileNotFoundException fnfe) {
-                    // Fallback to default
-                    is = ClassLoader.getSystemClassLoader().getResourceAsStream(default_filename);
-                    search_path = default_filename;
-                }
-                
-                // Fallback for WebStart
-                if(is == null) {
-                    is = BrowserConfig.class.getClassLoader().getResourceAsStream(default_filename);
-                    search_path = default_filename;
-                }
-                
-                if(is == null) {
-                    System.out.println("Skin properties file: "+ search_path +" not found");
-                    System.out.println("Returning default properties.");
-                } else {
-                    try {
-                        props.load(is);
-                    } catch(IOException ioe) {
-                        System.err.println("Error reading skin properties file: "+ search_path +" "+ ioe.getMessage());
-                        System.err.println("Returning default properties.");
-                    } finally {
-                        try {
-                            is.close();
-                        } catch(IOException ioe) {}
-                    }
-                }
-                return(props);
-            });
-        } catch (PrivilegedActionException pae) {
-            System.err.println("Error getting skin properties");
-        }
-    }
-}
+/*****************************************************************************
+ *                     Yumetech, Inc Copyright (c) 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ *****************************************************************************/
+
+package org.xj3d.sai;
+
+// External Imports
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+// Local Imports
+// None
+
+/**
+ * Utility class to load, qualify and store SAI and EAI browser configuration
+ * parameters, including the properties defining the browser 'skin'.
+ * Used by the various BrowserFactoryImpl's as a common parameter loader.
+ *
+ * @author Rex Melton
+ * @version $Revision: 1.2 $
+ */
+public class BrowserConfig {
+
+    //////////////////////////////////////////////////////////////////////////////////////
+    // Known Xj3D parameter Strings
+
+    // Parameters defined in spec
+    private static final String ANTIALIASED_PARAM = "Antialiased";
+    private static final String PRIMITIVE_QUALITY_PARAM = "PrimitiveQuality";
+    private static final String SHADING_PARAM = "Shading";
+    private static final String TEXTURE_QUALITY_PARAM = "TextureQuality";
+
+    // Parameters common to Xj3D factory impls
+    private static final String NAV_SHOW_PARAM = "Xj3D_NavbarShown";
+    private static final String NAV_POS_PARAM = "Xj3D_NavbarPosition";
+    private static final String LOC_SHOW_PARAM = "Xj3D_LocationShown";
+    private static final String LOC_POS_PARAM = "Xj3D_LocationPosition";
+    private static final String LOC_READONLY_PARAM = "Xj3D_LocationReadOnly";
+    private static final String SHOW_CONSOLE_PARAM = "Xj3D_ShowConsole";
+    private static final String OPEN_BUTTON_SHOW_PARAM = "Xj3D_OpenButtonShown";
+    private static final String RELOAD_BUTTON_SHOW_PARAM = "Xj3D_ReloadButtonShown";
+    private static final String STATUS_BAR_SHOW_PARAM = "Xj3D_StatusBarShown";
+    private static final String FPS_SHOW_PARAM = "Xj3D_FPSShown";
+    private static final String CONTENT_DIRECTORY_PARAM = "Xj3D_ContentDirectory";
+    private static final String ANTIALIASING_QUALITY_PARAM = "Xj3D_AntialiasingQuality";
+    private static final String DIMENSIONS_PARAM = "Xj3D_PreferredDimensions";
+    private static final String DISABLE_AUDIO_PARAM = "Xj3D_DisableAudio";
+
+    // AWT / Swing toolkit specific parameter
+    private static final String SWING_PARAM = "Xj3D_InterfaceType";
+
+    // SAI only parameters
+    private static final String SKIN_PROPERTIES = "Xj3D_Skin_Properties";
+    private static final String SKIN_RESOURCES = "Xj3D_Skin_Resources";
+
+    // Rendering configuration parameters
+    private static final String CULLING_MODE = "Xj3D_Culling_Mode";
+    private static final String FORCE_LIGHTING = "Xj3D_ForceLighting";
+
+    //////////////////////////////////////////////////////////////////////////////////////
+
+    /** Error message for passing a null String in loadURL */
+    private static final String NULL_PARAMETER_ERROR = "Null parameter strings not allowed.";
+
+    /** Error message for malformed parameter String in loadURL */
+    private static final String MALFORMED_PARAMETER_STRING_ERROR =
+        "Malformed parameter string."+
+        "  Expecting strings of the form A=B";
+
+    /** Property file defining the appearance of the browser */
+    private static final String SKIN_PROPERTY_FILE = "xj3d-skin.properties";
+
+    /** Set of quality params */
+    private static Set<String> qualitySet;
+
+    /** Set of culling mode params */
+    private static Set<String> cullingSet;
+
+    /** Should the browser be restricted to VRML97 only. Default false. */
+    public boolean vrml97Only;
+
+    /** The type of GUI interface that should be created */
+    public BrowserInterfaceTypes interfaceType;
+
+    /** Should the navigation bar be visible. Default true. */
+    public boolean showDash;
+
+    /** Placement of the navigation bar if visible. Default false. */
+    public boolean dashTop;
+
+    /** Should the location bar be visible. Default true. */
+    public boolean showUrl;
+
+    /** Placement of the location bar if visible. Default true. */
+    public boolean urlTop;
+
+    /** Should the location bar be read only. Default false. */
+    public boolean urlReadOnly;
+
+    /** Should the console be visible. Default false. */
+    public boolean showConsole;
+
+    /** Should the open button, on the location bar, be visible. Default false. */
+    public boolean showOpenButton;
+
+    /** Should the reload button, on the location bar, be visible. Default false. */
+    public boolean showReloadButton;
+
+    /** Should StatusBar be shown. Default false. */
+    public boolean showStatusBar;
+
+    /** Should StatusBar have a frames-per-second display. Default false. */
+    public boolean showFPS;
+
+    /** Initial directory to use for locating content. Defaults to System.getProperty("user.dir")*/
+    public String contentDirectory;
+
+    /** Antialiasing enabled. Default false. */
+    public boolean antialiased;
+
+    /** Antialiasing quality. "low"|"medium"|"high". Default "low". */
+    public String antialiasingQuality;
+
+    /** Primitive geometry quality. "low"|"medium"|"high". Default "medium". */
+    public String primitiveQuality;
+
+    /** Texture quality. "low"|"medium"|"high". Default "medium". */
+    public String textureQuality;
+
+    /** Properties object defining appearance of browser panel. Defaults to an empty Properties object. */
+    public Properties browserSkin;
+
+    /** Map object containing default resources referred to by the skinProperties. Default null. */
+    public Map<String, Object> resourceMap;
+
+    /** Culling Mode. "none"|"frustum". Default "frustum". */
+    public String cullingMode;
+
+    /** Should we force objects with no appearance to have a material for lighting */
+    public boolean forceLighting;
+
+    /** The preferred width of the window. */
+    public int preferredWidth;
+
+    /** The preferred height of the window. */
+    public int preferredHeight;
+
+    /** Should audio be disabled. Default false. */
+    public boolean disableAudio;
+
+    /**
+     * Create a BrowserConfig instance initialized with defaults.
+     */
+    public BrowserConfig() {
+
+        vrml97Only = false;
+
+        // In the case of testing w/ EAI, NEWT does not work and LIGHTWEIGHT is
+        // a performance hit
+        interfaceType = BrowserInterfaceTypes.PARTIAL_LIGHTWEIGHT;
+        showDash = true;
+        dashTop = false;
+        showUrl = true;
+        urlTop = true;
+        urlReadOnly = false;
+        showConsole = false;
+        showOpenButton = false;
+        showReloadButton = false;
+        showStatusBar = false;
+        disableAudio = false;
+        showFPS = false;
+        antialiased = false;
+        antialiasingQuality = "low";
+        primitiveQuality = "medium";
+        textureQuality = "medium";
+        cullingMode = "frustum";
+        forceLighting = false;
+
+        browserSkin = new Properties();
+        contentDirectory = System.getProperty("user.dir");
+    }
+
+    /**
+     * Create a BrowserConfig instance initialized with defaults which will be
+     * overridden by any parameters passed in the argument array.
+     *
+     * @param params Parameters to control the look and feel.
+     * @throws IllegalArgumentException if a parameter in the argument Map is invalid.
+     */
+    public BrowserConfig(String[] params) {
+        this(); // invoke default constructor
+
+        if((params != null) && (params.length != 0)) {
+            Map<String, Object> paramMap = parseParameters(params);
+            initialize(paramMap, false);
+        } else {
+            initialize(null, false);
+        }
+    }
+
+    /**
+     * Create a BrowserConfig instance initialized with defaults which will be
+     * overridden by any parameters passed in the argument Map.
+     *
+     * @param params Parameters to control the look and feel.
+     * @throws IllegalArgumentException if a parameter in the argument Map is invalid.
+     */
+    public BrowserConfig(Map<String, Object> params) {
+        this(); // invoke default constructor
+        initialize(params, true);
+    }
+
+    //-----------------------------------------------------------------------
+    // Local Methods
+    //-----------------------------------------------------------------------
+
+    /**
+     * Overridden the default parameters with values from the argument Map.
+     *
+     * @param params Parameters to control the look and feel.
+     * @param isSAI Indication of the source of the parameters. <code>false</code> if
+     * the Map values are derived from an EAI String[] and must be cast to
+     * their type (if the required type is not a String). <code>true</code> if the
+     * Map has been passed from the SAI constructor - and are already in their required
+     * types.
+     * @throws IllegalArgumentException if a parameter in the argument Map is invalid.
+     */
+    @SuppressWarnings("unchecked")
+    private void initialize(Map<String, Object> params, boolean isSAI) {
+
+        if((params != null) && (!params.isEmpty())) {
+
+            if(qualitySet == null) {
+                qualitySet = new HashSet<>(3);
+                qualitySet.add("low");
+                qualitySet.add("medium");
+                qualitySet.add("high");
+            }
+
+            if(cullingSet == null) {
+                cullingSet = new HashSet<>(2);
+                cullingSet.add("none");
+                cullingSet.add("frustum");
+            }
+
+            String stringVal = getStringValue(params, SWING_PARAM, isSAI);
+            if(stringVal != null) {
+
+                // AWT is not very fucntional and very limited in capability
+                if(stringVal.equalsIgnoreCase("awt"))
+                    interfaceType = BrowserInterfaceTypes.HEAVYWEIGHT;
+                else if(stringVal.equalsIgnoreCase("swing"))
+                    interfaceType = BrowserInterfaceTypes.PARTIAL_LIGHTWEIGHT;
+                else if(stringVal.equalsIgnoreCase("swing-lightweight"))
+                    interfaceType = BrowserInterfaceTypes.LIGHTWEIGHT;
+                else if(stringVal.equalsIgnoreCase("newt"))
+                    interfaceType = BrowserInterfaceTypes.NEWT;
+                else if(stringVal.equalsIgnoreCase("offscreen"))
+                    interfaceType = BrowserInterfaceTypes.OFFSCREEN;
+            }
+
+            Boolean booleanVal = getBooleanValue(params, NAV_SHOW_PARAM, isSAI);
+            if(booleanVal != null) {
+                showDash = booleanVal;
+            }
+
+            stringVal = getStringValue(params, NAV_POS_PARAM, isSAI);
+            if(stringVal != null) {
+                dashTop = stringVal.equalsIgnoreCase("top");
+            }
+
+            booleanVal = getBooleanValue(params, LOC_SHOW_PARAM, isSAI);
+            if(booleanVal != null) {
+                showUrl = booleanVal;
+            }
+
+            stringVal = getStringValue(params, LOC_POS_PARAM, isSAI);
+            if(stringVal != null) {
+                urlTop = stringVal.equalsIgnoreCase("top");
+            }
+
+            booleanVal = getBooleanValue(params, LOC_READONLY_PARAM, isSAI);
+            if(booleanVal != null) {
+                urlReadOnly = booleanVal;
+            }
+
+            booleanVal = getBooleanValue(params, SHOW_CONSOLE_PARAM, isSAI);
+            if(booleanVal != null) {
+                showConsole = booleanVal;
+            }
+
+            booleanVal = getBooleanValue(params, OPEN_BUTTON_SHOW_PARAM, isSAI);
+            if(booleanVal != null) {
+                showOpenButton = booleanVal;
+            }
+
+            booleanVal = getBooleanValue(params, RELOAD_BUTTON_SHOW_PARAM, isSAI);
+            if(booleanVal != null) {
+                showReloadButton = booleanVal;
+            }
+
+            booleanVal = getBooleanValue(params, STATUS_BAR_SHOW_PARAM, isSAI);
+            if(booleanVal != null) {
+                showStatusBar = booleanVal;
+            }
+
+            booleanVal = getBooleanValue(params, FPS_SHOW_PARAM, isSAI);
+            if(booleanVal != null) {
+                showFPS = booleanVal;
+            }
+
+            stringVal = getStringValue(params, CONTENT_DIRECTORY_PARAM, isSAI);
+            if(stringVal != null) {
+                contentDirectory = stringVal;
+            }
+
+            booleanVal = getBooleanValue(params, ANTIALIASED_PARAM, isSAI);
+            if(booleanVal != null) {
+                antialiased = booleanVal;
+            }
+
+            booleanVal = getBooleanValue(params, FORCE_LIGHTING, isSAI);
+            if(booleanVal != null) {
+                forceLighting = booleanVal;
+            }
+
+            stringVal = getStringValue(params, PRIMITIVE_QUALITY_PARAM, isSAI);
+            if(stringVal != null) {
+                if(!qualitySet.contains(stringVal)) {
+                    throw new IllegalArgumentException(
+                        "BrowserConfig: " + PRIMITIVE_QUALITY_PARAM + " must be low, medium or high");
+                }
+                primitiveQuality = stringVal;
+            }
+
+            stringVal = getStringValue(params, TEXTURE_QUALITY_PARAM, isSAI);
+            if(stringVal != null) {
+                if(!qualitySet.contains(stringVal)) {
+                    throw new IllegalArgumentException(
+                        "BrowserConfig: " + TEXTURE_QUALITY_PARAM + " must be low, medium or high");
+                }
+                textureQuality = stringVal;
+            }
+
+            stringVal = getStringValue(params, ANTIALIASING_QUALITY_PARAM, isSAI);
+            if(stringVal != null) {
+                if(!qualitySet.contains(stringVal)) {
+                    throw new IllegalArgumentException(
+                        "BrowserConfig: " + ANTIALIASING_QUALITY_PARAM + " must be low, medium or high");
+                }
+                antialiasingQuality = stringVal;
+            }
+
+            Object obj = params.get(SKIN_PROPERTIES);
+            if(obj != null && !(obj instanceof Properties)) {
+                throw new IllegalArgumentException(
+                    "BrowserConfig: " + SKIN_PROPERTIES + " must be a Properties object");
+            }
+            else {
+                browserSkin = (Properties)obj;
+            }
+
+            obj = params.get(SKIN_RESOURCES);
+            if(obj != null && !(obj instanceof Map)) {
+                throw new IllegalArgumentException(
+                    "BrowserConfig: "+ SKIN_RESOURCES + " must be a Map object");
+            }
+            else {
+                // unchecked cast warning suppressed
+                resourceMap = (Map<String, Object>)obj;
+            }
+
+            stringVal = getStringValue(params, CULLING_MODE, isSAI);
+            if(stringVal != null) {
+                if(!cullingSet.contains(stringVal)) {
+                    throw new IllegalArgumentException(
+                        "BrowserConfig: " + CULLING_MODE + " must be none or frustum");
+                }
+                cullingMode = stringVal;
+            }
+
+            stringVal = getStringValue(params, DIMENSIONS_PARAM, isSAI);
+            if(stringVal != null) {
+               StringTokenizer strtok = new StringTokenizer(stringVal, "x");
+               String width_str = strtok.nextToken();
+               String height_str = strtok.nextToken();
+
+               try {
+                   preferredWidth = Integer.parseInt(width_str);
+               } catch(NumberFormatException nfe) {
+                   // Should do something here, but no error reporter.
+                   nfe.printStackTrace(System.err);
+               }
+
+               try {
+                   preferredHeight = Integer.parseInt(height_str);
+               } catch(NumberFormatException nfe) {
+                   // Should do something here, but no error reporter.
+                   nfe.printStackTrace(System.err);
+               }
+            }
+
+            booleanVal = getBooleanValue(params, DISABLE_AUDIO_PARAM, isSAI);
+            if(booleanVal != null) {
+                disableAudio = booleanVal;
+            }
+        }
+
+        if(browserSkin == null) {
+            loadBrowserSkin();
+        }
+        if(contentDirectory == null) {
+            contentDirectory = System.getProperty("user.dir");
+        }
+    }
+
+    /**
+     * Extract the specified parameter from the argument Map, qualify and return it.
+     *
+     * @param params The Map containing the parameters
+     * @param paramName The key of the parameter in the Map
+     * @param isSAI The 'qualification' switch
+     * @return The qualified parameter value, or null if it does not exist.
+     * @throws IllegalArgumentException if the parameter isSAI, and is not an instanceof Boolean.
+     */
+    private Boolean getBooleanValue(Map params, String paramName, boolean isSAI) {
+        Boolean booleanVal = null;
+        Object obj = params.get(paramName);
+        if(obj != null) {
+            if(isSAI) {
+                if(!(obj instanceof Boolean)) {
+                    throw new IllegalArgumentException("BrowserConfig: " + paramName + " must be a Boolean");
+                } else {
+                    booleanVal = (Boolean)obj;
+                }
+            } else {
+                booleanVal = Boolean.valueOf((String)obj);
+            }
+        }
+        return(booleanVal);
+    }
+
+    /**
+     * Extract the specified parameter from the argument Map, qualify and return it.
+     *
+     * @param params The Map containing the parameters
+     * @param paramName The key of the parameter in the Map
+     * @param isSAI The 'qualification' switch
+     * @return The qualified parameter value, or null if it does not exist.
+     * @throws IllegalArgumentException if the parameter isSAI, and is not an instanceof String.
+     */
+    private String getStringValue(Map params, String paramName, boolean isSAI) {
+        String stringVal = null;
+        Object obj = params.get(paramName);
+        if(obj != null) {
+            if(isSAI) {
+                if(!(obj instanceof String)) {
+                    throw new IllegalArgumentException("BrowserConfig: " + paramName + " must be a String");
+                }
+            }
+            stringVal = (String)obj;
+        }
+        return(stringVal);
+    }
+
+    /**
+     * Parse the strings from the parameter array and place them into a map
+     * so it is easy to look them up. Assumes the list is non-null.
+     *
+     * @param params The given parameter list
+     * @return a map of the parsed parameters
+     */
+    private Map<String, Object> parseParameters(String[] params) {
+        Map<String, Object> ret_val = new HashMap<>();
+
+        for(String param : params) {
+            if(param==null)
+                throw new IllegalArgumentException(NULL_PARAMETER_ERROR);
+            int index = param.indexOf('=');
+            if(index<1)
+                throw new IllegalArgumentException(MALFORMED_PARAMETER_STRING_ERROR);
+            ret_val.put(param.substring(0, index),
+                param.substring(index + 1));
+        }
+
+        return ret_val;
+    }
+
+    /**
+     * Load the browser skin properties. These properties are
+     * passed along to configure the appearance of the user
+     * interface components associated with the X3DComponent.
+     */
+    private void loadBrowserSkin() {
+        try {
+            browserSkin = AccessController.doPrivileged((PrivilegedExceptionAction<Properties>) () -> {
+                InputStream is;
+                Properties props = new Properties();
+                String search_path;
+                
+                String user_dirname = System.getProperty("user.dir");
+                String user_filename = user_dirname + File.separator + SKIN_PROPERTY_FILE;
+                // Using File.separator does not work for defLoc, not sure why
+                String default_filename = "config/common/" + SKIN_PROPERTY_FILE;
+                try {
+                    is = new FileInputStream(user_filename);
+                    search_path = user_filename;
+                } catch(FileNotFoundException fnfe) {
+                    // Fallback to default
+                    is = ClassLoader.getSystemClassLoader().getResourceAsStream(default_filename);
+                    search_path = default_filename;
+                }
+                
+                // Fallback for WebStart
+                if(is == null) {
+                    is = BrowserConfig.class.getClassLoader().getResourceAsStream(default_filename);
+                    search_path = default_filename;
+                }
+                
+                if(is == null) {
+                    System.out.println("Skin properties file: "+ search_path +" not found");
+                    System.out.println("Returning default properties.");
+                } else {
+                    try {
+                        props.load(is);
+                    } catch(IOException ioe) {
+                        System.err.println("Error reading skin properties file: "+ search_path +" "+ ioe.getMessage());
+                        System.err.println("Returning default properties.");
+                    } finally {
+                        try {
+                            is.close();
+                        } catch(IOException ioe) {}
+                    }
+                }
+                return(props);
+            });
+        } catch (PrivilegedActionException pae) {
+            System.err.println("Error getting skin properties");
+        }
+    }
+}
diff --git a/src/java/org/xj3d/sai/Xj3DAnchorListener.java b/src/java/org/xj3d/sai/Xj3DAnchorListener.java
index 61c7eb4f2b7cbac8c7f71de12623f8719d02e64e..08f23db163e30dd1c45b862a6119084ce1f96f76 100644
--- a/src/java/org/xj3d/sai/Xj3DAnchorListener.java
+++ b/src/java/org/xj3d/sai/Xj3DAnchorListener.java
@@ -21,6 +21,7 @@ package org.xj3d.sai;
 /**
  * Interception listener for anchor handling that allows an external user to
  * replace or supplement the browser's built in processing.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/xj3d/sai/Xj3DScreenCaptureListener.java b/src/java/org/xj3d/sai/Xj3DScreenCaptureListener.java
index 3e5a9318a2f7abf86f27fc01ae192d341793aeee..9bd41031f1afdc76ab952d96a0a12afcba623b2d 100644
--- a/src/java/org/xj3d/sai/Xj3DScreenCaptureListener.java
+++ b/src/java/org/xj3d/sai/Xj3DScreenCaptureListener.java
@@ -1,43 +1,43 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.sai;
-
-// External imports
-import java.awt.image.BufferedImage;
-
-// Local imports
-// None
-
-/**
- * Notification of Screen captures from the internals of Xj3D
- * <p>
- *
- * This is the callback that is registered with the {@link Xj3DBrowser} for
- * capturing screenshots. This will be called in a blocking fashion from the
- * browser. Time spent in this method will prevent the browser from executing
- * the next frame. In order to keep performance high end user code should
- * offload processing the values coming from this method to a separate thread.
- *
- * @author Justin Couch
- * @version $Revision: 1.2 $
- */
-public interface Xj3DScreenCaptureListener {
-
-    /**
-     * Notification of a new screen capture presented as an image. A new
-     * image instance will be generated for each frame.
-     *
-     * @param img The screen captured image
-     */
-    void screenCaptured(BufferedImage img);
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.sai;
+
+// External imports
+import java.awt.image.BufferedImage;
+
+// Local imports
+// None
+
+/**
+ * Notification of Screen captures from the internals of Xj3D
+ * <p>
+ *
+ * This is the callback that is registered with the {@link Xj3DBrowser} for
+ * capturing screenshots. This will be called in a blocking fashion from the
+ * browser. Time spent in this method will prevent the browser from executing
+ * the next frame. In order to keep performance high end user code should
+ * offload processing the values coming from this method to a separate thread.
+ *
+ * @author Justin Couch
+ * @version $Revision: 1.2 $
+ */
+public interface Xj3DScreenCaptureListener {
+
+    /**
+     * Notification of a new screen capture presented as an image. A new
+     * image instance will be generated for each frame.
+     *
+     * @param img The screen captured image
+     */
+    void screenCaptured(BufferedImage img);
+}
diff --git a/src/java/org/xj3d/ui/awt/browser/ogl/SampleChooser.java b/src/java/org/xj3d/ui/awt/browser/ogl/SampleChooser.java
index b0206dacb612b3cc91026d69eced0126482dad1e..72f004318c325ec3af98ef90bf22b4691b82d9d9 100644
--- a/src/java/org/xj3d/ui/awt/browser/ogl/SampleChooser.java
+++ b/src/java/org/xj3d/ui/awt/browser/ogl/SampleChooser.java
@@ -1,113 +1,113 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- *****************************************************************************/
-
-package org.xj3d.ui.awt.browser.ogl;
-
-// External imports
-import com.jogamp.opengl.*;
-import com.jogamp.opengl.GLProfile;
-
-import org.j3d.util.DefaultErrorReporter;
-import org.j3d.util.ErrorReporter;
-
-// Local imports
-// None
-
-/**
- * A sample chooser for selecting the right number of multisamples.
- *
- * @author Alan Hudson
- * @version $Revision: 1.1 $
- */
-class SampleChooser {
-
-    /** Message when we can't find a matching format for the capabilities */
-    private static final String NO_PIXEL_FORMATS_MSG =
-        "WARNING: antialiasing will be disabled because none of the " +
-        "available pixel formats had it to offer";
-
-    /** Message the caller didn't request antialiasing */
-    private static final String NO_AA_REQUEST_MSG =
-        "WARNING: antialiasing will be disabled because the " +
-        "DefaultGLCapabilitiesChooser didn't supply it";
-
-    /** The number of samples we've discovered */
-    private int maxSamples = -1;
-
-    private boolean anyHaveSampleBuffers = false;
-
-    /** Reporter instance for handing out errors */
-    private ErrorReporter errorReporter;
-
-    /**
-     * Construct a new, default instance of this class.
-     */
-    SampleChooser() {
-        errorReporter = DefaultErrorReporter.getDefaultReporter();
-
-        GLDrawableFactory fac = GLDrawableFactory.getFactory(GLProfile.getDefault());
-
-        GLCapabilities caps = new GLCapabilities(GLProfile.getDefault());
-        caps.setSampleBuffers(true);
-
-        // Set a max to compare with reality
-        caps.setNumSamples(16);
-
-        GLAutoDrawable ad = fac.createDummyAutoDrawable(fac.getDefaultDevice(), true, caps, new DefaultGLCapabilitiesChooser());
-        ad.display();
-        caps = (GLCapabilities) ad.getChosenGLCapabilities();
-
-        if (caps != null) {
-            if (caps.getNumSamples() > maxSamples) {
-                maxSamples = caps.getNumSamples();
-            }
-            anyHaveSampleBuffers = caps.getSampleBuffers();
-        }
-
-        if (maxSamples == -1) {
-            errorReporter.messageReport(NO_PIXEL_FORMATS_MSG);
-        } else {
-            if (!anyHaveSampleBuffers) {
-                errorReporter.messageReport(NO_AA_REQUEST_MSG);
-            }
-        }
-    }
-
-    //----------------------------------------------------------
-    // Local Methods
-    //----------------------------------------------------------
-
-    /**
-     * Register an error reporter with the engine so that any errors generated
-     * by the node's internals can be reported in a nice, pretty fashion.
-     * Setting a value of null will clear the currently set reporter. If one
-     * is already set, the new value replaces the old.
-     *
-     * @param reporter The instance to use or null
-     */
-    void setErrorReporter(ErrorReporter reporter) {
-        // Reset the default only if we are not shutting down the system.
-        if(reporter == null)
-            errorReporter = DefaultErrorReporter.getDefaultReporter();
-        else
-            errorReporter = reporter;
-    }
-
-    /**
-     * Ask for the number of samples detected. This is only valid after having
-     * been run. Otherwise, it will return a value of -1.
-     */
-    int getMaxSamples() {
-        return maxSamples;
-    }
-}
-
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2001 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ *****************************************************************************/
+
+package org.xj3d.ui.awt.browser.ogl;
+
+// External imports
+import com.jogamp.opengl.*;
+import com.jogamp.opengl.GLProfile;
+
+import org.j3d.util.DefaultErrorReporter;
+import org.j3d.util.ErrorReporter;
+
+// Local imports
+// None
+
+/**
+ * A sample chooser for selecting the right number of multisamples.
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.1 $
+ */
+class SampleChooser {
+
+    /** Message when we can't find a matching format for the capabilities */
+    private static final String NO_PIXEL_FORMATS_MSG =
+        "WARNING: antialiasing will be disabled because none of the " +
+        "available pixel formats had it to offer";
+
+    /** Message the caller didn't request antialiasing */
+    private static final String NO_AA_REQUEST_MSG =
+        "WARNING: antialiasing will be disabled because the " +
+        "DefaultGLCapabilitiesChooser didn't supply it";
+
+    /** The number of samples we've discovered */
+    private int maxSamples = -1;
+
+    private boolean anyHaveSampleBuffers = false;
+
+    /** Reporter instance for handing out errors */
+    private ErrorReporter errorReporter;
+
+    /**
+     * Construct a new, default instance of this class.
+     */
+    SampleChooser() {
+        errorReporter = DefaultErrorReporter.getDefaultReporter();
+
+        GLDrawableFactory fac = GLDrawableFactory.getFactory(GLProfile.getDefault());
+
+        GLCapabilities caps = new GLCapabilities(GLProfile.getDefault());
+        caps.setSampleBuffers(true);
+
+        // Set a max to compare with reality
+        caps.setNumSamples(16);
+
+        GLAutoDrawable ad = fac.createDummyAutoDrawable(fac.getDefaultDevice(), true, caps, new DefaultGLCapabilitiesChooser());
+        ad.display();
+        caps = (GLCapabilities) ad.getChosenGLCapabilities();
+
+        if (caps != null) {
+            if (caps.getNumSamples() > maxSamples) {
+                maxSamples = caps.getNumSamples();
+            }
+            anyHaveSampleBuffers = caps.getSampleBuffers();
+        }
+
+        if (maxSamples == -1) {
+            errorReporter.messageReport(NO_PIXEL_FORMATS_MSG);
+        } else {
+            if (!anyHaveSampleBuffers) {
+                errorReporter.messageReport(NO_AA_REQUEST_MSG);
+            }
+        }
+    }
+
+    //----------------------------------------------------------
+    // Local Methods
+    //----------------------------------------------------------
+
+    /**
+     * Register an error reporter with the engine so that any errors generated
+     * by the node's internals can be reported in a nice, pretty fashion.
+     * Setting a value of null will clear the currently set reporter. If one
+     * is already set, the new value replaces the old.
+     *
+     * @param reporter The instance to use or null
+     */
+    void setErrorReporter(ErrorReporter reporter) {
+        // Reset the default only if we are not shutting down the system.
+        if(reporter == null)
+            errorReporter = DefaultErrorReporter.getDefaultReporter();
+        else
+            errorReporter = reporter;
+    }
+
+    /**
+     * Ask for the number of samples detected. This is only valid after having
+     * been run. Otherwise, it will return a value of -1.
+     */
+    int getMaxSamples() {
+        return maxSamples;
+    }
+}
+
diff --git a/src/java/org/xj3d/ui/awt/browser/ogl/VRMLOGLBrowserFactoryImpl.java b/src/java/org/xj3d/ui/awt/browser/ogl/VRMLOGLBrowserFactoryImpl.java
index d5efe56f94984eb2f9e85b86738519f482e5df8f..054c33c145b35a8bd245b57eb7b9c4c1302d0eff 100644
--- a/src/java/org/xj3d/ui/awt/browser/ogl/VRMLOGLBrowserFactoryImpl.java
+++ b/src/java/org/xj3d/ui/awt/browser/ogl/VRMLOGLBrowserFactoryImpl.java
@@ -29,38 +29,32 @@ import vrml.eai.NoSuchBrowserException;
 import org.xj3d.sai.BrowserConfig;
 
 /**
- * <p>
  * An implementation of the EAI {@link vrml.eai.BrowserFactoryImpl} interface
  * that creates a browser that uses OpenGL for the renderer.
- * </p>
+ * <p>
  *
+ * <b>Supported Actions</b>
  * <p>
- * <b>Supported Actions</b>.
  *
  * Currently the factory implementation only supports creating a new component.
  * We do expect to add other support at a later date, such as fetching an
  * existing instance.
- * </p>
+ * <p>
  *
+ * <b>Component Creation</b>
  * <p>
- * <b>Component Creation</b>.
  *
  * This implementation allows you to create a new component that is ready to
  * place content in. Parameters can be supplied and are declared in the form
- * </p>
  * <pre>
  *   <i>param name</i>=<i>param value</i>
  * </pre>
- * <p>
  * There should be no whitespace either side of the equals sign.
- * </p>
- *
  * <p>
+ *
  * When creating a new browser component, the following parameters are
  * supported:
- * </p>
- * <table>
- * <caption>the following parameters are supported</caption>
+ * <table summary="the following parameters are supported">
  * <tr>
  *  <td><b>Parameter Name String</b></td>
  *  <td><b>Parameter Value String - Description</b></td>
diff --git a/src/java/org/xj3d/ui/awt/browser/ogl/X3DBrowserJPanel.java b/src/java/org/xj3d/ui/awt/browser/ogl/X3DBrowserJPanel.java
index cfe2b978fda29c53847f077d8e75fb483e01b84b..6cfac98f65f673db7a0be13addb7e81bde289921 100644
--- a/src/java/org/xj3d/ui/awt/browser/ogl/X3DBrowserJPanel.java
+++ b/src/java/org/xj3d/ui/awt/browser/ogl/X3DBrowserJPanel.java
@@ -50,6 +50,7 @@ import org.xj3d.sai.BrowserConfig;
 /**
  * Swing JPanel implementation that wraps the functionality of a X3D browser
  * into a convenient, easy to use form for the SAI.
+ * <p>
  *
  * @author Justin Couch, Brad Vender, Alan Hudson
  * @version $Revision: 1.10 $
diff --git a/src/java/org/xj3d/ui/awt/browser/ogl/X3DNRBrowserFactoryImpl.java b/src/java/org/xj3d/ui/awt/browser/ogl/X3DNRBrowserFactoryImpl.java
index edad5953efb7e94884ac548b5ca98691a8be2cae..f05d2e789685099875db3b2c11a413f457d407b6 100644
--- a/src/java/org/xj3d/ui/awt/browser/ogl/X3DNRBrowserFactoryImpl.java
+++ b/src/java/org/xj3d/ui/awt/browser/ogl/X3DNRBrowserFactoryImpl.java
@@ -60,19 +60,17 @@ import org.xj3d.impl.core.loading.MemCacheLoadManager;
 import org.xj3d.sai.BrowserConfig;
 
 /**
- * <p>
  * Factory implementation for X3D SAI which will produce components using
  * the Null renderer.
- * </p>
- * <p>
+ *
  * <b>Component Creation</b>
- * </p>
  * <p>
+ *
  * This implementation allows you to create a new component that is ready to
  * place content in. Parameters can be supplied in the Map as defined by
  * the SAI. The first column is the parameter name string, the second is
  * the type of data, and the third is an explanation.
- * </p>
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.7 $
diff --git a/src/java/org/xj3d/ui/awt/browser/ogl/X3DOGLBrowserFactoryImpl.java b/src/java/org/xj3d/ui/awt/browser/ogl/X3DOGLBrowserFactoryImpl.java
index 6fc20297fdf04b5d2f5144befce13a86a4aade01..7460641ee8bf675906b5cc1914edb032733f1077 100644
--- a/src/java/org/xj3d/ui/awt/browser/ogl/X3DOGLBrowserFactoryImpl.java
+++ b/src/java/org/xj3d/ui/awt/browser/ogl/X3DOGLBrowserFactoryImpl.java
@@ -32,23 +32,18 @@ import org.xj3d.sai.BrowserConfig;
 import org.xj3d.ui.awt.offscreen.browser.ogl.X3DOffscreenSurface;
 
 /**
- * <p>
  * Factory implementation for X3D SAI which will produce components using
  * the OpenGL renderer.
- * </p>
- *
  * <p>
+ *
  * This implementation allows you to create a new component that is ready to
  * place content in. Parameters can be supplied in the Map as defined by
  * the SAI.
- * </p>
- *
  * <p>
+ *
  * When creating a new browser component, the following parameters are
  * supported:
- * </p>
- * <table>
- * <caption>the following parameters are supported</caption>
+ * <table summary="the following parameters are supported">
  * <tr>
  *  <td><b>Parameter Name String</b></td>
  *  <td><b>Data Type</b></td>
diff --git a/src/java/org/xj3d/ui/awt/device/AWTDeviceFactory.java b/src/java/org/xj3d/ui/awt/device/AWTDeviceFactory.java
index 2299c8162421e260051328c9b8c0a67b7a327171..47336c184667989cedd7541dd9d5af9a0b9b2dd3 100644
--- a/src/java/org/xj3d/ui/awt/device/AWTDeviceFactory.java
+++ b/src/java/org/xj3d/ui/awt/device/AWTDeviceFactory.java
@@ -1,130 +1,130 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.ui.awt.device;
-
-// External imports
-import java.awt.Component;
-
-import java.awt.event.KeyListener;
-import java.awt.event.MouseListener;
-import java.awt.event.MouseMotionListener;
-import java.awt.event.MouseWheelListener;
-
-import java.util.List;
-
-import org.j3d.device.input.DeviceManager;
-import org.j3d.device.input.InputDevice;
-
-import org.j3d.util.DefaultErrorReporter;
-import org.j3d.util.ErrorReporter;
-
-// Local imports
-import org.web3d.browser.Xj3DConstants;
-
-import org.web3d.vrml.util.KeySensorDevice;
-
-import org.xj3d.core.eventmodel.DeviceFactory;
-
-/**
- * A concrete implementation of DeviceFactory that is
- * specific to the AWT UI toolkit. Devices created through
- * this factory are initialized with the appropriate AWT
- * event listeners.
- *
- * @author Rex Melton
- * @version $Revision: 1.8 $
- */
-public class AWTDeviceFactory extends DeviceFactory {
-
-    /**
-     * Constructor.
-     *
-     * @param canvas - The Object representing the ui toolkit
-     * specific graphical component. Must be an instance of
-     * java.awt.Component.
-     * @param rendererID - Identifier String of the renderer type.
-     * @param surface - The Object representing the renderer
-     * specific drawing surface.
-     * @throws IllegalArgumentException if the canvas Object is not
-     * an instance of java.awt.Component.
-     * @param reporter - The instance to use or null. A value of null
-     * will clear the currently set reporter and causes the factory
-     * to use the DefaultErrorReporter.
-     */
-    public AWTDeviceFactory( Object canvas, String rendererID,
-        Object surface, ErrorReporter reporter ) {
-        if ( !( canvas instanceof Component ) ) {
-            throw new IllegalArgumentException(
-                "canvas object is not a subclass of java.awt.Component" );
-        }
-        errorReporter = ( reporter == null ) ?
-            DefaultErrorReporter.getDefaultReporter( ) : reporter;
-
-        toolkitID = Xj3DConstants.AWT_ID;
-
-        this.canvas = canvas;
-        // do we want to check the rendererID ?
-        this.rendererID = rendererID;
-        // can we check the surface ? what's valid ?
-        this.surface = surface;
-    }
-
-    /**
-     * Return the array of DeviceManagers that are available per the
-     * constructor parameters. The InputDevices instantiated will be
-     * initialized with the AWT ui toolkit event listeners.
-     *
-     * @return the array of DeviceManagers. If no DeviceManagers are
-     * available, an empty (size 0) array is returned.
-     */
-    @Override
-    public DeviceManager[] getDeviceManagers( ) {
-        List<Object> managerList = createDevices( );
-        DeviceManager[] manager =
-            managerList.toArray( new DeviceManager[managerList.size( )] );
-        Component cmp = (Component)canvas;
-        for (DeviceManager manager1 : manager) {
-            InputDevice[] device = manager1.getDevices();
-            for (InputDevice dev : device) {
-                if( dev instanceof MouseListener ) {
-                    cmp.addMouseListener( (MouseListener)dev );
-                }
-                if( dev instanceof MouseMotionListener ) {
-                    cmp.addMouseMotionListener( (MouseMotionListener)dev );
-                }
-                if( dev instanceof MouseWheelListener ) {
-                    cmp.addMouseWheelListener( (MouseWheelListener)dev );
-                }
-                if( dev instanceof KeyListener ) {
-                    cmp.addKeyListener( (KeyListener)dev );
-                }
-            }
-        }
-        return( manager );
-    }
-
-    /**
-     * Return the KeySensorDevice associated with the rendering surface
-     * initialized with the AWT key event listener.
-     *
-     * @return the KeySensorDevice
-     */
-    @Override
-    public KeySensorDevice getKeySensorDevice( ) {
-        AWTKeySensorDevice keyDevice = new AWTKeySensorDevice( );
-        Component cmp = (Component)canvas;
-        cmp.addKeyListener( keyDevice );
-        return( keyDevice );
-    }
-}
-
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.ui.awt.device;
+
+// External imports
+import java.awt.Component;
+
+import java.awt.event.KeyListener;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.event.MouseWheelListener;
+
+import java.util.List;
+
+import org.j3d.device.input.DeviceManager;
+import org.j3d.device.input.InputDevice;
+
+import org.j3d.util.DefaultErrorReporter;
+import org.j3d.util.ErrorReporter;
+
+// Local imports
+import org.web3d.browser.Xj3DConstants;
+
+import org.web3d.vrml.util.KeySensorDevice;
+
+import org.xj3d.core.eventmodel.DeviceFactory;
+
+/**
+ * A concrete implementation of DeviceFactory that is
+ * specific to the AWT UI toolkit. Devices created through
+ * this factory are initialized with the appropriate AWT
+ * event listeners.
+ *
+ * @author Rex Melton
+ * @version $Revision: 1.8 $
+ */
+public class AWTDeviceFactory extends DeviceFactory {
+
+    /**
+     * Constructor.
+     *
+     * @param canvas - The Object representing the ui toolkit
+     * specific graphical component. Must be an instance of
+     * java.awt.Component.
+     * @param rendererID - Identifier String of the renderer type.
+     * @param surface - The Object representing the renderer
+     * specific drawing surface.
+     * @throws IllegalArgumentException if the canvas Object is not
+     * an instance of java.awt.Component.
+     * @param reporter - The instance to use or null. A value of null
+     * will clear the currently set reporter and causes the factory
+     * to use the DefaultErrorReporter.
+     */
+    public AWTDeviceFactory( Object canvas, String rendererID,
+        Object surface, ErrorReporter reporter ) {
+        if ( !( canvas instanceof Component ) ) {
+            throw new IllegalArgumentException(
+                "canvas object is not a subclass of java.awt.Component" );
+        }
+        errorReporter = ( reporter == null ) ?
+            DefaultErrorReporter.getDefaultReporter( ) : reporter;
+
+        toolkitID = Xj3DConstants.AWT_ID;
+
+        this.canvas = canvas;
+        // do we want to check the rendererID ?
+        this.rendererID = rendererID;
+        // can we check the surface ? what's valid ?
+        this.surface = surface;
+    }
+
+    /**
+     * Return the array of DeviceManagers that are available per the
+     * constructor parameters. The InputDevices instantiated will be
+     * initialized with the AWT ui toolkit event listeners.
+     *
+     * @return the array of DeviceManagers. If no DeviceManagers are
+     * available, an empty (size 0) array is returned.
+     */
+    @Override
+    public DeviceManager[] getDeviceManagers( ) {
+        List<Object> managerList = createDevices( );
+        DeviceManager[] manager =
+            managerList.toArray( new DeviceManager[managerList.size( )] );
+        Component cmp = (Component)canvas;
+        for (DeviceManager manager1 : manager) {
+            InputDevice[] device = manager1.getDevices();
+            for (InputDevice dev : device) {
+                if( dev instanceof MouseListener ) {
+                    cmp.addMouseListener( (MouseListener)dev );
+                }
+                if( dev instanceof MouseMotionListener ) {
+                    cmp.addMouseMotionListener( (MouseMotionListener)dev );
+                }
+                if( dev instanceof MouseWheelListener ) {
+                    cmp.addMouseWheelListener( (MouseWheelListener)dev );
+                }
+                if( dev instanceof KeyListener ) {
+                    cmp.addKeyListener( (KeyListener)dev );
+                }
+            }
+        }
+        return( manager );
+    }
+
+    /**
+     * Return the KeySensorDevice associated with the rendering surface
+     * initialized with the AWT key event listener.
+     *
+     * @return the KeySensorDevice
+     */
+    @Override
+    public KeySensorDevice getKeySensorDevice( ) {
+        AWTKeySensorDevice keyDevice = new AWTKeySensorDevice( );
+        Component cmp = (Component)canvas;
+        cmp.addKeyListener( keyDevice );
+        return( keyDevice );
+    }
+}
+
diff --git a/src/java/org/xj3d/ui/awt/device/AWTKeySensorDevice.java b/src/java/org/xj3d/ui/awt/device/AWTKeySensorDevice.java
index be67e0635d3d4ae064c1a70a32769ce4c86ec037..479b6bc4e268c1f2d37592b94a1ba83eed2e3460 100644
--- a/src/java/org/xj3d/ui/awt/device/AWTKeySensorDevice.java
+++ b/src/java/org/xj3d/ui/awt/device/AWTKeySensorDevice.java
@@ -1,217 +1,217 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.ui.awt.device;
-
-// External imports - NONE
-import java.awt.event.KeyEvent;
-import java.awt.event.KeyListener;
-
-import org.web3d.vrml.util.KeySensorDevice;
-import org.web3d.vrml.util.KeySequence;
-import org.web3d.vrml.util.Xj3DKeyCode;
-import org.web3d.vrml.util.Xj3DKeyEvent;
-
-// Local imports - NONE
-
-
-/**
- * Implementation of a KeySensorDevice to gather and adapt the key events
- * for an AWT specific rendering component.
- *
- * @author Rex Melton
- * @version $Revision: 1.1 $
- */
-public class AWTKeySensorDevice implements KeySensorDevice, KeyListener {
-
-    /** The array of character key codes - of interest. Arranged in a one
-     *  dimensional array of awt, x3d pairs */
-    private static int[] charKeyCode = {
-        KeyEvent.VK_ENTER, Xj3DKeyCode.CHAR_KEY_ENTER,
-        KeyEvent.VK_BACK_SPACE, Xj3DKeyCode.CHAR_KEY_BACKSPACE,
-    };
-
-    /** The array of control key codes - of interest. Arranged in a one
-     *  dimensional array of awt, x3d pairs */
-    private static int[] controlKeyCode = {
-        KeyEvent.VK_F1, Xj3DKeyCode.ACTION_KEY_F1,
-        KeyEvent.VK_F2, Xj3DKeyCode.ACTION_KEY_F2,
-        KeyEvent.VK_F3, Xj3DKeyCode.ACTION_KEY_F3,
-        KeyEvent.VK_F4, Xj3DKeyCode.ACTION_KEY_F4,
-        KeyEvent.VK_F5, Xj3DKeyCode.ACTION_KEY_F5,
-        KeyEvent.VK_F6, Xj3DKeyCode.ACTION_KEY_F6,
-        KeyEvent.VK_F7, Xj3DKeyCode.ACTION_KEY_F7,
-        KeyEvent.VK_F8, Xj3DKeyCode.ACTION_KEY_F8,
-        KeyEvent.VK_F9, Xj3DKeyCode.ACTION_KEY_F9,
-        KeyEvent.VK_F10, Xj3DKeyCode.ACTION_KEY_F10,
-        KeyEvent.VK_F11, Xj3DKeyCode.ACTION_KEY_F11,
-        KeyEvent.VK_F12, Xj3DKeyCode.ACTION_KEY_F12,
-        KeyEvent.VK_HOME, Xj3DKeyCode.ACTION_KEY_HOME,
-        KeyEvent.VK_END, Xj3DKeyCode.ACTION_KEY_END,
-        KeyEvent.VK_PAGE_UP, Xj3DKeyCode.ACTION_KEY_PGUP,
-        KeyEvent.VK_PAGE_DOWN, Xj3DKeyCode.ACTION_KEY_PGDN,
-        KeyEvent.VK_UP, Xj3DKeyCode.ACTION_KEY_UP,
-        KeyEvent.VK_DOWN, Xj3DKeyCode.ACTION_KEY_DOWN,
-        KeyEvent.VK_LEFT, Xj3DKeyCode.ACTION_KEY_LEFT,
-        KeyEvent.VK_RIGHT, Xj3DKeyCode.ACTION_KEY_RIGHT,
-        KeyEvent.VK_ALT, Xj3DKeyCode.MODIFIER_KEY_ALT,
-        KeyEvent.VK_CONTROL, Xj3DKeyCode.MODIFIER_KEY_CONTROL,
-        KeyEvent.VK_SHIFT, Xj3DKeyCode.MODIFIER_KEY_SHIFT,
-    };
-
-    /** The ordered list of key events once they have been adapted
-     *  from awt to Xj3D format */
-    private KeySequence keySequence;
-
-    /**
-     * Constructor
-     */
-    public AWTKeySensorDevice( ) {
-        keySequence = new KeySequence( );
-    }
-
-    //------------------------------------------------------------------------
-    // Methods for KeyDevice
-    //------------------------------------------------------------------------
-
-    /**
-     * Return the ordered set of key events in the argument KeySequence
-     * object that have occurred since the previous call to this method.
-     *
-     * @param seq - The KeySequence object to initialize with the set
-     * of key events
-     */
-    @Override
-    public void getEvents( KeySequence seq ) {
-        keySequence.transfer( seq );
-    }
-
-    //------------------------------------------------------------------------
-    // Methods for KeyListener events
-    //------------------------------------------------------------------------
-
-    /**
-     * Process a key press event.
-     *
-     * @param evt The event that caused this method to be called
-     */
-    @Override
-    public void keyPressed( KeyEvent evt ) {
-        int awtKeyCode = evt.getKeyCode( );
-        char character = evt.getKeyChar( );
-        Object src = evt.getSource( );
-        if ( character != KeyEvent.CHAR_UNDEFINED ) {
-            // there is a character
-            int x3dKeyCode = getCharKeyCode( awtKeyCode );
-            keySequence.add( new Xj3DKeyEvent(
-                src,
-                Xj3DKeyEvent.KEY_PRESSED,
-                character,
-                x3dKeyCode ) );
-        }
-        else {
-            // no character, must be a control key
-            int x3dKeyCode = getControlKeyCode( awtKeyCode );
-            keySequence.add( new Xj3DKeyEvent(
-                src,
-                Xj3DKeyEvent.KEY_PRESSED,
-                Xj3DKeyEvent.CHAR_UNDEFINED,
-                x3dKeyCode ) );
-        }
-    }
-
-    /**
-     * Process a key release event.
-     *
-     * @param evt The event that caused this method to be called
-     */
-    @Override
-    public void keyReleased( KeyEvent evt ) {
-        int awtKeyCode = evt.getKeyCode( );
-        char character = evt.getKeyChar( );
-        Object src = evt.getSource( );
-        if ( character != KeyEvent.CHAR_UNDEFINED ) {
-            // there is a character
-            int x3dKeyCode = getCharKeyCode( awtKeyCode );
-            keySequence.add( new Xj3DKeyEvent(
-                src,
-                Xj3DKeyEvent.KEY_RELEASED,
-                character,
-                x3dKeyCode ) );
-        }
-        else {
-            // no character, must be a control key
-            int x3dKeyCode = getControlKeyCode( awtKeyCode );
-            keySequence.add( new Xj3DKeyEvent(
-                src,
-                Xj3DKeyEvent.KEY_RELEASED,
-                Xj3DKeyEvent.CHAR_UNDEFINED,
-                x3dKeyCode ) );
-        }
-    }
-
-    /**
-     * Process a key typed event.
-     *
-     * @param evt The event that caused this method to be called
-     */
-    @Override
-    public void keyTyped( KeyEvent evt ) {
-    }
-
-
-    //------------------------------------------------------------------------
-    // Local Methods
-    //------------------------------------------------------------------------
-
-    /**
-     * Return the Xj3DKeyCode that corresponds to the argument AWT
-     * key code. Note that for characters, the only key codes of
-     * interest are enter and backspace.
-     *
-     * @param awtKeyCode the AWT key code for a character key
-     * @return the corresponding Xj3DKeyCode if a match is found in
-     * the defined set of character key codes, otherwise return
-     * Xj3DKeyCode.KEY_CODE_UNDEFINED
-     */
-    private static int getCharKeyCode( int awtKeyCode ) {
-        int x3dKeyCode = Xj3DKeyCode.KEY_CODE_UNDEFINED;
-        for ( int i = charKeyCode.length - 2; i >= 0; i-=2 ) {
-            if ( awtKeyCode == charKeyCode[i] ) {
-                x3dKeyCode = charKeyCode[i+1];
-                break;
-            }
-        }
-        return( x3dKeyCode );
-    }
-
-    /**
-     * Return the Xj3DKeyCode that corresponds to the argument AWT
-     * key code of a non-character key.
-     *
-     * @param awtKeyCode the AWT key code for the control key
-     * @return the corresponding Xj3DKeyCode if a match is found in
-     * the defined set of control key codes, otherwise return
-     * Xj3DKeyCode.KEY_CODE_UNDEFINED
-     */
-    private static int getControlKeyCode( int awtKeyCode ) {
-        int x3dKeyCode = Xj3DKeyCode.KEY_CODE_UNDEFINED;
-        for ( int i = controlKeyCode.length - 2; i >= 0; i-=2 ) {
-            if ( awtKeyCode == controlKeyCode[i] ) {
-                x3dKeyCode = controlKeyCode[i+1];
-                break;
-            }
-        }
-        return( x3dKeyCode );
-    }
-}
-
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.ui.awt.device;
+
+// External imports - NONE
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+
+import org.web3d.vrml.util.KeySensorDevice;
+import org.web3d.vrml.util.KeySequence;
+import org.web3d.vrml.util.Xj3DKeyCode;
+import org.web3d.vrml.util.Xj3DKeyEvent;
+
+// Local imports - NONE
+
+
+/**
+ * Implementation of a KeySensorDevice to gather and adapt the key events
+ * for an AWT specific rendering component.
+ *
+ * @author Rex Melton
+ * @version $Revision: 1.1 $
+ */
+public class AWTKeySensorDevice implements KeySensorDevice, KeyListener {
+
+    /** The array of character key codes - of interest. Arranged in a one
+     *  dimensional array of awt, x3d pairs */
+    private static int[] charKeyCode = {
+        KeyEvent.VK_ENTER, Xj3DKeyCode.CHAR_KEY_ENTER,
+        KeyEvent.VK_BACK_SPACE, Xj3DKeyCode.CHAR_KEY_BACKSPACE,
+    };
+
+    /** The array of control key codes - of interest. Arranged in a one
+     *  dimensional array of awt, x3d pairs */
+    private static int[] controlKeyCode = {
+        KeyEvent.VK_F1, Xj3DKeyCode.ACTION_KEY_F1,
+        KeyEvent.VK_F2, Xj3DKeyCode.ACTION_KEY_F2,
+        KeyEvent.VK_F3, Xj3DKeyCode.ACTION_KEY_F3,
+        KeyEvent.VK_F4, Xj3DKeyCode.ACTION_KEY_F4,
+        KeyEvent.VK_F5, Xj3DKeyCode.ACTION_KEY_F5,
+        KeyEvent.VK_F6, Xj3DKeyCode.ACTION_KEY_F6,
+        KeyEvent.VK_F7, Xj3DKeyCode.ACTION_KEY_F7,
+        KeyEvent.VK_F8, Xj3DKeyCode.ACTION_KEY_F8,
+        KeyEvent.VK_F9, Xj3DKeyCode.ACTION_KEY_F9,
+        KeyEvent.VK_F10, Xj3DKeyCode.ACTION_KEY_F10,
+        KeyEvent.VK_F11, Xj3DKeyCode.ACTION_KEY_F11,
+        KeyEvent.VK_F12, Xj3DKeyCode.ACTION_KEY_F12,
+        KeyEvent.VK_HOME, Xj3DKeyCode.ACTION_KEY_HOME,
+        KeyEvent.VK_END, Xj3DKeyCode.ACTION_KEY_END,
+        KeyEvent.VK_PAGE_UP, Xj3DKeyCode.ACTION_KEY_PGUP,
+        KeyEvent.VK_PAGE_DOWN, Xj3DKeyCode.ACTION_KEY_PGDN,
+        KeyEvent.VK_UP, Xj3DKeyCode.ACTION_KEY_UP,
+        KeyEvent.VK_DOWN, Xj3DKeyCode.ACTION_KEY_DOWN,
+        KeyEvent.VK_LEFT, Xj3DKeyCode.ACTION_KEY_LEFT,
+        KeyEvent.VK_RIGHT, Xj3DKeyCode.ACTION_KEY_RIGHT,
+        KeyEvent.VK_ALT, Xj3DKeyCode.MODIFIER_KEY_ALT,
+        KeyEvent.VK_CONTROL, Xj3DKeyCode.MODIFIER_KEY_CONTROL,
+        KeyEvent.VK_SHIFT, Xj3DKeyCode.MODIFIER_KEY_SHIFT,
+    };
+
+    /** The ordered list of key events once they have been adapted
+     *  from awt to Xj3D format */
+    private KeySequence keySequence;
+
+    /**
+     * Constructor
+     */
+    public AWTKeySensorDevice( ) {
+        keySequence = new KeySequence( );
+    }
+
+    //------------------------------------------------------------------------
+    // Methods for KeyDevice
+    //------------------------------------------------------------------------
+
+    /**
+     * Return the ordered set of key events in the argument KeySequence
+     * object that have occurred since the previous call to this method.
+     *
+     * @param seq - The KeySequence object to initialize with the set
+     * of key events
+     */
+    @Override
+    public void getEvents( KeySequence seq ) {
+        keySequence.transfer( seq );
+    }
+
+    //------------------------------------------------------------------------
+    // Methods for KeyListener events
+    //------------------------------------------------------------------------
+
+    /**
+     * Process a key press event.
+     *
+     * @param evt The event that caused this method to be called
+     */
+    @Override
+    public void keyPressed( KeyEvent evt ) {
+        int awtKeyCode = evt.getKeyCode( );
+        char character = evt.getKeyChar( );
+        Object src = evt.getSource( );
+        if ( character != KeyEvent.CHAR_UNDEFINED ) {
+            // there is a character
+            int x3dKeyCode = getCharKeyCode( awtKeyCode );
+            keySequence.add( new Xj3DKeyEvent(
+                src,
+                Xj3DKeyEvent.KEY_PRESSED,
+                character,
+                x3dKeyCode ) );
+        }
+        else {
+            // no character, must be a control key
+            int x3dKeyCode = getControlKeyCode( awtKeyCode );
+            keySequence.add( new Xj3DKeyEvent(
+                src,
+                Xj3DKeyEvent.KEY_PRESSED,
+                Xj3DKeyEvent.CHAR_UNDEFINED,
+                x3dKeyCode ) );
+        }
+    }
+
+    /**
+     * Process a key release event.
+     *
+     * @param evt The event that caused this method to be called
+     */
+    @Override
+    public void keyReleased( KeyEvent evt ) {
+        int awtKeyCode = evt.getKeyCode( );
+        char character = evt.getKeyChar( );
+        Object src = evt.getSource( );
+        if ( character != KeyEvent.CHAR_UNDEFINED ) {
+            // there is a character
+            int x3dKeyCode = getCharKeyCode( awtKeyCode );
+            keySequence.add( new Xj3DKeyEvent(
+                src,
+                Xj3DKeyEvent.KEY_RELEASED,
+                character,
+                x3dKeyCode ) );
+        }
+        else {
+            // no character, must be a control key
+            int x3dKeyCode = getControlKeyCode( awtKeyCode );
+            keySequence.add( new Xj3DKeyEvent(
+                src,
+                Xj3DKeyEvent.KEY_RELEASED,
+                Xj3DKeyEvent.CHAR_UNDEFINED,
+                x3dKeyCode ) );
+        }
+    }
+
+    /**
+     * Process a key typed event.
+     *
+     * @param evt The event that caused this method to be called
+     */
+    @Override
+    public void keyTyped( KeyEvent evt ) {
+    }
+
+
+    //------------------------------------------------------------------------
+    // Local Methods
+    //------------------------------------------------------------------------
+
+    /**
+     * Return the Xj3DKeyCode that corresponds to the argument AWT
+     * key code. Note that for characters, the only key codes of
+     * interest are enter and backspace.
+     *
+     * @param awtKeyCode the AWT key code for a character key
+     * @return the corresponding Xj3DKeyCode if a match is found in
+     * the defined set of character key codes, otherwise return
+     * Xj3DKeyCode.KEY_CODE_UNDEFINED
+     */
+    private static int getCharKeyCode( int awtKeyCode ) {
+        int x3dKeyCode = Xj3DKeyCode.KEY_CODE_UNDEFINED;
+        for ( int i = charKeyCode.length - 2; i >= 0; i-=2 ) {
+            if ( awtKeyCode == charKeyCode[i] ) {
+                x3dKeyCode = charKeyCode[i+1];
+                break;
+            }
+        }
+        return( x3dKeyCode );
+    }
+
+    /**
+     * Return the Xj3DKeyCode that corresponds to the argument AWT
+     * key code of a non-character key.
+     *
+     * @param awtKeyCode the AWT key code for the control key
+     * @return the corresponding Xj3DKeyCode if a match is found in
+     * the defined set of control key codes, otherwise return
+     * Xj3DKeyCode.KEY_CODE_UNDEFINED
+     */
+    private static int getControlKeyCode( int awtKeyCode ) {
+        int x3dKeyCode = Xj3DKeyCode.KEY_CODE_UNDEFINED;
+        for ( int i = controlKeyCode.length - 2; i >= 0; i-=2 ) {
+            if ( awtKeyCode == controlKeyCode[i] ) {
+                x3dKeyCode = controlKeyCode[i+1];
+                break;
+            }
+        }
+        return( x3dKeyCode );
+    }
+}
+
diff --git a/src/java/org/xj3d/ui/awt/offscreen/browser/ogl/X3DOffscreenSurface.java b/src/java/org/xj3d/ui/awt/offscreen/browser/ogl/X3DOffscreenSurface.java
index 35ce7403144c79a742dcc987f1a5a76e8af7c546..07c06fa98a6d6c768137520917f7ff7bf3ee4540 100644
--- a/src/java/org/xj3d/ui/awt/offscreen/browser/ogl/X3DOffscreenSurface.java
+++ b/src/java/org/xj3d/ui/awt/offscreen/browser/ogl/X3DOffscreenSurface.java
@@ -57,6 +57,7 @@ import org.xj3d.ui.awt.net.content.AWTContentHandlerFactory;
 /**
  * Swing JPanel implementation that wraps the functionality of a X3D browser
  * into a convenient, easy to use form for the SAI.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.4 $
diff --git a/src/java/org/xj3d/ui/awt/widgets/AWTProgressListener.java b/src/java/org/xj3d/ui/awt/widgets/AWTProgressListener.java
index a5f4400fed60148cf2bb21c1a61af639bc595e13..292498618991b290a19e1549f951e24800a0518f 100644
--- a/src/java/org/xj3d/ui/awt/widgets/AWTProgressListener.java
+++ b/src/java/org/xj3d/ui/awt/widgets/AWTProgressListener.java
@@ -1,137 +1,138 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2003 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.ui.awt.widgets;
-
-// External imports
-import java.awt.Label;
-
-import org.ietf.uri.ResourceConnection;
-import org.ietf.uri.URI;
-import org.ietf.uri.event.ProgressEvent;
-import org.ietf.uri.event.ProgressListener;
-
-// Local imports
-import org.j3d.util.ErrorReporter;
-
-/**
- * An implementation of the URI progress listener for putting messages to
- * a status label.
- *
- * @author  Justin Couch
- * @version $Revision: 1.1 $
- */
-public class AWTProgressListener implements ProgressListener
-{
-    /** The status label to put transient messages on */
-    private Label statusLabel;
-
-    /** Error handler for more serious messages */
-    private ErrorReporter reporter;
-
-    /**
-     * Create a new listener that puts information in these different places.
-     * Assumes that both references are non-null.
-     *
-     * @param status The status label to write to
-     * @param rep The place for error messages
-     */
-    public AWTProgressListener(Label status, ErrorReporter rep) {
-        statusLabel = status;
-        reporter = rep;
-    }
-
-    //---------------------------------------------------------------
-    // Methods defined by ProgressListener
-    //---------------------------------------------------------------
-
-    /**
-     * A connection to the resource has been established. At this point, no data
-     * has yet been downloaded.
-     *
-     * @param evt The event that caused this method to be called.
-     */
-    @Override
-    public void connectionEstablished(ProgressEvent evt) {
-        statusLabel.setText(evt.getMessage());
-    }
-
-    /**
-     * The header information reading and handshaking is taking place. Reading
-     * and interpreting of the data (a download started event) should commence
-     * shortly. When that begins, you will be given the appropriate event.
-     *
-     * @param evt The event that caused this method to be called.
-     */
-    @Override
-    public void handshakeInProgress(ProgressEvent evt) {
-        statusLabel.setText(evt.getMessage());
-    }
-
-    /**
-     * The download has started.
-     *
-     * @param evt The event that caused this method to be called.
-     */
-    @Override
-    public void downloadStarted(ProgressEvent evt) {
-        statusLabel.setText(evt.getMessage());
-    }
-
-    /**
-     * The download has updated its status.
-     *
-     * @param evt The event that caused this method to be called.
-     */
-    @Override
-    public void downloadUpdate(ProgressEvent evt) {
-        ResourceConnection conn = evt.getSource();
-        URI uri = conn.getURI();
-
-        StringBuilder buf = new StringBuilder(uri.toExternalForm());
-        buf.append(" (");
-        buf.append(evt.getValue());
-        buf.append(")");
-
-        statusLabel.setText(buf.toString());
-    }
-
-    /**
-     * The download has ended.
-     *
-     * @param evt The event that caused this method to be called.
-     */
-    @Override
-    public void downloadEnded(ProgressEvent evt) {
-        ResourceConnection conn = evt.getSource();
-        URI uri = conn.getURI();
-        String msg = uri.toExternalForm() + " download complete.";
-/*
-        String msg2 = evt.getMessage();
-        if (msg2 != null)
-            msg = msg + msg2;
-*/
-        statusLabel.setText(msg);
-        reporter.messageReport(msg);
-    }
-
-    /**
-     * An error has occurred during the download.
-     *
-     * @param evt The event that caused this method to be called.
-     */
-    @Override
-    public void downloadError(ProgressEvent evt) {
-        statusLabel.setText(evt.getMessage());
-        reporter.errorReport(evt.getMessage(), null);
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2003 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.ui.awt.widgets;
+
+// External imports
+import java.awt.Label;
+
+import org.ietf.uri.ResourceConnection;
+import org.ietf.uri.URI;
+import org.ietf.uri.event.ProgressEvent;
+import org.ietf.uri.event.ProgressListener;
+
+// Local imports
+import org.j3d.util.ErrorReporter;
+
+/**
+ * An implementation of the URI progress listener for putting messages to
+ * a status label.
+ *  <p>
+ *
+ * @author  Justin Couch
+ * @version $Revision: 1.1 $
+ */
+public class AWTProgressListener implements ProgressListener
+{
+    /** The status label to put transient messages on */
+    private Label statusLabel;
+
+    /** Error handler for more serious messages */
+    private ErrorReporter reporter;
+
+    /**
+     * Create a new listener that puts information in these different places.
+     * Assumes that both references are non-null.
+     *
+     * @param status The status label to write to
+     * @param rep The place for error messages
+     */
+    public AWTProgressListener(Label status, ErrorReporter rep) {
+        statusLabel = status;
+        reporter = rep;
+    }
+
+    //---------------------------------------------------------------
+    // Methods defined by ProgressListener
+    //---------------------------------------------------------------
+
+    /**
+     * A connection to the resource has been established. At this point, no data
+     * has yet been downloaded.
+     *
+     * @param evt The event that caused this method to be called.
+     */
+    @Override
+    public void connectionEstablished(ProgressEvent evt) {
+        statusLabel.setText(evt.getMessage());
+    }
+
+    /**
+     * The header information reading and handshaking is taking place. Reading
+     * and interpreting of the data (a download started event) should commence
+     * shortly. When that begins, you will be given the appropriate event.
+     *
+     * @param evt The event that caused this method to be called.
+     */
+    @Override
+    public void handshakeInProgress(ProgressEvent evt) {
+        statusLabel.setText(evt.getMessage());
+    }
+
+    /**
+     * The download has started.
+     *
+     * @param evt The event that caused this method to be called.
+     */
+    @Override
+    public void downloadStarted(ProgressEvent evt) {
+        statusLabel.setText(evt.getMessage());
+    }
+
+    /**
+     * The download has updated its status.
+     *
+     * @param evt The event that caused this method to be called.
+     */
+    @Override
+    public void downloadUpdate(ProgressEvent evt) {
+        ResourceConnection conn = evt.getSource();
+        URI uri = conn.getURI();
+
+        StringBuilder buf = new StringBuilder(uri.toExternalForm());
+        buf.append(" (");
+        buf.append(evt.getValue());
+        buf.append(")");
+
+        statusLabel.setText(buf.toString());
+    }
+
+    /**
+     * The download has ended.
+     *
+     * @param evt The event that caused this method to be called.
+     */
+    @Override
+    public void downloadEnded(ProgressEvent evt) {
+        ResourceConnection conn = evt.getSource();
+        URI uri = conn.getURI();
+        String msg = uri.toExternalForm() + " download complete.";
+/*
+        String msg2 = evt.getMessage();
+        if (msg2 != null)
+            msg = msg + msg2;
+*/
+        statusLabel.setText(msg);
+        reporter.messageReport(msg);
+    }
+
+    /**
+     * An error has occurred during the download.
+     *
+     * @param evt The event that caused this method to be called.
+     */
+    @Override
+    public void downloadError(ProgressEvent evt) {
+        statusLabel.setText(evt.getMessage());
+        reporter.errorReport(evt.getMessage(), null);
+    }
+}
diff --git a/src/java/org/xj3d/ui/awt/widgets/CursorManager.java b/src/java/org/xj3d/ui/awt/widgets/CursorManager.java
index cd9c791b51acac8ec612792b296e57b97c86d6d2..62820ec18deedff021bf22843520c99a6a67daf2 100644
--- a/src/java/org/xj3d/ui/awt/widgets/CursorManager.java
+++ b/src/java/org/xj3d/ui/awt/widgets/CursorManager.java
@@ -48,6 +48,7 @@ import org.xj3d.core.eventmodel.CursorFilter;
  * Properties object are given predefined values.  The
  * predefined values not used in the event of error loading
  * user supplied values.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.10 $
diff --git a/src/java/org/xj3d/ui/awt/widgets/FitWorldAction.java b/src/java/org/xj3d/ui/awt/widgets/FitWorldAction.java
index 637293a566232c7206666dfe5bd60ab6ceec2f44..25e21f53d8d543322806fb198ab5a5c2dd5c7e7f 100644
--- a/src/java/org/xj3d/ui/awt/widgets/FitWorldAction.java
+++ b/src/java/org/xj3d/ui/awt/widgets/FitWorldAction.java
@@ -25,6 +25,7 @@ import org.web3d.browser.BrowserCore;
 
 /**
  * An action that moves to the viewpoint to look at the whole world.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.4 $
diff --git a/src/java/org/xj3d/ui/awt/widgets/HomeViewpointAction.java b/src/java/org/xj3d/ui/awt/widgets/HomeViewpointAction.java
index a16293fdc646a9c29e79c02b7db164167e5e7357..8eedea147c3404b0e32228c037b8559f8585fd94 100644
--- a/src/java/org/xj3d/ui/awt/widgets/HomeViewpointAction.java
+++ b/src/java/org/xj3d/ui/awt/widgets/HomeViewpointAction.java
@@ -25,6 +25,7 @@ import org.xj3d.core.eventmodel.ViewpointManager;
 
 /**
  * An action that moves to the Home viewpoint on the main layer.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.3 $
diff --git a/src/java/org/xj3d/ui/awt/widgets/IconLoader.java b/src/java/org/xj3d/ui/awt/widgets/IconLoader.java
index 4a7587563922531cc66251f93ab300be25f79b15..3857dafc4c42003cf742485d901a30872fe1c20b 100644
--- a/src/java/org/xj3d/ui/awt/widgets/IconLoader.java
+++ b/src/java/org/xj3d/ui/awt/widgets/IconLoader.java
@@ -27,6 +27,7 @@ import org.j3d.util.ErrorReporter;
 /**
  * A convenience class that loads Icons and images for Xj3D's internal uses
  * and provides caching mechanisms.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.2 $
diff --git a/src/java/org/xj3d/ui/awt/widgets/LoadURLAction.java b/src/java/org/xj3d/ui/awt/widgets/LoadURLAction.java
index 0fb33dcdfbe2c91d484214d1c768bdd19b4686bf..f0c40236bd6d115fcc63bbefa3fda380b8f7dd54 100644
--- a/src/java/org/xj3d/ui/awt/widgets/LoadURLAction.java
+++ b/src/java/org/xj3d/ui/awt/widgets/LoadURLAction.java
@@ -1,124 +1,124 @@
-/*****************************************************************************
- * Copyright North Dakota State University and Web3d.org, 2004
- * Written By Bradley Vender (Bradley.Vender@ndsu.nodak.edu)
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- *****************************************************************************/
-
-package org.xj3d.ui.awt.widgets;
-
-// External Imports
-import java.awt.TextField;
-import java.awt.event.ActionListener;
-import java.awt.event.ActionEvent;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-
-import javax.swing.JTextField;
-
-// Local imports
-import org.web3d.util.FileHandler;
-import org.j3d.util.ErrorReporter;
-
-/**
- * Simple utility class for processing scene loading requests from the
- * location bar.
- *
- * @author Brad Vender
- * @version $Revision: 1.2 $
- */
-public class LoadURLAction implements ActionListener, Runnable {
-
-    /** The panel to load using */
-    private FileHandler handler;
-
-    /** Where to get String */
-    private JTextField urlSourceA;
-
-    /** Where to get String */
-    private TextField urlSourceB;
-
-    /**
-     * Basic constructor using a swing component.
-     *
-     * @param target The panel to modify
-     * @param source The component from which URLs will be gotten
-     */
-    public LoadURLAction(FileHandler target, JTextField source) {
-        handler = target;
-        urlSourceA = source;
-    }
-
-    /**
-     * Basic constructor using an AWT component.
-     *
-     * @param target The panel to modify
-     * @param source The component from which URLs will be gotten
-     */
-    public LoadURLAction(FileHandler target, TextField source) {
-        handler = target;
-        urlSourceB = source;
-    }
-
-    //------------------------------------------------------------------------
-    // Methods defined by ActionListener
-    //------------------------------------------------------------------------
-
-    /**
-     * Starts a new loading thread.
-     * @param e
-     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
-     */
-    @Override
-    public void actionPerformed(ActionEvent e) {
-        new Thread(this).start();
-    }
-
-    //------------------------------------------------------------------------
-    // Methods defined by Runnable
-    //------------------------------------------------------------------------
-
-    /**
-     * Just gets the URL from the text field and calls loadURL
-     */
-    @Override
-    public void run() {
-
-        String urlToLoad = urlSourceA != null ?
-                           urlSourceA.getText() :
-                           urlSourceB.getText();
-
-        ErrorReporter reporter = handler.getErrorReporter();
-
-        try {
-            reporter.messageReport("Attempting to load:" + urlToLoad);
-
-            String url_str = null;
-
-            // try a file first
-            File f = new File(urlToLoad);
-            if(f.exists()) {
-                if(f.isDirectory())
-                    reporter.errorReport("File is a directory", null);
-                else {
-                    url_str = f.toURI().toURL().toExternalForm();
-                }
-            } else {
-                // Try a URL
-                URL url = new URL(urlToLoad);
-                url_str = url.toExternalForm();
-            }
-
-            handler.loadURL(url_str);
-        } catch (IOException ioe) {
-            reporter.errorReport("Unable to load " + urlToLoad, ioe);
-        }
-    }
-}
+/*****************************************************************************
+ * Copyright North Dakota State University and Web3d.org, 2004
+ * Written By Bradley Vender (Bradley.Vender@ndsu.nodak.edu)
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ *****************************************************************************/
+
+package org.xj3d.ui.awt.widgets;
+
+// External Imports
+import java.awt.TextField;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+
+import javax.swing.JTextField;
+
+// Local imports
+import org.web3d.util.FileHandler;
+import org.j3d.util.ErrorReporter;
+
+/**
+ * Simple utility class for processing scene loading requests from the
+ * location bar.
+ *
+ * @author Brad Vender
+ * @version $Revision: 1.2 $
+ */
+public class LoadURLAction implements ActionListener, Runnable {
+
+    /** The panel to load using */
+    private FileHandler handler;
+
+    /** Where to get String */
+    private JTextField urlSourceA;
+
+    /** Where to get String */
+    private TextField urlSourceB;
+
+    /**
+     * Basic constructor using a swing component.
+     *
+     * @param target The panel to modify
+     * @param source The component from which URLs will be gotten
+     */
+    public LoadURLAction(FileHandler target, JTextField source) {
+        handler = target;
+        urlSourceA = source;
+    }
+
+    /**
+     * Basic constructor using an AWT component.
+     *
+     * @param target The panel to modify
+     * @param source The component from which URLs will be gotten
+     */
+    public LoadURLAction(FileHandler target, TextField source) {
+        handler = target;
+        urlSourceB = source;
+    }
+
+    //------------------------------------------------------------------------
+    // Methods defined by ActionListener
+    //------------------------------------------------------------------------
+
+    /**
+     * Starts a new loading thread.
+     * @param e
+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
+     */
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        new Thread(this).start();
+    }
+
+    //------------------------------------------------------------------------
+    // Methods defined by Runnable
+    //------------------------------------------------------------------------
+
+    /**
+     * Just gets the URL from the text field and calls loadURL
+     */
+    @Override
+    public void run() {
+
+        String urlToLoad = urlSourceA != null ?
+                           urlSourceA.getText() :
+                           urlSourceB.getText();
+
+        ErrorReporter reporter = handler.getErrorReporter();
+
+        try {
+            reporter.messageReport("Attempting to load:" + urlToLoad);
+
+            String url_str = null;
+
+            // try a file first
+            File f = new File(urlToLoad);
+            if(f.exists()) {
+                if(f.isDirectory())
+                    reporter.errorReport("File is a directory", null);
+                else {
+                    url_str = f.toURI().toURL().toExternalForm();
+                }
+            } else {
+                // Try a URL
+                URL url = new URL(urlToLoad);
+                url_str = url.toExternalForm();
+            }
+
+            handler.loadURL(url_str);
+        } catch (IOException ioe) {
+            reporter.errorReport("Unable to load " + urlToLoad, ioe);
+        }
+    }
+}
diff --git a/src/java/org/xj3d/ui/awt/widgets/LookatAction.java b/src/java/org/xj3d/ui/awt/widgets/LookatAction.java
index 39d39d2c674c62f964bcfd5e7f89614f654f21a4..bd4e6a72f530b8efef043eb3b6719bd25a83a44d 100644
--- a/src/java/org/xj3d/ui/awt/widgets/LookatAction.java
+++ b/src/java/org/xj3d/ui/awt/widgets/LookatAction.java
@@ -28,6 +28,7 @@ import org.web3d.browser.Xj3DConstants;
 
 /**
  * An action that changes the navigation mode to LookAt.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.2 $
diff --git a/src/java/org/xj3d/ui/awt/widgets/NavModeAction.java b/src/java/org/xj3d/ui/awt/widgets/NavModeAction.java
index 99344568f4edfb1d6cce9b3ad2e9cdd56c2cc9d6..4ee8483f36ef3c8692c0f5e875e138f7485b7a4b 100644
--- a/src/java/org/xj3d/ui/awt/widgets/NavModeAction.java
+++ b/src/java/org/xj3d/ui/awt/widgets/NavModeAction.java
@@ -26,6 +26,7 @@ import org.web3d.browser.BrowserCore;
 
 /**
  * An action that changes to a specific navigation mode.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.3 $
diff --git a/src/java/org/xj3d/ui/awt/widgets/NextViewpointAction.java b/src/java/org/xj3d/ui/awt/widgets/NextViewpointAction.java
index 546e2226bdb3a83085181167f815de49002091cd..bf5bb7d1292313e16de3748d582acb4414a7dc98 100644
--- a/src/java/org/xj3d/ui/awt/widgets/NextViewpointAction.java
+++ b/src/java/org/xj3d/ui/awt/widgets/NextViewpointAction.java
@@ -27,6 +27,7 @@ import org.xj3d.core.eventmodel.ViewpointManager;
 
 /**
  * An action that moves to the next viewpoint on the main layer.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.3 $
diff --git a/src/java/org/xj3d/ui/awt/widgets/OpenAction.java b/src/java/org/xj3d/ui/awt/widgets/OpenAction.java
index f9431c5890e3e39993f864db614e86cd39e8c88e..d4179994e0f2f8de33bb3869e5e269ca79c27dc0 100644
--- a/src/java/org/xj3d/ui/awt/widgets/OpenAction.java
+++ b/src/java/org/xj3d/ui/awt/widgets/OpenAction.java
@@ -30,6 +30,7 @@ import org.web3d.util.FileHandler;
 
 /**
  * An action that can be used to open a file.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.4 $
diff --git a/src/java/org/xj3d/ui/awt/widgets/PreviousViewpointAction.java b/src/java/org/xj3d/ui/awt/widgets/PreviousViewpointAction.java
index 6529dd3b8aa9e5d720f64995c7da2bc014335dc1..e789de5f7a36dffa099db1e6d5b786c5b38d9be2 100644
--- a/src/java/org/xj3d/ui/awt/widgets/PreviousViewpointAction.java
+++ b/src/java/org/xj3d/ui/awt/widgets/PreviousViewpointAction.java
@@ -27,6 +27,7 @@ import org.xj3d.core.eventmodel.ViewpointManager;
 
 /**
  * An action that moves to the Previous viewpoint on the main layer.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.3 $
diff --git a/src/java/org/xj3d/ui/awt/widgets/ReloadAction.java b/src/java/org/xj3d/ui/awt/widgets/ReloadAction.java
index 40b96f4008da80902a694fe9648035aa906114a7..3c324049dd2024673d9beee99c124cd74dd9ed69 100644
--- a/src/java/org/xj3d/ui/awt/widgets/ReloadAction.java
+++ b/src/java/org/xj3d/ui/awt/widgets/ReloadAction.java
@@ -27,6 +27,7 @@ import org.web3d.util.FileHandler;
 
 /**
  * An action that reloads the last file.
+ * <p>
  *
  * @author Alan Hudson
  * @version $Revision: 1.2 $
diff --git a/src/java/org/xj3d/ui/awt/widgets/SelectableFileFilter.java b/src/java/org/xj3d/ui/awt/widgets/SelectableFileFilter.java
index 4e21866b9b76cab0be4f878540922bed29b16018..590e31dcc685308bd8c761673c1fc1f0d8dace3d 100644
--- a/src/java/org/xj3d/ui/awt/widgets/SelectableFileFilter.java
+++ b/src/java/org/xj3d/ui/awt/widgets/SelectableFileFilter.java
@@ -1,92 +1,92 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2005 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.ui.awt.widgets;
-
-// External imports
-import javax.swing.filechooser.*;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-// Local imports
-
-/**
- * File filter for restricting files to any arbitrary types set.
- *
- * @author Alan Hudson
- * @version $Revision: 1.1 $
- */
-public class SelectableFileFilter extends FileFilter {
-
-    /** The valid extensions */
-    private Set<String> validExts;
-
-    /** The description */
-    private String description;
-
-    /**
-     * Create a new selectable filter for a collection of extensions,
-     * and a given description.
-     *
-     * @param extensions A non-null array of extensions to process for
-     * @param description An arbitrary description string
-     */
-    public SelectableFileFilter(String[] extensions, String description) {
-        validExts = new HashSet<>(extensions.length);
-        validExts.addAll(Arrays.asList(extensions));
-
-        this.description = description;
-    }
-
-    /**
-     * Should we accept this file
-     *
-     * @param f The file to test
-     * @return true if acceptable
-     */
-    @Override
-    public boolean accept(File f) {
-        if (f.isDirectory())
-            return true;
-
-        String extension = null;
-
-        String s = f.getName();
-
-        int i = s.lastIndexOf('.');
-
-        if (i > 0 &&  i < s.length() - 1)
-            extension = s.substring(i+1).toLowerCase();
-
-
-        if (extension != null) {
-            if (validExts.contains(extension))
-                return true;
-            else
-                return false;
-        }
-
-        return false;
-    }
-
-    /**
-     * The description of this filter
-     * @return 
-     */
-    @Override
-    public String getDescription() {
-        return description;
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2005 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.ui.awt.widgets;
+
+// External imports
+import javax.swing.filechooser.*;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+// Local imports
+
+/**
+ * File filter for restricting files to any arbitrary types set.
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.1 $
+ */
+public class SelectableFileFilter extends FileFilter {
+
+    /** The valid extensions */
+    private Set<String> validExts;
+
+    /** The description */
+    private String description;
+
+    /**
+     * Create a new selectable filter for a collection of extensions,
+     * and a given description.
+     *
+     * @param extensions A non-null array of extensions to process for
+     * @param description An arbitrary description string
+     */
+    public SelectableFileFilter(String[] extensions, String description) {
+        validExts = new HashSet<>(extensions.length);
+        validExts.addAll(Arrays.asList(extensions));
+
+        this.description = description;
+    }
+
+    /**
+     * Should we accept this file
+     *
+     * @param f The file to test
+     * @return true if acceptable
+     */
+    @Override
+    public boolean accept(File f) {
+        if (f.isDirectory())
+            return true;
+
+        String extension = null;
+
+        String s = f.getName();
+
+        int i = s.lastIndexOf('.');
+
+        if (i > 0 &&  i < s.length() - 1)
+            extension = s.substring(i+1).toLowerCase();
+
+
+        if (extension != null) {
+            if (validExts.contains(extension))
+                return true;
+            else
+                return false;
+        }
+
+        return false;
+    }
+
+    /**
+     * The description of this filter
+     * @return 
+     */
+    @Override
+    public String getDescription() {
+        return description;
+    }
+}
diff --git a/src/java/org/xj3d/ui/awt/widgets/SwingConsoleButton.java b/src/java/org/xj3d/ui/awt/widgets/SwingConsoleButton.java
index d32b4aa19015b7bd4d02dc7a37d2f2f1b5843f31..438f4e279a8d3963ace6ca09475ab1e7546b5270 100644
--- a/src/java/org/xj3d/ui/awt/widgets/SwingConsoleButton.java
+++ b/src/java/org/xj3d/ui/awt/widgets/SwingConsoleButton.java
@@ -27,6 +27,7 @@ import javax.swing.ImageIcon;
 /**
  * A self-configured button implementation that can be used to show and hide
  * the console window.
+ * <p>
  *
  * @author Justin Couch
  * @version $Revision: 1.5 $
diff --git a/src/java/org/xj3d/ui/awt/widgets/SwingConsoleWindow.java b/src/java/org/xj3d/ui/awt/widgets/SwingConsoleWindow.java
index 104b6f0ecbea7e75d84c5d354a93279731659bd0..d1094525f774fde5d30c666c46468a8a2142a317 100644
--- a/src/java/org/xj3d/ui/awt/widgets/SwingConsoleWindow.java
+++ b/src/java/org/xj3d/ui/awt/widgets/SwingConsoleWindow.java
@@ -1,5 +1,5 @@
 /*****************************************************************************
- *                        Web3d.org Copyright (c) 2001 - 2022
+ *                        Web3d.org Copyright (c) 2001 - 2006
  *                               Java Source
  *
  * This source is licensed under the GNU LGPL v2.1
@@ -14,17 +14,22 @@ package org.xj3d.ui.awt.widgets;
 
 // External imports
 import java.awt.*;
-import java.awt.datatransfer.Clipboard;
-import java.awt.datatransfer.StringSelection;
+import java.io.*;
+import javax.swing.*;
+
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.io.*;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.StringSelection;
+
 import java.net.UnknownHostException;
-import javax.swing.*;
+
+// Local imports
+import org.web3d.vrml.lang.*;
+
 import org.j3d.util.ErrorReporter;
 import org.j3d.util.HashSet;
-import org.web3d.util.Xj3dVersionInformation;
-import org.web3d.vrml.lang.*;
+import org.web3d.util.Version;
 import org.web3d.vrml.sav.ErrorHandler;
 import org.web3d.vrml.sav.Locator;
 import org.web3d.vrml.sav.VRMLParseException;
@@ -110,7 +115,7 @@ public class SwingConsoleWindow extends JFrame
         setLocation(80, 80);
         setDefaultCloseOperation(HIDE_ON_CLOSE);
 
-        messageReport("Xj3D Version: " + Xj3dVersionInformation.XJ3D_VERSION + "\n");
+        messageReport("Xj3D Version: " + Version.XJ3D_VERSION + "\n");
 
         ignoredExceptionTypes = new HashSet<>();
         ignoredExceptionTypes.add(InvalidFieldException.class);
diff --git a/src/java/org/xj3d/ui/awt/widgets/SwingLocationToolbar.java b/src/java/org/xj3d/ui/awt/widgets/SwingLocationToolbar.java
index 67fad874c4b15a3c244b1384ec1e9fb35ea9923c..d43e9ba2e01f6a1c1d198c992b870398d04b1539 100644
--- a/src/java/org/xj3d/ui/awt/widgets/SwingLocationToolbar.java
+++ b/src/java/org/xj3d/ui/awt/widgets/SwingLocationToolbar.java
@@ -15,20 +15,25 @@ package org.xj3d.ui.awt.widgets;
 // External imports
 import java.awt.*;
 import java.awt.event.*;
-import java.io.File;
-import java.io.IOException;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.*;
-import java.util.prefs.Preferences;
 import javax.swing.*;
+
 import org.ietf.uri.*;
 import org.ietf.uri.event.ProgressListener;
-import org.j3d.util.DefaultErrorReporter;
-import org.j3d.util.ErrorReporter;
+
+import java.io.IOException;
+import java.io.File;
+import java.util.*;
+import java.util.prefs.Preferences;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+// Local imports
 import org.web3d.browser.BrowserCore;
 import org.web3d.browser.BrowserCoreListener;
 import org.web3d.util.FileHandler;
+import org.j3d.util.DefaultErrorReporter;
+import org.j3d.util.ErrorReporter;
 import org.web3d.vrml.nodes.VRMLScene;
 import org.web3d.vrml.sav.InputSource;
 import org.xj3d.core.loading.WorldLoaderManager;
@@ -37,6 +42,8 @@ import org.xj3d.impl.core.loading.FramerateThrottle;
 /**
  * A swing panel that implements the capabilities of the URL/Location
  * toolbar.
+ * <p>
+ *
  *
  * @author Justin Couch
  * @version $Revision: 1.13 $
@@ -405,9 +412,8 @@ public class SwingLocationToolbar extends JPanel
 
         String url_str;
 
-        errorReporter.messageReport("==================================================\n" + 
-             "Loading: " + url);
-        
+        errorReporter.messageReport("==================================================\n" + "Loading: " + url);
+
         // try a file first
         File f = new File(url);
         if(f.exists()) {
@@ -415,11 +421,9 @@ public class SwingLocationToolbar extends JPanel
                 errorReporter.errorReport("File is a directory", null);
                 return;
             } else {
-                url_str = f.toURI().toURL().toExternalForm(); // = url; TODO avoid munging? 
+                url_str = f.toURI().toURL().toExternalForm();
             }
-        } 
-        else {
-            
+        } else {
             // Try a URL
             URL url_obj = new URL(url);
             url_str = url_obj.toExternalForm();
@@ -532,7 +536,7 @@ public class SwingLocationToolbar extends JPanel
         urlComboBox.removeItem(loc);
         urlComboBox.insertItemAt(loc, 0);
 
-//        Object si = urlComboBox.getSelectedItem();
+        Object si = urlComboBox.getSelectedItem();
 
         urlComboBox.setSelectedIndex(0);
 
@@ -542,11 +546,11 @@ public class SwingLocationToolbar extends JPanel
 
         Iterator<String> itr = locations.iterator();
         int i = 0;
-        String val;
+
         while(itr.hasNext()) {
-            val = itr.next();
+            String val = itr.next();
 
-            if (val != null && !val.isEmpty()) {
+            if (val != null && val.length() > 0) {
                 prefs.remove(HISTORY_PROPERTY + i);
                 i++;
             } else {
@@ -560,7 +564,7 @@ public class SwingLocationToolbar extends JPanel
         i = 0;
 
         while(itr.hasNext()) {
-            val = itr.next();
+            String val = itr.next();
 
             if (val.length() > 0) {
                 prefs.put(HISTORY_PROPERTY + i, val);
diff --git a/src/java/org/xj3d/ui/awt/widgets/SwingProgressListener.java b/src/java/org/xj3d/ui/awt/widgets/SwingProgressListener.java
index ea49326e27c8c6fdd7ffdef7d07279e6d3132830..58c91501fa9bb5eac9d0d418f870af2cd619631f 100644
--- a/src/java/org/xj3d/ui/awt/widgets/SwingProgressListener.java
+++ b/src/java/org/xj3d/ui/awt/widgets/SwingProgressListener.java
@@ -1,267 +1,268 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2003 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.ui.awt.widgets;
-
-// External imports
-import java.awt.Container;
-import javax.swing.JLabel;
-import javax.swing.JProgressBar;
-
-import org.ietf.uri.ResourceConnection;
-import org.ietf.uri.URI;
-import org.ietf.uri.event.ProgressEvent;
-import org.ietf.uri.event.ProgressListener;
-
-// Local imports
-import org.j3d.util.ErrorReporter;
-
-/**
- * An implementation of the URI progress listener for putting messages to
- * a status label.
- *
- * @author  Justin Couch
- * @version $Revision: 1.4 $
- */
-public class SwingProgressListener implements ProgressListener {
-
-    /** Main file loading in progress message */
-    private static final String MAIN_FILE_LOAD_MSG =
-        "Main file downloading";
-
-    /** Main file loading complete message */
-    private static final String MAIN_FILE_LOAD_COMPLETE_MSG =
-        "Main file complete";
-
-    /** The status label to put transient messages on */
-    private JLabel statusLabel;
-
-    /** Error handler for more serious messages */
-    private ErrorReporter reporter;
-
-    /** A progress bar for main file loading */
-    private JProgressBar progressBar;
-
-    /** The size of the main file */
-    private int mainSize;
-
-    /** The container for the progress bar */
-    private Container progressPanel;
-
-    /** The layout location for the progress bar */
-    private String progressLocation;
-
-    /** Flag indicating that the current connection is to a local file */
-    private boolean currentConnectionIsFile;
-
-    /** Flag indicating that the main file is being loaded */
-    private boolean loadingMainFile;
-
-    /** Flag indicating that the progress bar is active */
-    private boolean progressBarIsActive;
-
-    /**
-     * Create a new listener that puts information in these different places.
-     * Assumes that both references are non-null.
-     *
-     * @param status The status label to write to
-     * @param progress progressBar display
-     * @param panel
-     * @param location
-     * @param rep The place for error messages
-     */
-    public SwingProgressListener(JLabel status, JProgressBar progress, Container panel,
-        String location, ErrorReporter rep) {
-        statusLabel = status;
-        reporter = rep;
-        progressBar = progress;
-        progressPanel = panel;
-        progressLocation = location;
-    }
-
-    //---------------------------------------------------------------
-    // Methods defined by ProgressListener
-    //---------------------------------------------------------------
-
-    /**
-     * A connection to the resource has been established. At this point, no data
-     * has yet been downloaded.
-     *
-     * @param evt The event that caused this method to be called.
-     */
-    @Override
-    public void connectionEstablished(ProgressEvent evt) {
-        statusLabel.setText(evt.getMessage());
-
-        ResourceConnection conn = evt.getSource();
-        if ((URI.getScheme(conn.getURI().toExternalForm()).equals(URI.FILE_SCHEME))) {
-
-            // if the connection is to a local file, then we can safely request
-            // it's length. requesting the length on an http connection may
-            // cause an infinite recursive loop - re-establishing a connection
-            // to get the file header - which generates this event - adnauseum...
-
-            currentConnectionIsFile = true;
-            mainSize = conn.getContentLength();
-            progressBar.setMaximum(mainSize);
-
-        } else {
-            currentConnectionIsFile = false;
-        }
-    }
-
-    /**
-     * The header information reading and handshaking is taking place. Reading
-     * and interpreting of the data (a download started event) should commence
-     * shortly. When that begins, you will be given the appropriate event.
-     *
-     * @param evt The event that caused this method to be called.
-     */
-    @Override
-    public void handshakeInProgress(ProgressEvent evt) {
-        statusLabel.setText(evt.getMessage());
-    }
-
-    /**
-     * The download has started.
-     *
-     * @param evt The event that caused this method to be called.
-     */
-    @Override
-    public void downloadStarted(ProgressEvent evt) {
-        ResourceConnection conn = evt.getSource();
-        int maxSize = conn.getContentLength();
-
-        progressBar.setMaximum(maxSize);
-
-        statusLabel.setText(evt.getMessage());
-    }
-
-    /**
-     * The download has updated its status.
-     *
-     * @param evt The event that caused this method to be called.
-     */
-    @Override
-    public void downloadUpdate(ProgressEvent evt) {
-        ResourceConnection conn = evt.getSource();
-
-        String url;
-        if (conn != null) {
-            URI uri = conn.getURI();
-            url = uri.toExternalForm();
-
-            //StringBuffer buf = new StringBuffer(url);
-            //buf.append(" (");
-            //buf.append(evt.getValue());
-            //buf.append(")");
-
-            //statusLabel.setText(buf.toString());
-            statusLabel.setText(url);
-
-            if ( progressBarIsActive ) {
-                progressBar.setValue(evt.getValue());
-            } else {
-
-                // this code path is depending upon the assumption
-                // that a downloadStarted event has occured and that
-                // the progress bar extent has been set there.
-
-                addProgressBar();
-                progressBarIsActive = true;
-                progressBar.setValue(evt.getValue());
-            }
-        } else {
-
-            // apparently the only way we can get here is if the
-            // 'main file' is being loaded
-
-            if ( loadingMainFile ) {
-                if ( progressBarIsActive ) {
-                    progressBar.setValue(evt.getValue());
-                }
-            } else {
-                loadingMainFile = true;
-                // TODO: Right now we don't know the filename
-                statusLabel.setText(MAIN_FILE_LOAD_MSG);
-                if ( currentConnectionIsFile ) {
-                    addProgressBar();
-                    progressBarIsActive = true;
-                    progressBar.setValue(evt.getValue());
-                }
-            }
-        }
-    }
-
-    /**
-     * The download has ended.
-     *
-     * @param evt The event that caused this method to be called.
-     */
-    @Override
-    public void downloadEnded(ProgressEvent evt) {
-        ResourceConnection conn = evt.getSource();
-
-        if (conn != null) {
-            URI uri = conn.getURI();
-
-            String msg = uri.toExternalForm() + " download complete.";
-            /*
-            String msg2 = evt.getMessage();
-            if (msg2 != null)
-            msg = msg + msg2;
-            */
-            statusLabel.setText(msg);
-            reporter.messageReport(msg);
-        } else {
-            statusLabel.setText(MAIN_FILE_LOAD_COMPLETE_MSG);
-            loadingMainFile = false;
-        }
-        if ( progressBarIsActive ) {
-            progressBarIsActive = false;
-            removeProgressBar();
-        }
-    }
-
-    /**
-     * An error has occurred during the download.
-     *
-     * @param evt The event that caused this method to be called.
-     */
-    @Override
-    public void downloadError(ProgressEvent evt) {
-        statusLabel.setText(evt.getMessage());
-        reporter.errorReport(evt.getMessage(), null);
-
-        if ( progressBarIsActive ) {
-            progressBarIsActive = false;
-            removeProgressBar();
-        }
-    }
-
-    /**
-     * Add the progress bar into the status bar.
-     */
-    private void addProgressBar() {
-        progressPanel.add(progressBar, progressLocation);
-    }
-
-    /**
-     * Remove the progress bar from the status bar.
-     */
-    private void removeProgressBar() {
-        //progressPanel.remove(progressBar);
-
-        progressBar.setMaximum(1);
-        progressBar.setValue(1);
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2003 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.ui.awt.widgets;
+
+// External imports
+import java.awt.Container;
+import javax.swing.JLabel;
+import javax.swing.JProgressBar;
+
+import org.ietf.uri.ResourceConnection;
+import org.ietf.uri.URI;
+import org.ietf.uri.event.ProgressEvent;
+import org.ietf.uri.event.ProgressListener;
+
+// Local imports
+import org.j3d.util.ErrorReporter;
+
+/**
+ * An implementation of the URI progress listener for putting messages to
+ * a status label.
+ *  <p>
+ *
+ * @author  Justin Couch
+ * @version $Revision: 1.4 $
+ */
+public class SwingProgressListener implements ProgressListener {
+
+    /** Main file loading in progress message */
+    private static final String MAIN_FILE_LOAD_MSG =
+        "Main file downloading";
+
+    /** Main file loading complete message */
+    private static final String MAIN_FILE_LOAD_COMPLETE_MSG =
+        "Main file complete";
+
+    /** The status label to put transient messages on */
+    private JLabel statusLabel;
+
+    /** Error handler for more serious messages */
+    private ErrorReporter reporter;
+
+    /** A progress bar for main file loading */
+    private JProgressBar progressBar;
+
+    /** The size of the main file */
+    private int mainSize;
+
+    /** The container for the progress bar */
+    private Container progressPanel;
+
+    /** The layout location for the progress bar */
+    private String progressLocation;
+
+    /** Flag indicating that the current connection is to a local file */
+    private boolean currentConnectionIsFile;
+
+    /** Flag indicating that the main file is being loaded */
+    private boolean loadingMainFile;
+
+    /** Flag indicating that the progress bar is active */
+    private boolean progressBarIsActive;
+
+    /**
+     * Create a new listener that puts information in these different places.
+     * Assumes that both references are non-null.
+     *
+     * @param status The status label to write to
+     * @param progress progressBar display
+     * @param panel
+     * @param location
+     * @param rep The place for error messages
+     */
+    public SwingProgressListener(JLabel status, JProgressBar progress, Container panel,
+        String location, ErrorReporter rep) {
+        statusLabel = status;
+        reporter = rep;
+        progressBar = progress;
+        progressPanel = panel;
+        progressLocation = location;
+    }
+
+    //---------------------------------------------------------------
+    // Methods defined by ProgressListener
+    //---------------------------------------------------------------
+
+    /**
+     * A connection to the resource has been established. At this point, no data
+     * has yet been downloaded.
+     *
+     * @param evt The event that caused this method to be called.
+     */
+    @Override
+    public void connectionEstablished(ProgressEvent evt) {
+        statusLabel.setText(evt.getMessage());
+
+        ResourceConnection conn = evt.getSource();
+        if ((URI.getScheme(conn.getURI().toExternalForm()).equals(URI.FILE_SCHEME))) {
+
+            // if the connection is to a local file, then we can safely request
+            // it's length. requesting the length on an http connection may
+            // cause an infinite recursive loop - re-establishing a connection
+            // to get the file header - which generates this event - adnauseum...
+
+            currentConnectionIsFile = true;
+            mainSize = conn.getContentLength();
+            progressBar.setMaximum(mainSize);
+
+        } else {
+            currentConnectionIsFile = false;
+        }
+    }
+
+    /**
+     * The header information reading and handshaking is taking place. Reading
+     * and interpreting of the data (a download started event) should commence
+     * shortly. When that begins, you will be given the appropriate event.
+     *
+     * @param evt The event that caused this method to be called.
+     */
+    @Override
+    public void handshakeInProgress(ProgressEvent evt) {
+        statusLabel.setText(evt.getMessage());
+    }
+
+    /**
+     * The download has started.
+     *
+     * @param evt The event that caused this method to be called.
+     */
+    @Override
+    public void downloadStarted(ProgressEvent evt) {
+        ResourceConnection conn = evt.getSource();
+        int maxSize = conn.getContentLength();
+
+        progressBar.setMaximum(maxSize);
+
+        statusLabel.setText(evt.getMessage());
+    }
+
+    /**
+     * The download has updated its status.
+     *
+     * @param evt The event that caused this method to be called.
+     */
+    @Override
+    public void downloadUpdate(ProgressEvent evt) {
+        ResourceConnection conn = evt.getSource();
+
+        String url;
+        if (conn != null) {
+            URI uri = conn.getURI();
+            url = uri.toExternalForm();
+
+            //StringBuffer buf = new StringBuffer(url);
+            //buf.append(" (");
+            //buf.append(evt.getValue());
+            //buf.append(")");
+
+            //statusLabel.setText(buf.toString());
+            statusLabel.setText(url);
+
+            if ( progressBarIsActive ) {
+                progressBar.setValue(evt.getValue());
+            } else {
+
+                // this code path is depending upon the assumption
+                // that a downloadStarted event has occured and that
+                // the progress bar extent has been set there.
+
+                addProgressBar();
+                progressBarIsActive = true;
+                progressBar.setValue(evt.getValue());
+            }
+        } else {
+
+            // apparently the only way we can get here is if the
+            // 'main file' is being loaded
+
+            if ( loadingMainFile ) {
+                if ( progressBarIsActive ) {
+                    progressBar.setValue(evt.getValue());
+                }
+            } else {
+                loadingMainFile = true;
+                // TODO: Right now we don't know the filename
+                statusLabel.setText(MAIN_FILE_LOAD_MSG);
+                if ( currentConnectionIsFile ) {
+                    addProgressBar();
+                    progressBarIsActive = true;
+                    progressBar.setValue(evt.getValue());
+                }
+            }
+        }
+    }
+
+    /**
+     * The download has ended.
+     *
+     * @param evt The event that caused this method to be called.
+     */
+    @Override
+    public void downloadEnded(ProgressEvent evt) {
+        ResourceConnection conn = evt.getSource();
+
+        if (conn != null) {
+            URI uri = conn.getURI();
+
+            String msg = uri.toExternalForm() + " download complete.";
+            /*
+            String msg2 = evt.getMessage();
+            if (msg2 != null)
+            msg = msg + msg2;
+            */
+            statusLabel.setText(msg);
+            reporter.messageReport(msg);
+        } else {
+            statusLabel.setText(MAIN_FILE_LOAD_COMPLETE_MSG);
+            loadingMainFile = false;
+        }
+        if ( progressBarIsActive ) {
+            progressBarIsActive = false;
+            removeProgressBar();
+        }
+    }
+
+    /**
+     * An error has occurred during the download.
+     *
+     * @param evt The event that caused this method to be called.
+     */
+    @Override
+    public void downloadError(ProgressEvent evt) {
+        statusLabel.setText(evt.getMessage());
+        reporter.errorReport(evt.getMessage(), null);
+
+        if ( progressBarIsActive ) {
+            progressBarIsActive = false;
+            removeProgressBar();
+        }
+    }
+
+    /**
+     * Add the progress bar into the status bar.
+     */
+    private void addProgressBar() {
+        progressPanel.add(progressBar, progressLocation);
+    }
+
+    /**
+     * Remove the progress bar from the status bar.
+     */
+    private void removeProgressBar() {
+        //progressPanel.remove(progressBar);
+
+        progressBar.setMaximum(1);
+        progressBar.setValue(1);
+    }
+}
diff --git a/src/java/org/xj3d/ui/awt/widgets/VRMLFileFilter.java b/src/java/org/xj3d/ui/awt/widgets/VRMLFileFilter.java
index 1b7e33da80fa26511ca72731981f4dd7c7a1c1d5..3c9c0e4a3a1371ad738a698af50b41ba28b3ac82 100644
--- a/src/java/org/xj3d/ui/awt/widgets/VRMLFileFilter.java
+++ b/src/java/org/xj3d/ui/awt/widgets/VRMLFileFilter.java
@@ -1,88 +1,88 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2005 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.ui.awt.widgets;
-
-// External imports
-import javax.swing.filechooser.*;
-
-import java.io.File;
-import java.util.HashSet;
-import java.util.Set;
-
-// Local imports
-// None
-
-/**
- * File filter for restricting files to VRML types.
- *
- * @author Alan Hudson
- * @version $Revision: 1.2 $
- */
-public class VRMLFileFilter extends FileFilter
-{
-    /** The valid extensions */
-    private Set<String> validExts;
-
-    /**
-     * Create a new file filter for just VRML types.
-     */
-    public VRMLFileFilter() {
-        validExts = new HashSet<>(3);
-
-        validExts.add("wrl");
-        validExts.add("wrz");
-        validExts.add("gz");
-    }
-
-    /**
-     * Should we accept this file
-     *
-     * @param f The file to test
-     * @return true if acceptable
-     */
-    @Override
-    public boolean accept(File f)
-    {
-        if (f.isDirectory())
-            return true;
-
-        String extension = null;
-
-        String s = f.getName();
-
-        int i = s.lastIndexOf('.');
-
-        if (i > 0 &&  i < s.length() - 1)
-        {
-            extension = s.substring(i+1).toLowerCase();
-        }
-
-
-        if (extension != null)
-        {
-            if (validExts.contains(extension))
-                return true;
-            else
-                return false;
-        }
-
-        return false;
-    }
-
-    // The description of this filter
-    @Override
-    public String getDescription()
-    {
-        return "Just VRML Files";
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2005 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.ui.awt.widgets;
+
+// External imports
+import javax.swing.filechooser.*;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Set;
+
+// Local imports
+// None
+
+/**
+ * File filter for restricting files to VRML types.
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.2 $
+ */
+public class VRMLFileFilter extends FileFilter
+{
+    /** The valid extensions */
+    private Set<String> validExts;
+
+    /**
+     * Create a new file filter for just VRML types.
+     */
+    public VRMLFileFilter() {
+        validExts = new HashSet<>(3);
+
+        validExts.add("wrl");
+        validExts.add("wrz");
+        validExts.add("gz");
+    }
+
+    /**
+     * Should we accept this file
+     *
+     * @param f The file to test
+     * @return true if acceptable
+     */
+    @Override
+    public boolean accept(File f)
+    {
+        if (f.isDirectory())
+            return true;
+
+        String extension = null;
+
+        String s = f.getName();
+
+        int i = s.lastIndexOf('.');
+
+        if (i > 0 &&  i < s.length() - 1)
+        {
+            extension = s.substring(i+1).toLowerCase();
+        }
+
+
+        if (extension != null)
+        {
+            if (validExts.contains(extension))
+                return true;
+            else
+                return false;
+        }
+
+        return false;
+    }
+
+    // The description of this filter
+    @Override
+    public String getDescription()
+    {
+        return "Just VRML Files";
+    }
+}
diff --git a/src/java/org/xj3d/ui/awt/widgets/Web3DFileFilter.java b/src/java/org/xj3d/ui/awt/widgets/Web3DFileFilter.java
index 3a84b014c64e6c4ace051cce2c3f73d4aba02761..ef0eb16b49f119eee03aaa5fca55934cc42e4ea4 100644
--- a/src/java/org/xj3d/ui/awt/widgets/Web3DFileFilter.java
+++ b/src/java/org/xj3d/ui/awt/widgets/Web3DFileFilter.java
@@ -1,90 +1,90 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2005 - 2006
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.ui.awt.widgets;
-
-// External imports
-import javax.swing.filechooser.*;
-
-import java.io.File;
-import java.util.HashSet;
-import java.util.Set;
-
-// Local imports
-// None
-
-/**
- * File filter for restricting files to both X3D and VRML types.
- *
- * @author Alan Hudson
- * @version $Revision: 1.2 $
- */
-public class Web3DFileFilter extends FileFilter {
-
-    /** The valid extensions */
-    private Set<String> validExts;
-
-    /**
-     * Create a new file filter instance.
-     */
-    public Web3DFileFilter() {
-        validExts = new HashSet<>(8);
-
-        validExts.add("x3d");
-        validExts.add("x3dz");
-        validExts.add("x3dv");
-        validExts.add("x3dvz");
-        validExts.add("x3db");
-        validExts.add("wrl");
-        validExts.add("wrz");
-        validExts.add("gz");
-    }
-
-    /**
-     * Should we accept this file
-     *
-     * @param f The file to test
-     * @return true if acceptable
-     */
-    @Override
-    public boolean accept(File f) {
-        if (f.isDirectory())
-            return true;
-
-        String extension = null;
-
-        String s = f.getName();
-
-        int i = s.lastIndexOf('.');
-
-        if (i > 0 &&  i < s.length() - 1)
-            extension = s.substring(i+1).toLowerCase();
-
-        if (extension != null) {
-            if (validExts.contains(extension))
-                return true;
-            else
-                return false;
-        }
-
-        return false;
-    }
-
-    /**
-     * The description of this filter
-     * @return 
-     */
-    @Override
-    public String getDescription() {
-        return "X3D and VRML Files";
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2005 - 2006
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.ui.awt.widgets;
+
+// External imports
+import javax.swing.filechooser.*;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Set;
+
+// Local imports
+// None
+
+/**
+ * File filter for restricting files to both X3D and VRML types.
+ *
+ * @author Alan Hudson
+ * @version $Revision: 1.2 $
+ */
+public class Web3DFileFilter extends FileFilter {
+
+    /** The valid extensions */
+    private Set<String> validExts;
+
+    /**
+     * Create a new file filter instance.
+     */
+    public Web3DFileFilter() {
+        validExts = new HashSet<>(8);
+
+        validExts.add("x3d");
+        validExts.add("x3dz");
+        validExts.add("x3dv");
+        validExts.add("x3dvz");
+        validExts.add("x3db");
+        validExts.add("wrl");
+        validExts.add("wrz");
+        validExts.add("gz");
+    }
+
+    /**
+     * Should we accept this file
+     *
+     * @param f The file to test
+     * @return true if acceptable
+     */
+    @Override
+    public boolean accept(File f) {
+        if (f.isDirectory())
+            return true;
+
+        String extension = null;
+
+        String s = f.getName();
+
+        int i = s.lastIndexOf('.');
+
+        if (i > 0 &&  i < s.length() - 1)
+            extension = s.substring(i+1).toLowerCase();
+
+        if (extension != null) {
+            if (validExts.contains(extension))
+                return true;
+            else
+                return false;
+        }
+
+        return false;
+    }
+
+    /**
+     * The description of this filter
+     * @return 
+     */
+    @Override
+    public String getDescription() {
+        return "X3D and VRML Files";
+    }
+}
diff --git a/src/java/org/xj3d/ui/awt/widgets/X3DFileFilter.java b/src/java/org/xj3d/ui/awt/widgets/X3DFileFilter.java
index 1176bcaaa0c76d95b8062b8bfb4fd89380dad340..12f61f281160a638a60503e24879669d0977e029 100644
--- a/src/java/org/xj3d/ui/awt/widgets/X3DFileFilter.java
+++ b/src/java/org/xj3d/ui/awt/widgets/X3DFileFilter.java
@@ -13,10 +13,11 @@
 package org.xj3d.ui.awt.widgets;
 
 // External imports
+import javax.swing.filechooser.*;
+
 import java.io.File;
 import java.util.HashSet;
 import java.util.Set;
-import javax.swing.filechooser.*;
 
 // Local imports
 // None
@@ -82,6 +83,6 @@ public class X3DFileFilter extends FileFilter {
      */
     @Override
     public String getDescription() {
-        return "X3D file formats";
+        return "Just X3D Files";
     }
 }
diff --git a/src/java/org/xj3d/ui/construct/DeathTimer.java b/src/java/org/xj3d/ui/construct/DeathTimer.java
index b4e43ba5b4990ee5f9a9fa9338e9da674373a425..227478df17f86e4cca5b72c2a1f1fff204cfe5eb 100644
--- a/src/java/org/xj3d/ui/construct/DeathTimer.java
+++ b/src/java/org/xj3d/ui/construct/DeathTimer.java
@@ -1,84 +1,84 @@
-/*****************************************************************************
- *                    Yumetech, Inc Copyright (c) 2010
- *                               Java Source
- *
- * This source is licensed under the BSD license.
- * Please read docs/BSD.txt for the text of the license.
- *
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.ui.construct;
-
-/**
- * A dark and evil class who is very impatient.  If it isn't told to stop
- * in time it will kill the whole system.
- *
- * Used with captureViewpoints in case the browser hangs.  We want the
- * browser to still exit.
- *
- * @author Alan Hudson, Eric Fickenscher
- * @version $Revision: 1.0 $
- */
-public class DeathTimer extends Thread {
-
-    /** The exit code to throw when calling System.exit() */
-    private static final int SYSTEM_TIMEOUT_EXIT_CODE = -1;
-
-    /** TRUE if we still want this DeathTimer thread
-     * to terminate the application by calling System.exit().
-     *
-     * Set to FALSE by calling exit() if we no longer want
-     * to kill the whole system.
-     */
-    private boolean exitIfTimeExceeded;
-
-    /** Amount of milliseconds to wait until we call System.exit() */
-    private long waitTime;
-
-    /**
-     * @param wait integer value - number of milliseconds to wait
-     * before calling System.exit().
-     */
-    public DeathTimer(int wait) {
-        exitIfTimeExceeded = true;
-        waitTime = wait;
-    }
-
-    /**
-     * Continue to call Thread.sleep while {@link #exitIfTimeExceeded} is
-     * TRUE.  Shutdown the application if {@link #waitTime} is
-     * exceeded.
-     */
-    @Override
-    public void run() {
-
-        waitTime += System.currentTimeMillis();
-
-        while ( exitIfTimeExceeded ) {
-
-            try {
-                Thread.sleep(500);
-
-            } catch(InterruptedException e) {
-                // ignored
-            }
-
-            if (System.currentTimeMillis() > waitTime) {
-                System.out.println("Time exceeded, killing system");
-                System.exit(SYSTEM_TIMEOUT_EXIT_CODE);
-            }
-        }
-    }
-
-    /**
-     * Exit this watcher.  Call this method if you no longer
-     * want to terminate the application.
-     */
-    public void exit() {
-        exitIfTimeExceeded = false;
-    }
-}
+/*****************************************************************************
+ *                    Yumetech, Inc Copyright (c) 2010
+ *                               Java Source
+ *
+ * This source is licensed under the BSD license.
+ * Please read docs/BSD.txt for the text of the license.
+ *
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.ui.construct;
+
+/**
+ * A dark and evil class who is very impatient.  If it isn't told to stop
+ * in time it will kill the whole system.
+ *
+ * Used with captureViewpoints in case the browser hangs.  We want the
+ * browser to still exit.
+ *
+ * @author Alan Hudson, Eric Fickenscher
+ * @version $Revision: 1.0 $
+ */
+public class DeathTimer extends Thread {
+
+    /** The exit code to throw when calling System.exit() */
+    private static final int SYSTEM_TIMEOUT_EXIT_CODE = -1;
+
+    /** TRUE if we still want this DeathTimer thread
+     * to terminate the application by calling System.exit().
+     *
+     * Set to FALSE by calling exit() if we no longer want
+     * to kill the whole system.
+     */
+    private boolean exitIfTimeExceeded;
+
+    /** Amount of milliseconds to wait until we call System.exit() */
+    private long waitTime;
+
+    /**
+     * @param wait integer value - number of milliseconds to wait
+     * before calling System.exit().
+     */
+    public DeathTimer(int wait) {
+        exitIfTimeExceeded = true;
+        waitTime = wait;
+    }
+
+    /**
+     * Continue to call Thread.sleep while {@link #exitIfTimeExceeded} is
+     * TRUE.  Shutdown the application if {@link #waitTime} is
+     * exceeded.
+     */
+    @Override
+    public void run() {
+
+        waitTime += System.currentTimeMillis();
+
+        while ( exitIfTimeExceeded ) {
+
+            try {
+                Thread.sleep(500);
+
+            } catch(InterruptedException e) {
+                // ignored
+            }
+
+            if (System.currentTimeMillis() > waitTime) {
+                System.out.println("Time exceeded, killing system");
+                System.exit(SYSTEM_TIMEOUT_EXIT_CODE);
+            }
+        }
+    }
+
+    /**
+     * Exit this watcher.  Call this method if you no longer
+     * want to terminate the application.
+     */
+    public void exit() {
+        exitIfTimeExceeded = false;
+    }
+}
diff --git a/src/java/org/xj3d/ui/construct/ScenePreprocessor.java b/src/java/org/xj3d/ui/construct/ScenePreprocessor.java
index ee4de49793a99caf75f20d6bbfc5641f3a4fbf47..5c54ed508d13c492e0bc6cf130780fc7d08f893a 100644
--- a/src/java/org/xj3d/ui/construct/ScenePreprocessor.java
+++ b/src/java/org/xj3d/ui/construct/ScenePreprocessor.java
@@ -1,37 +1,37 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2007
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- *****************************************************************************/
-
-package org.xj3d.ui.construct;
-
-// External imports
-// None
-
-// Local imports
-import org.web3d.vrml.nodes.VRMLScene;
-
-/**
- * Defines the requirements of a module that performs some modifications
- * to a VRMLScene instance before it is set to the browser Construct.
- *
- * @author Rex Melton
- * @version $Revision: 1.1 $
- */
-public interface ScenePreprocessor {
-
-    /** 
-     * Modify the VRMLScene
-     *
-     * @param scene The VRMLScene instance
-     * @param construct The browser construct
-     */
-    void preprocess( VRMLScene scene, Construct construct );
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2007
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ *****************************************************************************/
+
+package org.xj3d.ui.construct;
+
+// External imports
+// None
+
+// Local imports
+import org.web3d.vrml.nodes.VRMLScene;
+
+/**
+ * Defines the requirements of a module that performs some modifications
+ * to a VRMLScene instance before it is set to the browser Construct.
+ *
+ * @author Rex Melton
+ * @version $Revision: 1.1 $
+ */
+public interface ScenePreprocessor {
+
+    /** 
+     * Modify the VRMLScene
+     *
+     * @param scene The VRMLScene instance
+     * @param construct The browser construct
+     */
+    void preprocess( VRMLScene scene, Construct construct );
+}
diff --git a/src/java/org/xj3d/ui/construct/event/RecorderListener.java b/src/java/org/xj3d/ui/construct/event/RecorderListener.java
index 30255a7bd15b65de22c99bb776673e113a305819..5378a07c02ce2691302cfea7fea540c3f55f6cef 100644
--- a/src/java/org/xj3d/ui/construct/event/RecorderListener.java
+++ b/src/java/org/xj3d/ui/construct/event/RecorderListener.java
@@ -1,35 +1,35 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2007
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- ****************************************************************************/
-
-package org.xj3d.ui.construct.event;
-
-// External imports
-import java.util.EventListener;
-
-// Local imports
-// None
-
-/**
- * The listener interface for receiving events.
- *
- * @author Rex Melton
- * @version $Revision: 1.1 $
- */
-public interface RecorderListener extends EventListener {
-
-    /**
-     * Invoked when an RecorderEvent occurs.
-     * @param evt an RecorderEvent fired
-     */
-    void recorderStatusChanged( RecorderEvent evt );
-}
-
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2007
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ ****************************************************************************/
+
+package org.xj3d.ui.construct.event;
+
+// External imports
+import java.util.EventListener;
+
+// Local imports
+// None
+
+/**
+ * The listener interface for receiving events.
+ *
+ * @author Rex Melton
+ * @version $Revision: 1.1 $
+ */
+public interface RecorderListener extends EventListener {
+
+    /**
+     * Invoked when an RecorderEvent occurs.
+     * @param evt an RecorderEvent fired
+     */
+    void recorderStatusChanged( RecorderEvent evt );
+}
+
diff --git a/src/java/org/xj3d/ui/construct/ogl/AutoConfigureViewpoint.java b/src/java/org/xj3d/ui/construct/ogl/AutoConfigureViewpoint.java
index 2def6401afebf0b509182a900063ef48f5c741e0..a7e1e1af45b6d838150740f4b990abb4822889af 100644
--- a/src/java/org/xj3d/ui/construct/ogl/AutoConfigureViewpoint.java
+++ b/src/java/org/xj3d/ui/construct/ogl/AutoConfigureViewpoint.java
@@ -1,300 +1,300 @@
-/*****************************************************************************
- *                        Web3d.org Copyright (c) 2007 - 2008
- *                               Java Source
- *
- * This source is licensed under the GNU LGPL v2.1
- * Please read http://www.gnu.org/copyleft/lgpl.html for more information
- *
- * This software comes with the standard NO WARRANTY disclaimer for any
- * purpose. Use it at your own risk. If there's a problem you get to fix it.
- *
- *****************************************************************************/
-
-package org.xj3d.ui.construct.ogl;
-
-// External Imports
-import javax.vecmath.AxisAngle4f;
-import javax.vecmath.Matrix4f;
-import javax.vecmath.Point3f;
-import javax.vecmath.Vector3f;
-
-import org.j3d.aviatrix3d.BoundingBox;
-import org.j3d.aviatrix3d.Group;
-import org.j3d.aviatrix3d.Layer;
-import org.j3d.aviatrix3d.SimpleLayer;
-import org.j3d.aviatrix3d.SimpleScene;
-import org.j3d.aviatrix3d.SimpleViewport;
-
-import org.j3d.aviatrix3d.management.DisplayCollection;
-
-import org.j3d.aviatrix3d.rendering.BoundingVolume;
-
-import org.j3d.util.ErrorReporter;
-import org.j3d.util.MatrixUtils;
-
-// Local Imports
-import org.web3d.vrml.lang.VRMLNodeFactory;
-
-import org.web3d.vrml.nodes.VRMLScene;
-import org.web3d.vrml.nodes.VRMLWorldRootNodeType;
-
-import org.web3d.vrml.nodes.FrameStateListener;
-import org.web3d.vrml.nodes.FrameStateManager;
-
-import org.web3d.vrml.renderer.ogl.browser.OGLStandardBrowserCore;
-
-import org.web3d.vrml.renderer.ogl.nodes.navigation.OGLNavigationInfo;
-import org.web3d.vrml.renderer.ogl.nodes.navigation.OGLViewpoint;
-
-/**
- * Utility module for the ThumbnailRecorder that will attempt to create
- * a useful default viewpoint of the loaded scene. The generated viewpoint
- * will be along the vector [1, 1, 1] from the center of the scene bounds,
- * at a distance that -should- have the object(s) in the field of view.
- *
- * @author Rex Melton
- * @version $Revision: 1.10 $
- */
-public class AutoConfigureViewpoint implements FrameStateListener {
-
-    /** The logging identifier of this class */
-    private static final String LOG_NAME = "AutoConfigureViewpoint";
-
-    /** The construct */
-    protected OGLConstruct construct;
-
-    /** Should the headlight be on */
-    protected boolean headlight;
-
-    /** The browser core */
-    protected OGLStandardBrowserCore core;
-
-    /** The frame state manager */
-    protected FrameStateManager fsm;
-
-    /** The error reporting mechanism */
-    protected ErrorReporter errorReporter;
-
-    /** Synchronization flag */
-    protected boolean configComplete;
-
-    /** The viewpoint */
-    protected OGLViewpoint viewpoint;
-
-    /** The navigation info */
-    protected OGLNavigationInfo navInfo;
-
-    /** The scene root, parent for the nav info and viewpoint nodes */
-    protected VRMLWorldRootNodeType root;
-
-    /** Flag used in the end of frame listener, indicating that the new nodes
-    * may be added to the scene */
-    protected boolean addNodes;
-
-    /**
-     * Constructor
-     *
-     * @param construct The construct containing the scene for which to configure a viewpoint.
-     * @param headlight Should the headlight be on
-     */
-    public AutoConfigureViewpoint( OGLConstruct construct, boolean headlight ) {
-        this.construct = construct;
-	this.headlight = headlight;
-        core = construct.getBrowserCore( );
-        fsm = construct.getFrameStateManager( );
-        errorReporter = construct.getErrorReporter( );
-    }
-
-    //----------------------------------------------------------
-    // Methods defined by FrameStateListener
-    //----------------------------------------------------------
-
-    @Override
-    public void allEventsComplete( ) {
-        if ( addNodes ) {
-            // add and bind the new viewpoint and nav info
-            root.addChild( navInfo );
-            int index = navInfo.getFieldIndex( "set_bind" );
-            navInfo.setValue( index, true );
-            navInfo.setupFinished( );
-
-            root.addChild( viewpoint );
-            index = viewpoint.getFieldIndex( "set_bind" );
-            viewpoint.setValue( index, true );
-            viewpoint.setupFinished( );
-
-            addNodes = false;
-            fsm.addEndOfThisFrameListener( this );
-
-        } else {
-            synchronized ( this ) {
-                    configComplete = true;
-                    notify( );
-            }
-        }
-    }
-
-    //----------------------------------------------------------
-    // Local Methods
-    //----------------------------------------------------------
-
-    /**
-     * Create and configure a new viewpoint. Wait for the node to be
-     * added and bound in the scene before returning. If the bounds of
-     * the scene could not be determined, no configuration is performed
-     * and the method returns immediately.
-     *
-     * @return true if the viewpoint was added successfully, false otherwise.
-     */
-    public boolean configure( ) {
-
-        // bounding box size
-        float[] size = new float[3];
-        // the extents
-        float[] max = new float[3];
-        float[] min = new float[3];
-        BoundingBox bounds = getWorldBounds( );
-        if ( bounds == null ) {
-            errorReporter.errorReport(
-                    LOG_NAME + ": (warning) Unable to determine scene bounds, possibly no Shape geometry is defined. "
-                    + "No Viewpoint configured.", null);
-            // original exception: "Error: AutoConfigureViewpoint: Could not determine scene bounds. No Viewpoint configured."
-            // test scene C:\x3d-code\www.web3d.org\x3d\content\examples\Basic/UniversalMediaPanoramas/desert2.x3d
-            min = new float[]{-10.0f, -10.0f, -10.0f}; // arbitrary bounds, likely for scene with no geometry
-            max = new float[]{10.0f, 10.0f, 10.0f};
-        } else {
-            bounds.getSize(size);
-            bounds.getExtents(min, max);
-        }
-
-        // roughly, the model center
-        float x_center = ( min[0] + max[0] ) / 2;
-        float y_center = ( min[1] + max[1] ) / 2;
-        float z_center = ( min[2] + max[2] ) / 2;
-
-        float[] center = new float[]{ x_center, y_center, z_center };
-
-        // the extents, by half
-        float x = size[0];
-        float y = size[1];
-        float z = size[2];
-
-        // radius of the bounding sphere
-        float radius = (float)Math.sqrt((x * x) + (y * y) + (z * z));
-
-        // given a field-of-view of 45 degrees - the distance from
-        // the center of the bounding sphere at which the sphere
-        // surface should be within the f-o-v (0.392699 radians == 22.5 degrees)
-        // note, the sin gives the distance to the sphere's visible edge,
-        // a tan would give the distance to the center. the edge distance
-        // is greater and moves the position a bit farther away - providing
-        // some margin between the actual f-o-v and the bounding sphere
-        float distance = radius / (float)(Math.sin(0.392699));
-
-        // equidistant components of the distance to combine with
-        // the object center.
-        float offset = ( distance / (float)Math.sqrt(3.0) );
-
-        float near_clip = 0;
-
-        // if the distance away is less than the clipping plane
-        // then move the clipping plane
-        if (offset < 0.125f) {
-            near_clip = offset * 0.9f;
-        }
-
-        float[] position = new float[]{
-                x_center + offset, y_center + offset, z_center + offset};
-
-        ///////////////////////////////////////////////////////////////////////////////
-        // calculate an orientation that places the model at the focus
-
-        Point3f from = new Point3f(position);
-        Point3f to = new Point3f(center);
-        Vector3f Yup = new Vector3f(0, 1, 0);
-
-        MatrixUtils mu = new MatrixUtils();
-        Matrix4f rot = new Matrix4f();
-        mu.lookAt(from, to, Yup, rot);
-        mu.inverse(rot, rot);
-
-        AxisAngle4f a = new AxisAngle4f();
-        a.set(rot);
-        float[] orientation = new float[4];
-        a.get(orientation);
-
-        ///////////////////////////////////////////////////////////////////////////////
-
-        VRMLScene scene = core.getScene( );
-        VRMLNodeFactory factory = scene.getNodeFactory( );
-        viewpoint = (OGLViewpoint)factory.createVRMLNode( "Viewpoint", false );
-
-        int index = viewpoint.getFieldIndex( "set_position" );
-        viewpoint.setValue( index, position, 3 );
-
-        index = viewpoint.getFieldIndex( "set_orientation" );
-        viewpoint.setValue( index, orientation, 4 );
-
-        navInfo = (OGLNavigationInfo)factory.createVRMLNode( "NavigationInfo", false );
-        navInfo.setType(new String[0], 0);
-
-        navInfo.setHeadlight( headlight );
-        if (near_clip > 0) {
-            navInfo.setAvatarSize(new float[] { near_clip * 2, 1.6f, 0.75f }, 3);
-        }
-
-        root = (VRMLWorldRootNodeType)scene.getRootNode( );
-        addNodes = true;
-
-        // wait for the new nodes to be added to the scene and bound before returning.
-        synchronized ( this ) {
-            fsm.addEndOfThisFrameListener( this );
-            configComplete = false;
-            while( !configComplete ) {
-                try {
-                    wait( );
-                } catch ( InterruptedException ie ) {
-                }
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Return the bounds of the 3D world
-     *
-     * @return the bounds of the 3D world
-     */
-    private BoundingBox getWorldBounds( ) {
-
-        DisplayCollection displayManager = construct.getDisplayCollection( );
-        Layer[] layers = new Layer[displayManager.numLayers()];
-        displayManager.getLayers(layers);
-        SimpleScene currentScene;
-        SimpleViewport viewport;
-        SimpleLayer layer;
-        Group rootNode;
-        BoundingVolume bounds;
-
-        for (Layer layer1 : layers) {
-            if (!(layer1 instanceof SimpleLayer)) {
-                continue;
-            }
-            layer = (SimpleLayer) layer1;
-            if (!(layer.getViewport() instanceof SimpleViewport)) {
-                continue;
-            }
-            viewport = (SimpleViewport)layer.getViewport();
-            if (!(viewport.getScene() instanceof SimpleScene)) {
-                continue;
-            }
-            currentScene = viewport.getScene();
-            rootNode = currentScene.getRenderedGeometry();
-            bounds = rootNode.getBounds();
-            if ( bounds instanceof BoundingBox ) {
-                return (BoundingBox) bounds;
-            }
-        }
-        return null;
-    }
-}
+/*****************************************************************************
+ *                        Web3d.org Copyright (c) 2007 - 2008
+ *                               Java Source
+ *
+ * This source is licensed under the GNU LGPL v2.1
+ * Please read http://www.gnu.org/copyleft/lgpl.html for more information
+ *
+ * This software comes with the standard NO WARRANTY disclaimer for any
+ * purpose. Use it at your own risk. If there's a problem you get to fix it.
+ *
+ *****************************************************************************/
+
+package org.xj3d.ui.construct.ogl;
+
+// External Imports
+import javax.vecmath.AxisAngle4f;
+import javax.vecmath.Matrix4f;
+import javax.vecmath.Point3f;
+import javax.vecmath.Vector3f;
+
+import org.j3d.aviatrix3d.BoundingBox;
+import org.j3d.aviatrix3d.Group;
+import org.j3d.aviatrix3d.Layer;
+import org.j3d.aviatrix3d.SimpleLayer;
+import org.j3d.aviatrix3d.SimpleScene;
+import org.j3d.aviatrix3d.SimpleViewport;
+
+import org.j3d.aviatrix3d.management.DisplayCollection;
+
+import org.j3d.aviatrix3d.rendering.BoundingVolume;
+
+import org.j3d.util.ErrorReporter;
+import org.j3d.util.MatrixUtils;
+
+// Local Imports
+import org.web3d.vrml.lang.VRMLNodeFactory;
+
+import org.web3d.vrml.nodes.VRMLScene;
+import org.web3d.vrml.nodes.VRMLWorldRootNodeType;
+
+import org.web3d.vrml.nodes.FrameStateListener;
+import org.web3d.vrml.nodes.FrameStateManager;
+
+import org.web3d.vrml.renderer.ogl.browser.OGLStandardBrowserCore;
+
+import org.web3d.vrml.renderer.ogl.nodes.navigation.OGLNavigationInfo;
+import org.web3d.vrml.renderer.ogl.nodes.navigation.OGLViewpoint;
+
+/**
+ * Utility module for the ThumbnailRecorder that will attempt to create
+ * a useful default viewpoint of the loaded scene. The generated viewpoint
+ * will be along the vector [1, 1, 1] from the center of the scene bounds,
+ * at a distance that -should- have the object(s) in the field of view.
+ *
+ * @author Rex Melton
+ * @version $Revision: 1.10 $
+ */
+public class AutoConfigureViewpoint implements FrameStateListener {
+
+    /** The logging identifier of this class */
+    private static final String LOG_NAME = "AutoConfigureViewpoint";
+
+    /** The construct */
+    protected OGLConstruct construct;
+
+    /** Should the headlight be on */
+    protected boolean headlight;
+
+    /** The browser core */
+    protected OGLStandardBrowserCore core;
+
+    /** The frame state manager */
+    protected FrameStateManager fsm;
+
+    /** The error reporting mechanism */
+    protected ErrorReporter errorReporter;
+
+    /** Synchronization flag */
+    protected boolean configComplete;
+
+    /** The viewpoint */
+    protected OGLViewpoint viewpoint;
+
+    /** The navigation info */
+    protected OGLNavigationInfo navInfo;
+
+    /** The scene root, parent for the nav info and viewpoint nodes */
+    protected VRMLWorldRootNodeType root;
+
+    /** Flag used in the end of frame listener, indicating that the new nodes
+    * may be added to the scene */
+    protected boolean addNodes;
+
+    /**
+     * Constructor
+     *
+     * @param construct The construct containing the scene for which to configure a viewpoint.
+     * @param headlight Should the headlight be on
+     */
+    public AutoConfigureViewpoint( OGLConstruct construct, boolean headlight ) {
+        this.construct = construct;
+	this.headlight = headlight;
+        core = construct.getBrowserCore( );
+        fsm = construct.getFrameStateManager( );
+        errorReporter = construct.getErrorReporter( );
+    }
+
+    //----------------------------------------------------------
+    // Methods defined by FrameStateListener
+    //----------------------------------------------------------
+
+    @Override
+    public void allEventsComplete( ) {
+        if ( addNodes ) {
+            // add and bind the new viewpoint and nav info
+            root.addChild( navInfo );
+            int index = navInfo.getFieldIndex( "set_bind" );
+            navInfo.setValue( index, true );
+            navInfo.setupFinished( );
+
+            root.addChild( viewpoint );
+            index = viewpoint.getFieldIndex( "set_bind" );
+            viewpoint.setValue( index, true );
+            viewpoint.setupFinished( );
+
+            addNodes = false;
+            fsm.addEndOfThisFrameListener( this );
+
+        } else {
+            synchronized ( this ) {
+                    configComplete = true;
+                    notify( );
+            }
+        }
+    }
+
+    //----------------------------------------------------------
+    // Local Methods
+    //----------------------------------------------------------
+
+    /**
+     * Create and configure a new viewpoint. Wait for the node to be
+     * added and bound in the scene before returning. If the bounds of
+     * the scene could not be determined, no configuration is performed
+     * and the method returns immediately.
+     *
+     * @return true if the viewpoint was added successfully, false otherwise.
+     */
+    public boolean configure( ) {
+
+        // bounding box size
+        float[] size = new float[3];
+        // the extents
+        float[] max = new float[3];
+        float[] min = new float[3];
+        BoundingBox bounds = getWorldBounds( );
+        if ( bounds == null ) {
+            errorReporter.errorReport(
+                    LOG_NAME + ": (warning) Unable to determine scene bounds, possibly no Shape geometry is defined. "
+                    + "No Viewpoint configured.", null);
+            // original exception: "Error: AutoConfigureViewpoint: Could not determine scene bounds. No Viewpoint configured."
+            // test scene C:\x3d-code\www.web3d.org\x3d\content\examples\Basic/UniversalMediaPanoramas/desert2.x3d
+            min = new float[]{-10.0f, -10.0f, -10.0f}; // arbitrary bounds, likely for scene with no geometry
+            max = new float[]{10.0f, 10.0f, 10.0f};
+        } else {
+            bounds.getSize(size);
+            bounds.getExtents(min, max);
+        }
+
+        // roughly, the model center
+        float x_center = ( min[0] + max[0] ) / 2;
+        float y_center = ( min[1] + max[1] ) / 2;
+        float z_center = ( min[2] + max[2] ) / 2;
+
+        float[] center = new float[]{ x_center, y_center, z_center };
+
+        // the extents, by half
+        float x = size[0];
+        float y = size[1];
+        float z = size[2];
+
+        // radius of the bounding sphere
+        float radius = (float)Math.sqrt((x * x) + (y * y) + (z * z));
+
+        // given a field-of-view of 45 degrees - the distance from
+        // the center of the bounding sphere at which the sphere
+        // surface should be within the f-o-v (0.392699 radians == 22.5 degrees)
+        // note, the sin gives the distance to the sphere's visible edge,
+        // a tan would give the distance to the center. the edge distance
+        // is greater and moves the position a bit farther away - providing
+        // some margin between the actual f-o-v and the bounding sphere
+        float distance = radius / (float)(Math.sin(0.392699));
+
+        // equidistant components of the distance to combine with
+        // the object center.
+        float offset = ( distance / (float)Math.sqrt(3.0) );
+
+        float near_clip = 0;
+
+        // if the distance away is less than the clipping plane
+        // then move the clipping plane
+        if (offset < 0.125f) {
+            near_clip = offset * 0.9f;
+        }
+
+        float[] position = new float[]{
+                x_center + offset, y_center + offset, z_center + offset};
+
+        ///////////////////////////////////////////////////////////////////////////////
+        // calculate an orientation that places the model at the focus
+
+        Point3f from = new Point3f(position);
+        Point3f to = new Point3f(center);
+        Vector3f Yup = new Vector3f(0, 1, 0);
+
+        MatrixUtils mu = new MatrixUtils();
+        Matrix4f rot = new Matrix4f();
+        mu.lookAt(from, to, Yup, rot);
+        mu.inverse(rot, rot);
+
+        AxisAngle4f a = new AxisAngle4f();
+        a.set(rot);
+        float[] orientation = new float[4];
+        a.get(orientation);
+
+        ///////////////////////////////////////////////////////////////////////////////
+
+        VRMLScene scene = core.getScene( );
+        VRMLNodeFactory factory = scene.getNodeFactory( );
+        viewpoint = (OGLViewpoint)factory.createVRMLNode( "Viewpoint", false );
+
+        int index = viewpoint.getFieldIndex( "set_position" );
+        viewpoint.setValue( index, position, 3 );
+
+        index = viewpoint.getFieldIndex( "set_orientation" );
+        viewpoint.setValue( index, orientation, 4 );
+
+        navInfo = (OGLNavigationInfo)factory.createVRMLNode( "NavigationInfo", false );
+        navInfo.setType(new String[0], 0);
+
+        navInfo.setHeadlight( headlight );
+        if (near_clip > 0) {
+            navInfo.setAvatarSize(new float[] { near_clip * 2, 1.6f, 0.75f }, 3);
+        }
+
+        root = (VRMLWorldRootNodeType)scene.getRootNode( );
+        addNodes = true;
+
+        // wait for the new nodes to be added to the scene and bound before returning.
+        synchronized ( this ) {
+            fsm.addEndOfThisFrameListener( this );
+            configComplete = false;
+            while( !configComplete ) {
+                try {
+                    wait( );
+                } catch ( InterruptedException ie ) {
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Return the bounds of the 3D world
+     *
+     * @return the bounds of the 3D world
+     */
+    private BoundingBox getWorldBounds( ) {
+
+        DisplayCollection displayManager = construct.getDisplayCollection( );
+        Layer[] layers = new Layer[displayManager.numLayers()];
+        displayManager.getLayers(layers);
+        SimpleScene currentScene;
+        SimpleViewport viewport;
+        SimpleLayer layer;
+        Group rootNode;
+        BoundingVolume bounds;
+
+        for (Layer layer1 : layers) {
+            if (!(layer1 instanceof SimpleLayer)) {
+                continue;
+            }
+            layer = (SimpleLayer) layer1;
+            if (!(layer.getViewport() instanceof SimpleViewport)) {
+                continue;
+            }
+            viewport = (SimpleViewport)layer.getViewport();
+            if (!(viewport.getScene() instanceof SimpleScene)) {
+                continue;
+            }
+            currentScene = viewport.getScene();
+            rootNode = currentScene.getRenderedGeometry();
+            bounds = rootNode.getBounds();
+            if ( bounds instanceof BoundingBox ) {
+                return (BoundingBox) bounds;
+            }
+        }
+        return null;
+    }
+}
diff --git a/src/java/vrml/eai/Browser.java b/src/java/vrml/eai/Browser.java
index 34183d468cf19080833bd051e2637da9907d3031..f971285807643fcccf969cbf16339ea41752bc62 100644
--- a/src/java/vrml/eai/Browser.java
+++ b/src/java/vrml/eai/Browser.java
@@ -1,367 +1,364 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL v2.1. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai;
-
-import vrml.eai.event.BrowserListener;
-import vrml.eai.field.InvalidEventInException;
-import vrml.eai.field.InvalidEventOutException;
-
-/**
- * <p>
- * Basic browser interface that represents the interface to the VRML browser
- * from any application. Individual VRML browser implementors are to extend this
- * interface and provide this functionality. The individual users will not see
- * anything but this interface.
- *  </p>
- * <p>
- * A number of the methods in this application can take strings representing URLs.
- * Relative URL strings contained in URL fields of nodes or these method
- * arguments are interpreted as follows:
- *  </p>
- * <p>
- * Relative URLs are treated as per clause B.3.5 of the EAI Java Bindings
- *  </p>
- *
- * @version 1.1 25 April 1998
- */
-public interface Browser
-{
-  /**
-   * Get the name of the browser. The name is an implementation specific
-   * string representing the browser.
-   *
-   * @return The name of the browser or null if not supported
-   * @exception InvalidBrowserException The dispose method has been called on
-   *    this browser reference.
-   * @exception ConnectionException An error occurred in the connection to the
-   *    browser.
-   */
-  String getName()
-    throws InvalidBrowserException;
-
-  /**
-   * Get the version of the browser. Returns an implementation specific
-   * representation of the version number.
-   *
-   * @return The version of the browser or null if not supported
-   * @exception InvalidBrowserException The dispose method has been called on
-   *    this browser reference.
-   * @exception ConnectionException An error occurred in the connection to the
-   *    browser.
-   */
-  String getVersion()
-    throws InvalidBrowserException;
-
-  /**
-   * Get the current velocity of the bound viewpoint in meters per second.
-   * The velocity is defined in terms of the world values, not the local
-   * coordinate system of the viewpoint.
-   *
-   * @return The velocity in m/s or 0.0 if not supported
-   * @exception InvalidBrowserException The dispose method has been called on
-   *    this browser reference.
-   * @exception ConnectionException An error occurred in the connection to the
-   *    browser.
-   */
-  float getCurrentSpeed()
-    throws InvalidBrowserException;
-
-  /**
-   * Get the current frame rate of the browser in frames per second.
-   *
-   * @return The current frame rate or 0.0 if not supported
-   * @exception InvalidBrowserException The dispose method has been called on
-   *    this browser reference.
-   * @exception ConnectionException An error occurred in the connection to the
-   *    browser.
-   */
-  float getCurrentFrameRate()
-    throws InvalidBrowserException;
-
-  /**
-   * Get the fully qualified URL of the currently loaded world. This returns
-   * the entire URL including any possible arguments that might be associated
-   * with a CGI call or similar mechanism. If the initial world is replaced
-   * with <code>loadURL</code> then the string will reflect the new URL. If
-   * <code>replaceWorld</code> is called then the URL still represents the
-   * original world.
-   *
-   * @return A string of the URL or null if not supported.
-   * @see #loadURL
-   * @see #replaceWorld
-   * @exception InvalidBrowserException The dispose method has been called on
-   *    this browser reference.
-   * @exception URLUnavailableException The URL is not available because a
-   *    world has not been loaded
-   * @exception ConnectionException An error occurred in the connection to the
-   *    browser.
-   */
-  String getWorldURL()
-    throws InvalidBrowserException, URLUnavailableException;
-
-  /**
-   * Replace the current world with the given nodes. Replaces the entire
-   * contents of the VRML world with the new nodes. Any node references that
-   * belonged to the previous world are still valid but no longer form part of
-   * the scene graph (unless it is these nodes passed to this method). The
-   * URL of the world still represents the just unloaded world.
-   *  <p>
-   * Calling this method causes a SHUTDOWN event followed by an INITIALIZED
-   * event to be generated.
-   *
-   * @param nodes The list of nodes to use as the new root of the world
-   * @exception IllegalArgumentException if the nodes are not valid VRML nodes
-   * @exception InvalidBrowserException The dispose method has been called on
-   *    this browser reference.
-   * @exception ConnectionException An error occurred in the connection to the
-   *    browser.
-   */
-  void replaceWorld(Node[] nodes)
-    throws IllegalArgumentException, InvalidBrowserException;
-
-  /**
-   * Load the URL as the new root of the scene. Replaces all the current
-   * scene graph with the new world. A non-blocking call that will change the
-   * contents at some time in the future.
-   *  <p>
-   * Generates an immediate SHUTDOWN event and then when the new contents are
-   * ready to be loaded, sends an INITIALIZED event.
-   *
-   * @param url The list of URLs in decreasing order of preference as defined
-   *   in the VRML97 specification.
-   * @param parameter The list of parameters to accompany the load call as
-   *   defined in the Anchor node specification of VRML97
-   * @exception InvalidBrowserException The dispose method has been called on
-   *    this browser reference.
-   * @exception InvalidURLException All of the URLs passed to this method are
-   *    bogus and cannot be translated to usable values
-   * @exception ConnectionException An error occurred in the connection to the
-   *    browser.
-   */
-  void loadURL(String[] url, String[] parameter)
-    throws InvalidBrowserException, InvalidURLException;
-
-  /**
-   * Set the description of the current world. If the world is operating as
-   * part of a web browser then it shall attempt to set the title of the
-   * window. If the browser is from a component then the result is dependent
-   * on the implementation
-   *
-   * @param desc The description string to set.
-   * @exception InvalidBrowserException The dispose method has been called on
-   *    this browser reference.
-   * @exception ConnectionException An error occurred in the connection to the
-   *    browser.
-   */
-  void setDescription(String desc)
-    throws InvalidBrowserException;
-
-  /**
-   * Parse the given string and turn this into a list of VRML nodes. Method
-   * is a blocking call that won't return until all of the top level nodes
-   * defined in the string have been returned.
-   *  <p>
-   * At the point that this method returns, external files such as textures,
-   * sounds and inlines may not have been loaded.
-   *  <p>
-   * The string may contain all legal VRML syntax. The VRML header line is not
-   * required to be present in the string.
-   *
-   * @param vrmlString The string containing VRML string syntax
-   * @return A list of the top level nodes in VRML representation as defined
-   *    in the parameter
-   * @exception InvalidVrmlException If the string does not contain legal
-   *   VRML syntax or no node instantiations
-   * @exception InvalidBrowserException The dispose method has been called on
-   *    this browser reference.
-   * @exception ConnectionException An error occurred in the connection to the
-   *    browser.
-   */
-  Node[] createVrmlFromString(String vrmlString)
-    throws InvalidBrowserException, InvalidVrmlException;
-
-  /**
-   * Create and load VRML from the given URL and place the returned values
-   * as nodes into the given VRML node in the scene. The difference between
-   * this and loadURL is that this method does not replace the entire scene
-   * with the contents from the URL. Instead, it places the return values
-   * as events in the nominated node and MFNode eventIn.
-   *
-   * @param url The list of URLs in decreasing order of preference as defined
-   *   in the VRML97 specification.
-   * @param node The destination node for the VRML code to be sent to.
-   * @param eventIn The name of the MFNode eventIn to send the nodes to.
-   * @exception InvalidNodeException The nominated destination node has been
-   *   disposed of
-   * @exception InvalidBrowserException The dispose method has been called on
-   *    this browser reference.
-   * @exception InvalidURLException All of the URLs passed to this method are
-   *    bogus and cannot be translated to usable values
-   * @exception ConnectionException An error occurred in the connection to the
-   *    browser.
-   */
-  void createVrmlFromURL(String[] url, Node node, String eventIn)
-    throws InvalidBrowserException, InvalidNodeException, InvalidURLException;
-
-  /**
-   * Get a DEF node by name. Nodes given DEF names in the root scene graph
-   * are available to be retrieved by this method. DEFed nodes in Inlines,
-   * createVrmlFromString and createVrmlFromURL are not available.
-   *
-   * @param name The name of the DEF node to retrieve
-   * @return A reference to that node
-   * @exception InvalidNodeException The named node does not exist or is not
-   *    accessible.
-   * @exception InvalidBrowserException The dispose method has been called on
-   *    this browser reference.
-   * @exception URLUnavailableException The URL is not available because a
-   *    world has not been loaded
-   * @exception ConnectionException An error occurred in the connection to the
-   *    browser.
-   */
-  Node getNode(String name)
-      throws InvalidNodeException, InvalidBrowserException, URLUnavailableException;
-
-  /**
-   * Add a route between two nodes, from an eventOut to an eventIn. If the
-   * ROUTE already exists, this method silently exits. It does not attempt
-   * to add a second parallel ROUTE.
-   *
-   * @param fromNode The source node for the route
-   * @param eventOut The eventOut source of the route
-   * @param toNode The destination node of the route
-   * @param eventIn The eventIn destination of the route
-   * @exception InvalidEventOutException if the named eventOut does not exist
-   * @exception InvalidEventInException if the named eventIn does not exist.
-   * @exception InvalidNodeException The nominated destination or source node
-   *   has been disposed of
-   * @exception InvalidBrowserException The dispose method has been called on
-   *    this browser reference.
-   * @exception ConnectionException An error occurred in the connection to the
-   *    browser.
-   */
-  void addRoute(Node fromNode, String eventOut,
-                       Node toNode,   String eventIn)
-      throws InvalidBrowserException,
-             InvalidEventOutException,
-             InvalidEventInException,
-             InvalidNodeException;
-
-  /**
-   * Delete a route between two nodes. If the route does not exist, the
-   * method silently exits.
-   *
-   * @param fromNode The source node for the route
-   * @param eventOut The eventOut source of the route
-   * @param toNode The destination node of the route
-   * @param eventIn The eventIn destination of the route
-   * @exception InvalidEventOutException if the named eventOut does not exist
-   * @exception InvalidEventInException if the named eventIn does not exist.
-   * @exception InvalidNodeException The nominated destination or source node
-   *   has been disposed of
-   * @exception InvalidBrowserException The dispose method has been called on
-   *    this browser reference.
-   * @exception ConnectionException An error occurred in the connection to the
-   *    browser.
-   */
-  void deleteRoute(Node fromNode, String eventOut,
-                          Node toNode,   String eventIn)
-      throws InvalidBrowserException,
-             InvalidEventOutException,
-             InvalidEventInException,
-             InvalidNodeException;
-
-  /**
-   * Lock the output from the external interface to the browser as the code
-   * is about to begin a series of updates. No events will be passed to the
-   * VRML world. They will be buffered pending release due to a subsequent
-   * call to endUpdate.
-   *  <p>
-   * This call is a nesting call which means subsequent calls to beginUpdate
-   * are kept on a stack. No events will be released to the VRML browser
-   * until as many endUpdates have been called as beginUpdate.
-   *
-   * @exception InvalidBrowserException The dispose method has been called on
-   *    this browser reference.
-   * @exception ConnectionException An error occurred in the connection to the
-   *    browser.
-   */
-  void beginUpdate()
-      throws InvalidBrowserException;
-
-  /**
-   * Release the output of events from the external interface into the
-   * VRML browser. All events posted to this point from the last time that
-   * beginUpdate was called are released into the VRML browser for
-   * processing at the next available opportunity.
-   *  <p>
-   * This call is a nesting call which means subsequent calls to beginUpdate
-   * are kept on a stack. No events will be released to the VRML browser
-   * until as many endUpdates have been called as beginUpdate.
-   *  <p>
-   * If no beginUpdate has been called before calling this method, it has
-   * no effect.
-   *
-   * @exception InvalidBrowserException The dispose method has been called on
-   *    this browser reference.
-   * @exception ConnectionException An error occurred in the connection to the
-   *    browser.
-   */
-  void endUpdate()
-      throws InvalidBrowserException;
-
-  /**
-   * Add a listener for browser events. Any changes in the browser will be
-   * sent to this listener. The order of calling listeners is not guaranteed.
-   * Checking is performed on whether the nominated listener is already
-   * registered to ensure that multiple registration cannot take place.
-   * Therefore it is possible to multiply register the one class
-   * instance while only receiving one event.
-   *
-   * @param l The listener to add.
-   * @exception NullPointerException If the provided listener reference is
-   *     null
-   * @exception InvalidBrowserException The dispose method has been called on
-   *    this browser reference.
-   * @exception ConnectionException An error occurred in the connection to the
-   *    browser.
-   */
-  void addBrowserListener(BrowserListener l)
-      throws InvalidBrowserException;
-
-  /**
-   * Remove a listener for browser events. After calling this method, the
-   * listener will no longer receive events from this browser instance. If the
-   * listener passed as an argument is not currently registered, the method
-   * will silently exit.
-   *
-   * @param l The listener to remove
-   * @exception NullPointerException If the provided listener reference is
-   *     null
-   * @exception InvalidBrowserException The dispose method has been called on
-   *    this browser reference.
-   * @exception ConnectionException An error occurred in the connection to the
-   *    browser.
-   */
-  void removeBrowserListener(BrowserListener l)
-      throws InvalidBrowserException;
-
-  /**
-   * Dispose the resources that are used by this instance. Should be called
-   * just prior to leaving the application.
-   */
-  void dispose();
-}
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL v2.1. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai;
+
+import vrml.eai.event.BrowserListener;
+import vrml.eai.field.InvalidEventInException;
+import vrml.eai.field.InvalidEventOutException;
+
+/**
+ * Basic browser interface that represents the interface to the VRML browser
+ * from any application. Individual VRML browser implementors are to extend this
+ * interface and provide this functionality. The individual users will not see
+ * anything but this interface.
+ *  <p>
+ * A number of the methods in this application can take strings representing URLs.
+ * Relative URL strings contained in URL fields of nodes or these method
+ * arguments are interpreted as follows:
+ *  <p>
+ * Relative URLs are treated as per clause B.3.5 of the EAI Java Bindings
+ *  <p>
+ *
+ * @version 1.1 25 April 1998
+ */
+public interface Browser
+{
+  /**
+   * Get the name of the browser. The name is an implementation specific
+   * string representing the browser.
+   *
+   * @return The name of the browser or null if not supported
+   * @exception InvalidBrowserException The dispose method has been called on
+   *    this browser reference.
+   * @exception ConnectionException An error occurred in the connection to the
+   *    browser.
+   */
+  String getName()
+    throws InvalidBrowserException;
+
+  /**
+   * Get the version of the browser. Returns an implementation specific
+   * representation of the version number.
+   *
+   * @return The version of the browser or null if not supported
+   * @exception InvalidBrowserException The dispose method has been called on
+   *    this browser reference.
+   * @exception ConnectionException An error occurred in the connection to the
+   *    browser.
+   */
+  String getVersion()
+    throws InvalidBrowserException;
+
+  /**
+   * Get the current velocity of the bound viewpoint in meters per second.
+   * The velocity is defined in terms of the world values, not the local
+   * coordinate system of the viewpoint.
+   *
+   * @return The velocity in m/s or 0.0 if not supported
+   * @exception InvalidBrowserException The dispose method has been called on
+   *    this browser reference.
+   * @exception ConnectionException An error occurred in the connection to the
+   *    browser.
+   */
+  float getCurrentSpeed()
+    throws InvalidBrowserException;
+
+  /**
+   * Get the current frame rate of the browser in frames per second.
+   *
+   * @return The current frame rate or 0.0 if not supported
+   * @exception InvalidBrowserException The dispose method has been called on
+   *    this browser reference.
+   * @exception ConnectionException An error occurred in the connection to the
+   *    browser.
+   */
+  float getCurrentFrameRate()
+    throws InvalidBrowserException;
+
+  /**
+   * Get the fully qualified URL of the currently loaded world. This returns
+   * the entire URL including any possible arguments that might be associated
+   * with a CGI call or similar mechanism. If the initial world is replaced
+   * with <code>loadURL</code> then the string will reflect the new URL. If
+   * <code>replaceWorld</code> is called then the URL still represents the
+   * original world.
+   *
+   * @return A string of the URL or null if not supported.
+   * @see #loadURL
+   * @see #replaceWorld
+   * @exception InvalidBrowserException The dispose method has been called on
+   *    this browser reference.
+   * @exception URLUnavailableException The URL is not available because a
+   *    world has not been loaded
+   * @exception ConnectionException An error occurred in the connection to the
+   *    browser.
+   */
+  String getWorldURL()
+    throws InvalidBrowserException, URLUnavailableException;
+
+  /**
+   * Replace the current world with the given nodes. Replaces the entire
+   * contents of the VRML world with the new nodes. Any node references that
+   * belonged to the previous world are still valid but no longer form part of
+   * the scene graph (unless it is these nodes passed to this method). The
+   * URL of the world still represents the just unloaded world.
+   *  <p>
+   * Calling this method causes a SHUTDOWN event followed by an INITIALIZED
+   * event to be generated.
+   *
+   * @param nodes The list of nodes to use as the new root of the world
+   * @exception IllegalArgumentException if the nodes are not valid VRML nodes
+   * @exception InvalidBrowserException The dispose method has been called on
+   *    this browser reference.
+   * @exception ConnectionException An error occurred in the connection to the
+   *    browser.
+   */
+  void replaceWorld(Node[] nodes)
+    throws IllegalArgumentException, InvalidBrowserException;
+
+  /**
+   * Load the URL as the new root of the scene. Replaces all the current
+   * scene graph with the new world. A non-blocking call that will change the
+   * contents at some time in the future.
+   *  <p>
+   * Generates an immediate SHUTDOWN event and then when the new contents are
+   * ready to be loaded, sends an INITIALIZED event.
+   *
+   * @param url The list of URLs in decreasing order of preference as defined
+   *   in the VRML97 specification.
+   * @param parameter The list of parameters to accompany the load call as
+   *   defined in the Anchor node specification of VRML97
+   * @exception InvalidBrowserException The dispose method has been called on
+   *    this browser reference.
+   * @exception InvalidURLException All of the URLs passed to this method are
+   *    bogus and cannot be translated to usable values
+   * @exception ConnectionException An error occurred in the connection to the
+   *    browser.
+   */
+  void loadURL(String[] url, String[] parameter)
+    throws InvalidBrowserException, InvalidURLException;
+
+  /**
+   * Set the description of the current world. If the world is operating as
+   * part of a web browser then it shall attempt to set the title of the
+   * window. If the browser is from a component then the result is dependent
+   * on the implementation
+   *
+   * @param desc The description string to set.
+   * @exception InvalidBrowserException The dispose method has been called on
+   *    this browser reference.
+   * @exception ConnectionException An error occurred in the connection to the
+   *    browser.
+   */
+  void setDescription(String desc)
+    throws InvalidBrowserException;
+
+  /**
+   * Parse the given string and turn this into a list of VRML nodes. Method
+   * is a blocking call that won't return until all of the top level nodes
+   * defined in the string have been returned.
+   *  <p>
+   * At the point that this method returns, external files such as textures,
+   * sounds and inlines may not have been loaded.
+   *  <p>
+   * The string may contain all legal VRML syntax. The VRML header line is not
+   * required to be present in the string.
+   *
+   * @param vrmlString The string containing VRML string syntax
+   * @return A list of the top level nodes in VRML representation as defined
+   *    in the parameter
+   * @exception InvalidVrmlException If the string does not contain legal
+   *   VRML syntax or no node instantiations
+   * @exception InvalidBrowserException The dispose method has been called on
+   *    this browser reference.
+   * @exception ConnectionException An error occurred in the connection to the
+   *    browser.
+   */
+  Node[] createVrmlFromString(String vrmlString)
+    throws InvalidBrowserException, InvalidVrmlException;
+
+  /**
+   * Create and load VRML from the given URL and place the returned values
+   * as nodes into the given VRML node in the scene. The difference between
+   * this and loadURL is that this method does not replace the entire scene
+   * with the contents from the URL. Instead, it places the return values
+   * as events in the nominated node and MFNode eventIn.
+   *
+   * @param url The list of URLs in decreasing order of preference as defined
+   *   in the VRML97 specification.
+   * @param node The destination node for the VRML code to be sent to.
+   * @param eventIn The name of the MFNode eventIn to send the nodes to.
+   * @exception InvalidNodeException The nominated destination node has been
+   *   disposed of
+   * @exception InvalidBrowserException The dispose method has been called on
+   *    this browser reference.
+   * @exception InvalidURLException All of the URLs passed to this method are
+   *    bogus and cannot be translated to usable values
+   * @exception ConnectionException An error occurred in the connection to the
+   *    browser.
+   */
+  void createVrmlFromURL(String[] url, Node node, String eventIn)
+    throws InvalidBrowserException, InvalidNodeException, InvalidURLException;
+
+  /**
+   * Get a DEF node by name. Nodes given DEF names in the root scene graph
+   * are available to be retrieved by this method. DEFed nodes in Inlines,
+   * createVrmlFromString and createVrmlFromURL are not available.
+   *
+   * @param name The name of the DEF node to retrieve
+   * @return A reference to that node
+   * @exception InvalidNodeException The named node does not exist or is not
+   *    accessible.
+   * @exception InvalidBrowserException The dispose method has been called on
+   *    this browser reference.
+   * @exception URLUnavailableException The URL is not available because a
+   *    world has not been loaded
+   * @exception ConnectionException An error occurred in the connection to the
+   *    browser.
+   */
+  Node getNode(String name)
+      throws InvalidNodeException, InvalidBrowserException, URLUnavailableException;
+
+  /**
+   * Add a route between two nodes, from an eventOut to an eventIn. If the
+   * ROUTE already exists, this method silently exits. It does not attempt
+   * to add a second parallel ROUTE.
+   *
+   * @param fromNode The source node for the route
+   * @param eventOut The eventOut source of the route
+   * @param toNode The destination node of the route
+   * @param eventIn The eventIn destination of the route
+   * @exception InvalidEventOutException if the named eventOut does not exist
+   * @exception InvalidEventInException if the named eventIn does not exist.
+   * @exception InvalidNodeException The nominated destination or source node
+   *   has been disposed of
+   * @exception InvalidBrowserException The dispose method has been called on
+   *    this browser reference.
+   * @exception ConnectionException An error occurred in the connection to the
+   *    browser.
+   */
+  void addRoute(Node fromNode, String eventOut,
+                       Node toNode,   String eventIn)
+      throws InvalidBrowserException,
+             InvalidEventOutException,
+             InvalidEventInException,
+             InvalidNodeException;
+
+  /**
+   * Delete a route between two nodes. If the route does not exist, the
+   * method silently exits.
+   *
+   * @param fromNode The source node for the route
+   * @param eventOut The eventOut source of the route
+   * @param toNode The destination node of the route
+   * @param eventIn The eventIn destination of the route
+   * @exception InvalidEventOutException if the named eventOut does not exist
+   * @exception InvalidEventInException if the named eventIn does not exist.
+   * @exception InvalidNodeException The nominated destination or source node
+   *   has been disposed of
+   * @exception InvalidBrowserException The dispose method has been called on
+   *    this browser reference.
+   * @exception ConnectionException An error occurred in the connection to the
+   *    browser.
+   */
+  void deleteRoute(Node fromNode, String eventOut,
+                          Node toNode,   String eventIn)
+      throws InvalidBrowserException,
+             InvalidEventOutException,
+             InvalidEventInException,
+             InvalidNodeException;
+
+  /**
+   * Lock the output from the external interface to the browser as the code
+   * is about to begin a series of updates. No events will be passed to the
+   * VRML world. They will be buffered pending release due to a subsequent
+   * call to endUpdate.
+   *  <p>
+   * This call is a nesting call which means subsequent calls to beginUpdate
+   * are kept on a stack. No events will be released to the VRML browser
+   * until as many endUpdates have been called as beginUpdate.
+   *
+   * @exception InvalidBrowserException The dispose method has been called on
+   *    this browser reference.
+   * @exception ConnectionException An error occurred in the connection to the
+   *    browser.
+   */
+  void beginUpdate()
+      throws InvalidBrowserException;
+
+  /**
+   * Release the output of events from the external interface into the
+   * VRML browser. All events posted to this point from the last time that
+   * beginUpdate was called are released into the VRML browser for
+   * processing at the next available opportunity.
+   *  <p>
+   * This call is a nesting call which means subsequent calls to beginUpdate
+   * are kept on a stack. No events will be released to the VRML browser
+   * until as many endUpdates have been called as beginUpdate.
+   *  <p>
+   * If no beginUpdate has been called before calling this method, it has
+   * no effect.
+   *
+   * @exception InvalidBrowserException The dispose method has been called on
+   *    this browser reference.
+   * @exception ConnectionException An error occurred in the connection to the
+   *    browser.
+   */
+  void endUpdate()
+      throws InvalidBrowserException;
+
+  /**
+   * Add a listener for browser events. Any changes in the browser will be
+   * sent to this listener. The order of calling listeners is not guaranteed.
+   * Checking is performed on whether the nominated listener is already
+   * registered to ensure that multiple registration cannot take place.
+   * Therefore it is possible to multiply register the one class
+   * instance while only receiving one event.
+   *
+   * @param l The listener to add.
+   * @exception NullPointerException If the provided listener reference is
+   *     null
+   * @exception InvalidBrowserException The dispose method has been called on
+   *    this browser reference.
+   * @exception ConnectionException An error occurred in the connection to the
+   *    browser.
+   */
+  void addBrowserListener(BrowserListener l)
+      throws InvalidBrowserException;
+
+  /**
+   * Remove a listener for browser events. After calling this method, the
+   * listener will no longer receive events from this browser instance. If the
+   * listener passed as an argument is not currently registered, the method
+   * will silently exit.
+   *
+   * @param l The listener to remove
+   * @exception NullPointerException If the provided listener reference is
+   *     null
+   * @exception InvalidBrowserException The dispose method has been called on
+   *    this browser reference.
+   * @exception ConnectionException An error occurred in the connection to the
+   *    browser.
+   */
+  void removeBrowserListener(BrowserListener l)
+      throws InvalidBrowserException;
+
+  /**
+   * Dispose the resources that are used by this instance. Should be called
+   * just prior to leaving the application.
+   */
+  void dispose();
+}
diff --git a/src/java/vrml/eai/BrowserFactory.java b/src/java/vrml/eai/BrowserFactory.java
index 3067a9e8097c95899a82ab5717c0fa979ab26fac..8d22750afb26d6a17c2871a900c4da708defa106 100644
--- a/src/java/vrml/eai/BrowserFactory.java
+++ b/src/java/vrml/eai/BrowserFactory.java
@@ -29,44 +29,37 @@ import java.util.Properties;
 // None
 
 /**
- * <p>
  * The factory class for obtaining references to browser instances.
- * </p>
- * <p>
+ *  <p>
  * An implementation independent representation of the class used to access
  * and create browsers. The model follows that used by java.net.Socket. A
  * setImpl method is provided for browser writers to provide the internal
  * implementations of the browser.
- * </p>
- * <p>
+ *  <p>
  * An alternative way of doing this is through a properties file. The class,
  * when it loads looks for the file vrml.properties in the class path. (For
  * more information on how this works read
  * <code>java.lang.ClassLoader.getSystemResourceAsStream()</code>). From this
  * file this class then uses the following properties:
- * <ul>
- * <li><code>vrml.eai.factory.class</code></li>
- * </ul>
+ * <UL>
+ * <LI><code>vrml.eai.factory.class</code>
+ * </UL>
  *
- * <p>
  * The value of the factory class is then used as the name of the class to
  * load as the default browser implementation. This name must represent the
  * full package qualified name of the class. This class is then loaded using
  * the following method:
- * </p>
  *
  *  <pre>
  *  Class factory_class = Class.forName(factory_class_name);
  *  factory = (BrowserFactoryImpl)factory_class.newInstance();
  *  </pre>
  *
- * <p>
  * If a class cast exception is raised at the end, then an error is printed
  * but nothing is done about it. The result would be NullPointerExceptions
  * later in the code. Also, this may cause some security errors in some
  * web browsers.
- * </p>
- * <p>
+ *  <p>
  * To provide a custom implementation of the factory (which all
  * implementations must do) the user has the choice of the above two options
  * of either calling setImpl or by making sure that the vrml.properties
@@ -77,12 +70,10 @@ import java.util.Properties;
  * the implementation defined in the properties file. Attempting to call the
  * set implementation method after this point shall result in a VrmlException
  * being generated. Otherwise, it shall use the set implementation.
- * </p>
- * <p>
+ *  <p>
  * If for some reason the properties file does not contain the property for
  * the name of the factory class or the properties file does not exist, then
  * the default class name is <code>vrml.eai.DefaultBrowserImpl</code>
- * </p>
  *
  * <p><b>Supported Parameters</b></p>
  * <p>
@@ -90,8 +81,7 @@ import java.util.Properties;
  * how a browser operates.  You can also specify browser specific options.
  * The following options are supported by Xj3D.
  * </p>
- * <table>
- * <caption>the following options are supported by Xj3D</caption>
+ * <table summary="the following options are supported by Xj3D">
  * <tr><td> <b>Param Name </b></td><td> <b>Description </b></td><td> <b>Type </b></td><td> <b>Default </b></td><td> <b>Legal Values </b></td></tr>
  * <tr><td>Antialiased</td><td>Whether to turn on antialiasing</td><td>Boolean</td><td>false</td><td>true,false</td></tr>
  * <tr><td>TextureQuality</td><td>A quality metric for texturing.  High turns on all tricks like anisotropicFiltering</td><td>String</td><td>medium</td><td>low,medium,high</td></tr>
diff --git a/src/java/vrml/eai/BrowserFactoryImpl.java b/src/java/vrml/eai/BrowserFactoryImpl.java
index 38868946ec24a581c5e25110294be70314c287dd..8d5d661520c18b224af406abac77af302289cff3 100644
--- a/src/java/vrml/eai/BrowserFactoryImpl.java
+++ b/src/java/vrml/eai/BrowserFactoryImpl.java
@@ -1,127 +1,127 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai;
-
-import java.net.UnknownHostException;
-import java.net.InetAddress;
-
-/**
- * The factory implementation interface for obtaining references to browser
- * instances.
- *  <p>
- * Any implementation of a VRML browser that wishes to provide their own
- * customized version of the browser factory should must subclass this class.
- * In particular this is useful if the implementation needs to stay within the
- * package defined by the application for other reasons.
- *  <p>
- * A default implementation of this class is the DefaultBrowserFactoryImpl which
- * is package access only.
- *
- * @version 1.1 29 August 1998
- */
-public interface BrowserFactoryImpl
-{
-  /**
-   * Create a VRML browser that can be used as an AWT component. The component
-   * returned is guaranteed to be an instance of VrmlComponent.
-   *
-   * @param params Parameters to control the look and feel.
-   * @return The component browser initialised to be empty.
-   * @exception NotSupportedException The implementation does not support this
-   *    type of VRML browser.
-   * @see VrmlComponent
-   */
-  VrmlComponent createComponent(String[] params)
-    throws NotSupportedException;
-
-  /**
-   * Get a browser from the given java applet reference as a base in the
-   * current HTML page. Used when attempting to access a browser on the current
-   * page as this applet and is the first browser on the page. Generically, the
-   * same as calling getBrowser(applet, "", 0);
-   *
-   * @param applet The applet reference to use
-   * @return A reference to the Browser implementation
-   * @exception NotSupportedException The implementation does not support this
-   *    type of VRML browser
-   * @exception NoSuchBrowserException Could not locate a VRML browser on the
-   *    same page as the applet.
-   * @exception ConnectionException An error occurred during the connecting
-   *    process
-   */
-  @SuppressWarnings("deprecation")
-  Browser getBrowser(java.applet.Applet applet)
-    throws NotSupportedException, NoSuchBrowserException, ConnectionException;
-
-  /**
-   * Get a browser from the given java applet reference one some named page and
-   * at some embed location. Used when attempting to access a browser on
-   * another HTML page within a multi-framed environment, or if there are a
-   * number of VRML browser instances located on the same page.
-   *  <p>
-   * If the frame name is a zero length string or null then it is assumed to be
-   * located on the same HTML page as the applet. The index is the number of
-   * the embed VRML browser starting from the top of the page. If there are
-   * other non-VRML plugins embedded in the page these are not taken into
-   * account in calculating the embed index.
-   *
-   * @param applet The applet reference to use
-   * @param frameName The name of the frame to look into for the browser
-   * @param index The embed index of the VRML browser in the page
-   * @return A reference to the Browser implementation
-   * @exception NotSupportedException The implementation does not support this
-   *    type of VRML browser.
-   * @exception NoSuchBrowserException Could not locate a VRML browser on the
-   *    same page as the applet.
-   * @exception ConnectionException An error occurred during the connecting
-   *    process
-   */
-  @SuppressWarnings("deprecation")
-  Browser getBrowser(java.applet.Applet applet, String frameName, int index)
-    throws NotSupportedException, NoSuchBrowserException, ConnectionException;
-
-  /**
-   * Get a reference to a browser that is located on a remote machine. This
-   * a server application to send scene updates to a number of client browsers
-   * located on remote machines. If there are a number of browsers running on
-   * a remote machine, they can be differentiated by the port number they are
-   * listening on.
-   *  <p>
-   * There is no default port number for VRML browsers.
-   *
-   * @param address The address of the machine to connect to
-   * @param port The port number on that machine to connect to.
-   * @return A reference to the Browser implementation
-   * @exception NotSupportedException The implementation does not support this
-   *    type of VRML browser.
-   * @exception NoSuchBrowserException Could not locate a VRML browser on the
-   *    same page as the applet.
-   * @exception UnknownHostException Could not find the machine named in the
-   *    address.
-   * @exception ConnectionException An error occurred during the connecting
-   *    process
-   */
-  Browser getBrowser(InetAddress address, int port)
-    throws NotSupportedException,
-           NoSuchBrowserException,
-           UnknownHostException,
-           ConnectionException;
-}
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai;
+
+import java.net.UnknownHostException;
+import java.net.InetAddress;
+
+/**
+ * The factory implementation interface for obtaining references to browser
+ * instances.
+ *  <p>
+ * Any implementation of a VRML browser that wishes to provide their own
+ * customized version of the browser factory should must subclass this class.
+ * In particular this is useful if the implementation needs to stay within the
+ * package defined by the application for other reasons.
+ *  <p>
+ * A default implementation of this class is the DefaultBrowserFactoryImpl which
+ * is package access only.
+ *
+ * @version 1.1 29 August 1998
+ */
+public interface BrowserFactoryImpl
+{
+  /**
+   * Create a VRML browser that can be used as an AWT component. The component
+   * returned is guaranteed to be an instance of VrmlComponent.
+   *
+   * @param params Parameters to control the look and feel.
+   * @return The component browser initialised to be empty.
+   * @exception NotSupportedException The implementation does not support this
+   *    type of VRML browser.
+   * @see VrmlComponent
+   */
+  VrmlComponent createComponent(String[] params)
+    throws NotSupportedException;
+
+  /**
+   * Get a browser from the given java applet reference as a base in the
+   * current HTML page. Used when attempting to access a browser on the current
+   * page as this applet and is the first browser on the page. Generically, the
+   * same as calling getBrowser(applet, "", 0);
+   *
+   * @param applet The applet reference to use
+   * @return A reference to the Browser implementation
+   * @exception NotSupportedException The implementation does not support this
+   *    type of VRML browser
+   * @exception NoSuchBrowserException Could not locate a VRML browser on the
+   *    same page as the applet.
+   * @exception ConnectionException An error occurred during the connecting
+   *    process
+   */
+  @SuppressWarnings("deprecation")
+  Browser getBrowser(java.applet.Applet applet)
+    throws NotSupportedException, NoSuchBrowserException, ConnectionException;
+
+  /**
+   * Get a browser from the given java applet reference one some named page and
+   * at some embed location. Used when attempting to access a browser on
+   * another HTML page within a multi-framed environment, or if there are a
+   * number of VRML browser instances located on the same page.
+   *  <p>
+   * If the frame name is a zero length string or null then it is assumed to be
+   * located on the same HTML page as the applet. The index is the number of
+   * the embed VRML browser starting from the top of the page. If there are
+   * other non-VRML plugins embedded in the page these are not taken into
+   * account in calculating the embed index.
+   *
+   * @param applet The applet reference to use
+   * @param frameName The name of the frame to look into for the browser
+   * @param index The embed index of the VRML browser in the page
+   * @return A reference to the Browser implementation
+   * @exception NotSupportedException The implementation does not support this
+   *    type of VRML browser.
+   * @exception NoSuchBrowserException Could not locate a VRML browser on the
+   *    same page as the applet.
+   * @exception ConnectionException An error occurred during the connecting
+   *    process
+   */
+  @SuppressWarnings("deprecation")
+  Browser getBrowser(java.applet.Applet applet, String frameName, int index)
+    throws NotSupportedException, NoSuchBrowserException, ConnectionException;
+
+  /**
+   * Get a reference to a browser that is located on a remote machine. This
+   * a server application to send scene updates to a number of client browsers
+   * located on remote machines. If there are a number of browsers running on
+   * a remote machine, they can be differentiated by the port number they are
+   * listening on.
+   *  <p>
+   * There is no default port number for VRML browsers.
+   *
+   * @param address The address of the machine to connect to
+   * @param port The port number on that machine to connect to.
+   * @return A reference to the Browser implementation
+   * @exception NotSupportedException The implementation does not support this
+   *    type of VRML browser.
+   * @exception NoSuchBrowserException Could not locate a VRML browser on the
+   *    same page as the applet.
+   * @exception UnknownHostException Could not find the machine named in the
+   *    address.
+   * @exception ConnectionException An error occurred during the connecting
+   *    process
+   */
+  Browser getBrowser(InetAddress address, int port)
+    throws NotSupportedException,
+           NoSuchBrowserException,
+           UnknownHostException,
+           ConnectionException;
+}
+
+
+
+
+
diff --git a/src/java/vrml/eai/ConnectionException.java b/src/java/vrml/eai/ConnectionException.java
index dfb67599f42d1ae01a2902921116d0fac67cba48..ab4b4a288fba717ed68cb61ffa833c274a52fa8a 100644
--- a/src/java/vrml/eai/ConnectionException.java
+++ b/src/java/vrml/eai/ConnectionException.java
@@ -1,44 +1,44 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai;
-
-/**
- * The exception that is thrown when an error occurs in the connection between
- * the external application and the VRML browser. Typically this might be a
- * network connection stopping or similar problem.
- *
- * @version 1.0 3 August 1998
- */
-public class ConnectionException extends VrmlException
-{
-    /**
-     * Construct a basic instance of this exception with no error message
-     */
-    public ConnectionException()
-    {
-        super();
-    }
-
-    /**
-     * Constructs a new exception with a particular message
-     *
-     * @param msg The message to use
-     */
-    public ConnectionException(String msg)
-    {
-        super(msg);
-    }
-}
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai;
+
+/**
+ * The exception that is thrown when an error occurs in the connection between
+ * the external application and the VRML browser. Typically this might be a
+ * network connection stopping or similar problem.
+ *
+ * @version 1.0 3 August 1998
+ */
+public class ConnectionException extends VrmlException
+{
+    /**
+     * Construct a basic instance of this exception with no error message
+     */
+    public ConnectionException()
+    {
+        super();
+    }
+
+    /**
+     * Constructs a new exception with a particular message
+     *
+     * @param msg The message to use
+     */
+    public ConnectionException(String msg)
+    {
+        super(msg);
+    }
+}
diff --git a/src/java/vrml/eai/DefaultBrowserImpl.java b/src/java/vrml/eai/DefaultBrowserImpl.java
index 63ed7173d95f81970a7aa8d38e20d7b47e58d65c..40192d7873c7929129fb0829d39ee5295d584569 100644
--- a/src/java/vrml/eai/DefaultBrowserImpl.java
+++ b/src/java/vrml/eai/DefaultBrowserImpl.java
@@ -1,104 +1,104 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai;
-
-import java.net.UnknownHostException;
-import java.net.InetAddress;
-
-/**
- * The factory implementation interface for obtaining references to browser
- * instances.
- *  <p>
- * Any implementation of a VRML browser that wishes to provide their own
- * customized version of the browser factory should must subclass this class.
- * In particular this is useful if the implementation needs to stay within the
- * package defined by the application for other reasons.
- *  <p>
- * A default implementation of this class is the PlainBrowserFactoryImpl which
- * is package access only.
- *
- * @version 1.1 29 August 1998
- */
-class DefaultBrowserImpl
-  implements BrowserFactoryImpl
-{
-  private static final String ERR_MSG =
-    "Default Browser implementation cannot create browser reference";
-
-  /**
-   * Create a VRML browser that can be used as an AWT component. The component
-   * returned is guaranteed to be an instance of VrmlComponent.
-   *
-   * @param params Parameters to control the look and feel.
-   * @return The component browser initialised to be empty.
-   * @exception NotSupportedException The implementation does not support this
-   *    type of VRML browser.
-   * @see VrmlComponent
-   */
-  @Override
-  public VrmlComponent createComponent(String[] params)
-    throws NotSupportedException
-  {
-    throw new NotSupportedException(ERR_MSG);
-  }
-
-  @Override
-  @SuppressWarnings("deprecation")
-  public Browser getBrowser(java.applet.Applet applet)
-    throws NotSupportedException, NoSuchBrowserException
-  {
-    throw new NotSupportedException(ERR_MSG);
-  }
-
-  @Override
-  @SuppressWarnings("deprecation")
-  public Browser getBrowser(java.applet.Applet applet, String frameName, int index)
-    throws NotSupportedException, NoSuchBrowserException
-  {
-    throw new NotSupportedException(ERR_MSG);
-  }
-
-  /**
-   * Get a reference to a browser that is located on a remote machine. This
-   * a server application to send scene updates to a number of client browsers
-   * located on remote machines. If there are a number of browsers running on
-   * a remote machine, they can be differentiated by the port number they are
-   * listening on.
-   *  <p>
-   * There is no default port number for VRML browsers.
-   *
-   * @param address The address of the machine to connect to
-   * @param port The port number on that machine to connect to.
-   * @return A reference to the Browser implementation
-   * @exception NotSupportedException The implementation does not support this
-   *    type of VRML browser.
-   * @exception NoSuchBrowserException Could not locate a VRML browser on the
-   *    same page as the applet.
-   * @exception NoSuchHostException Could not find the machine named in the
-   *    address.
-   */
-  @Override
-  public Browser getBrowser(InetAddress address, int port)
-    throws NotSupportedException, NoSuchBrowserException, UnknownHostException
-  {
-    throw new NotSupportedException(ERR_MSG);
-  }
-}
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai;
+
+import java.net.UnknownHostException;
+import java.net.InetAddress;
+
+/**
+ * The factory implementation interface for obtaining references to browser
+ * instances.
+ *  <p>
+ * Any implementation of a VRML browser that wishes to provide their own
+ * customized version of the browser factory should must subclass this class.
+ * In particular this is useful if the implementation needs to stay within the
+ * package defined by the application for other reasons.
+ *  <p>
+ * A default implementation of this class is the PlainBrowserFactoryImpl which
+ * is package access only.
+ *
+ * @version 1.1 29 August 1998
+ */
+class DefaultBrowserImpl
+  implements BrowserFactoryImpl
+{
+  private static final String ERR_MSG =
+    "Default Browser implementation cannot create browser reference";
+
+  /**
+   * Create a VRML browser that can be used as an AWT component. The component
+   * returned is guaranteed to be an instance of VrmlComponent.
+   *
+   * @param params Parameters to control the look and feel.
+   * @return The component browser initialised to be empty.
+   * @exception NotSupportedException The implementation does not support this
+   *    type of VRML browser.
+   * @see VrmlComponent
+   */
+  @Override
+  public VrmlComponent createComponent(String[] params)
+    throws NotSupportedException
+  {
+    throw new NotSupportedException(ERR_MSG);
+  }
+
+  @Override
+  @SuppressWarnings("deprecation")
+  public Browser getBrowser(java.applet.Applet applet)
+    throws NotSupportedException, NoSuchBrowserException
+  {
+    throw new NotSupportedException(ERR_MSG);
+  }
+
+  @Override
+  @SuppressWarnings("deprecation")
+  public Browser getBrowser(java.applet.Applet applet, String frameName, int index)
+    throws NotSupportedException, NoSuchBrowserException
+  {
+    throw new NotSupportedException(ERR_MSG);
+  }
+
+  /**
+   * Get a reference to a browser that is located on a remote machine. This
+   * a server application to send scene updates to a number of client browsers
+   * located on remote machines. If there are a number of browsers running on
+   * a remote machine, they can be differentiated by the port number they are
+   * listening on.
+   *  <p>
+   * There is no default port number for VRML browsers.
+   *
+   * @param address The address of the machine to connect to
+   * @param port The port number on that machine to connect to.
+   * @return A reference to the Browser implementation
+   * @exception NotSupportedException The implementation does not support this
+   *    type of VRML browser.
+   * @exception NoSuchBrowserException Could not locate a VRML browser on the
+   *    same page as the applet.
+   * @exception NoSuchHostException Could not find the machine named in the
+   *    address.
+   */
+  @Override
+  public Browser getBrowser(InetAddress address, int port)
+    throws NotSupportedException, NoSuchBrowserException, UnknownHostException
+  {
+    throw new NotSupportedException(ERR_MSG);
+  }
+}
+
+
+
+
+
diff --git a/src/java/vrml/eai/InvalidBrowserException.java b/src/java/vrml/eai/InvalidBrowserException.java
index c574c63952f7e341f473501832db24afe398dcd7..3a3ed8dadcd010fbaa60d089c64116fd8b79492c 100644
--- a/src/java/vrml/eai/InvalidBrowserException.java
+++ b/src/java/vrml/eai/InvalidBrowserException.java
@@ -1,43 +1,43 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai;
-
-/**
- * The exception that is thrown when the user attempts to access a method in
- * the Browser interface after the reference has had the dispose method called.
- *
- * @version 1.0 7th March 1998
- */
-public class InvalidBrowserException extends VrmlException
-{
-    /**
-     * Construct a basic instance of this exception with no error message
-     */
-    public InvalidBrowserException()
-    {
-        super();
-    }
-
-    /**
-     * Constructs a new exception with a particular message
-     *
-     * @param msg The message to use
-     */
-    public InvalidBrowserException(String msg)
-    {
-        super(msg);
-    }
-}
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai;
+
+/**
+ * The exception that is thrown when the user attempts to access a method in
+ * the Browser interface after the reference has had the dispose method called.
+ *
+ * @version 1.0 7th March 1998
+ */
+public class InvalidBrowserException extends VrmlException
+{
+    /**
+     * Construct a basic instance of this exception with no error message
+     */
+    public InvalidBrowserException()
+    {
+        super();
+    }
+
+    /**
+     * Constructs a new exception with a particular message
+     *
+     * @param msg The message to use
+     */
+    public InvalidBrowserException(String msg)
+    {
+        super(msg);
+    }
+}
diff --git a/src/java/vrml/eai/InvalidURLException.java b/src/java/vrml/eai/InvalidURLException.java
index a29ef14832a7b250518299096d011a9bef65cbe6..761c4b7304d581bb1794fc1939073801abd8ca4e 100644
--- a/src/java/vrml/eai/InvalidURLException.java
+++ b/src/java/vrml/eai/InvalidURLException.java
@@ -1,43 +1,43 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai;
-
-/**
- * The exception that is thrown when the list of all URL and URN values are
- * invalid and cannot be parsed to form a proper URL/URN.
- *
- * @version 1.0 13th August 1998
- */
-public class InvalidURLException extends VrmlException
-{
-    /**
-     * Construct a basic instance of this exception with no error message
-     */
-    public InvalidURLException()
-    {
-        super();
-    }
-
-    /**
-     * Constructs a new exception with a particular message
-     *
-     * @param msg The message to use
-     */
-    public InvalidURLException(String msg)
-    {
-        super(msg);
-    }
-}
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai;
+
+/**
+ * The exception that is thrown when the list of all URL and URN values are
+ * invalid and cannot be parsed to form a proper URL/URN.
+ *
+ * @version 1.0 13th August 1998
+ */
+public class InvalidURLException extends VrmlException
+{
+    /**
+     * Construct a basic instance of this exception with no error message
+     */
+    public InvalidURLException()
+    {
+        super();
+    }
+
+    /**
+     * Constructs a new exception with a particular message
+     *
+     * @param msg The message to use
+     */
+    public InvalidURLException(String msg)
+    {
+        super(msg);
+    }
+}
diff --git a/src/java/vrml/eai/InvalidVrmlException.java b/src/java/vrml/eai/InvalidVrmlException.java
index 411f27beb8338594de7d7e3facac7056e85d245a..c13f75aa987e8b1951c8d798ee16985cb94a2490 100644
--- a/src/java/vrml/eai/InvalidVrmlException.java
+++ b/src/java/vrml/eai/InvalidVrmlException.java
@@ -1,43 +1,43 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai;
-
-/**
- * The exception that is thrown when a the string passed to
- * createVrmlFromString does not contain legal VRML.
- *
- * @version 1.0 7th March 1998
- */
-public class InvalidVrmlException extends VrmlException
-{
-    /**
-     * Construct a basic instance of this exception with no error message
-     */
-    public InvalidVrmlException()
-    {
-        super();
-    }
-
-    /**
-     * Constructs a new exception with a particular message
-     *
-     * @param msg The message to use
-     */
-    public InvalidVrmlException(String msg)
-    {
-        super(msg);
-    }
-}
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai;
+
+/**
+ * The exception that is thrown when a the string passed to
+ * createVrmlFromString does not contain legal VRML.
+ *
+ * @version 1.0 7th March 1998
+ */
+public class InvalidVrmlException extends VrmlException
+{
+    /**
+     * Construct a basic instance of this exception with no error message
+     */
+    public InvalidVrmlException()
+    {
+        super();
+    }
+
+    /**
+     * Constructs a new exception with a particular message
+     *
+     * @param msg The message to use
+     */
+    public InvalidVrmlException(String msg)
+    {
+        super(msg);
+    }
+}
diff --git a/src/java/vrml/eai/NoSuchBrowserException.java b/src/java/vrml/eai/NoSuchBrowserException.java
index 727256192836b26c0690067e210a4117da87b346..a271af1b6959806c3da9074e72608b91ddf666bb 100644
--- a/src/java/vrml/eai/NoSuchBrowserException.java
+++ b/src/java/vrml/eai/NoSuchBrowserException.java
@@ -1,46 +1,46 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai;
-
-/**
- * The exception that is thrown when the Browser factory is not able to locate
- * a browser given the arguments.
- *
- * @see BrowserFactory
- * @see BrowserFactoryImpl
- *
- * @version 1.0 23rd June 1998
- */
-public class NoSuchBrowserException extends VrmlException
-{
-    /**
-     * Construct a basic instance of this exception with no error message
-     */
-    public NoSuchBrowserException()
-    {
-        super();
-    }
-
-    /**
-     * Constructs a new exception with a particular message
-     *
-     * @param msg The message to use
-     */
-    public NoSuchBrowserException(String msg)
-    {
-        super(msg);
-    }
-}
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai;
+
+/**
+ * The exception that is thrown when the Browser factory is not able to locate
+ * a browser given the arguments.
+ *
+ * @see BrowserFactory
+ * @see BrowserFactoryImpl
+ *
+ * @version 1.0 23rd June 1998
+ */
+public class NoSuchBrowserException extends VrmlException
+{
+    /**
+     * Construct a basic instance of this exception with no error message
+     */
+    public NoSuchBrowserException()
+    {
+        super();
+    }
+
+    /**
+     * Constructs a new exception with a particular message
+     *
+     * @param msg The message to use
+     */
+    public NoSuchBrowserException(String msg)
+    {
+        super(msg);
+    }
+}
diff --git a/src/java/vrml/eai/Node.java b/src/java/vrml/eai/Node.java
index 709f970a6569cce16287c7318fe126266ce85c47..70c47c9eb3fd5c67a50549ab477863d879563ba5 100644
--- a/src/java/vrml/eai/Node.java
+++ b/src/java/vrml/eai/Node.java
@@ -1,104 +1,104 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai;
-
-// Standard imports
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-// Local imports
-import vrml.eai.field.EventIn;
-import vrml.eai.field.EventOut;
-import vrml.eai.field.InvalidEventInException;
-import vrml.eai.field.InvalidEventOutException;
-
-/**
- * The representation of the VRML node as a java class. This is the basic node
- * class that all nodes represent.
- *
- * @version 1.1 17th June 1998
- */
-public abstract class Node
-{
-    /**
-     * Get the type of this node. The string returned should be the name of
-     * the VRML node or the name of the proto instance this node represents.
-     *
-     * @return The type of this node.
-     * @exception InvalidNodeException The node has had it's resources
-     *   disposed of
-     */
-    public abstract String getType()
-      throws InvalidNodeException;
-
-    /**
-     * Get an eventIn for this node.
-     *  <p>
-     * If the basic field required is an exposedField you can use either the
-     * standard name (such as <i>translation</i>) or you can use the <i>set_</i>
-     * modifier (such as <i>set_translation</i>).
-     *
-     * @param name The name of the eventIn that is required
-     * @return A reference to the eventIn requested.
-     * @exception InvalidEventInException The named eventIn does not exist for
-     *   this node.
-     * @exception InvalidNodeException The node has had it's resources disposed
-     *   of
-     */
-    public abstract EventIn getEventIn(String name)
-        throws InvalidEventInException, InvalidNodeException;
-
-    /**
-     * Get an eventOut for this node.
-     *  <p>
-     * If the basic field required is an exposedField you can use either the
-     * standard name (such as <i>translation</i>) or you can use the
-     * <i>_changed</i> modifier (such as <i>translation_changed</i>).
-     *
-     * @param name The name of the eventIn that is required
-     * @return A reference to the eventIn requested.
-     * @exception InvalidEventOutException The named eventIn does not exist for
-     *   this node.
-     * @exception InvalidNodeException The node has had it's resources disposed
-     *   of
-     */
-    public abstract EventOut getEventOut(String name)
-        throws InvalidEventOutException, InvalidNodeException;
-
-    /**
-     * Dispose of this node's resources. This is used to indicate to the
-     * browser that the java side of the application does not require the
-     * resources represented by this node. The browser is now free to do
-     * what it likes with the node.
-     *  <p>
-     * This in no way implies that the browser is to remove this node from
-     * the scene graph, only that the java applet is no longer interested
-     * in this particular node through this reference.
-     *  <p>
-     * Once this method has been called, any further calls to methods of
-     * this instance of the class is will generate an InvalidNodeException.
-     *
-     * @throws InvalidNodeException The node is no longer valid and can't be
-     *    disposed of again.
-     */
-    public abstract void dispose()
-      throws InvalidNodeException;
-}
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai;
+
+// Standard imports
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+// Local imports
+import vrml.eai.field.EventIn;
+import vrml.eai.field.EventOut;
+import vrml.eai.field.InvalidEventInException;
+import vrml.eai.field.InvalidEventOutException;
+
+/**
+ * The representation of the VRML node as a java class. This is the basic node
+ * class that all nodes represent.
+ *
+ * @version 1.1 17th June 1998
+ */
+public abstract class Node
+{
+    /**
+     * Get the type of this node. The string returned should be the name of
+     * the VRML node or the name of the proto instance this node represents.
+     *
+     * @return The type of this node.
+     * @exception InvalidNodeException The node has had it's resources
+     *   disposed of
+     */
+    public abstract String getType()
+      throws InvalidNodeException;
+
+    /**
+     * Get an eventIn for this node.
+     *  <p>
+     * If the basic field required is an exposedField you can use either the
+     * standard name (such as <i>translation</i>) or you can use the <i>set_</i>
+     * modifier (such as <i>set_translation</i>).
+     *
+     * @param name The name of the eventIn that is required
+     * @return A reference to the eventIn requested.
+     * @exception InvalidEventInException The named eventIn does not exist for
+     *   this node.
+     * @exception InvalidNodeException The node has had it's resources disposed
+     *   of
+     */
+    public abstract EventIn getEventIn(String name)
+        throws InvalidEventInException, InvalidNodeException;
+
+    /**
+     * Get an eventOut for this node.
+     *  <p>
+     * If the basic field required is an exposedField you can use either the
+     * standard name (such as <i>translation</i>) or you can use the
+     * <i>_changed</i> modifier (such as <i>translation_changed</i>).
+     *
+     * @param name The name of the eventIn that is required
+     * @return A reference to the eventIn requested.
+     * @exception InvalidEventOutException The named eventIn does not exist for
+     *   this node.
+     * @exception InvalidNodeException The node has had it's resources disposed
+     *   of
+     */
+    public abstract EventOut getEventOut(String name)
+        throws InvalidEventOutException, InvalidNodeException;
+
+    /**
+     * Dispose of this node's resources. This is used to indicate to the
+     * browser that the java side of the application does not require the
+     * resources represented by this node. The browser is now free to do
+     * what it likes with the node.
+     *  <p>
+     * This in no way implies that the browser is to remove this node from
+     * the scene graph, only that the java applet is no longer interested
+     * in this particular node through this reference.
+     *  <p>
+     * Once this method has been called, any further calls to methods of
+     * this instance of the class is will generate an InvalidNodeException.
+     *
+     * @throws InvalidNodeException The node is no longer valid and can't be
+     *    disposed of again.
+     */
+    public abstract void dispose()
+      throws InvalidNodeException;
+}
+
+
+
+
+
diff --git a/src/java/vrml/eai/NotSupportedException.java b/src/java/vrml/eai/NotSupportedException.java
index 750eec625e3aa8f79f93b2bfcfc90030b4e0cf35..0acc19ee5408be164111db8750d56e7ee25e7251 100644
--- a/src/java/vrml/eai/NotSupportedException.java
+++ b/src/java/vrml/eai/NotSupportedException.java
@@ -1,49 +1,49 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai;
-
-/**
- * The exception that is thrown when an operation is not supported by an
- * underlying implementation.
- *  <p>
- * Typically this class is used when one of the implementations are not
- * supported in BrowserFactory
- *
- * @see BrowserFactory
- * @see BrowserFactoryImpl
- *
- * @version 1.0 23rd June 1998
- */
-public class NotSupportedException extends VrmlException
-{
-    /**
-     * Construct a basic instance of this exception with no error message
-     */
-    public NotSupportedException()
-    {
-        super();
-    }
-
-    /**
-     * Constructs a new exception with a particular message
-     *
-     * @param msg The message to use
-     */
-    public NotSupportedException(String msg)
-    {
-        super(msg);
-    }
-}
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai;
+
+/**
+ * The exception that is thrown when an operation is not supported by an
+ * underlying implementation.
+ *  <p>
+ * Typically this class is used when one of the implementations are not
+ * supported in BrowserFactory
+ *
+ * @see BrowserFactory
+ * @see BrowserFactoryImpl
+ *
+ * @version 1.0 23rd June 1998
+ */
+public class NotSupportedException extends VrmlException
+{
+    /**
+     * Construct a basic instance of this exception with no error message
+     */
+    public NotSupportedException()
+    {
+        super();
+    }
+
+    /**
+     * Constructs a new exception with a particular message
+     *
+     * @param msg The message to use
+     */
+    public NotSupportedException(String msg)
+    {
+        super(msg);
+    }
+}
diff --git a/src/java/vrml/eai/VrmlComponent.java b/src/java/vrml/eai/VrmlComponent.java
index 525488ed311657e336a16a57ff4199674ecda55f..2b1236b31fdc7ad153e0327db40a58d9ece2cefc 100644
--- a/src/java/vrml/eai/VrmlComponent.java
+++ b/src/java/vrml/eai/VrmlComponent.java
@@ -1,57 +1,57 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai;
-
-/**
- * Provides for implementation of a VRML browser than runs as a
- * component and able to extract a Browser reference from it.
- *  <p>
- * Generally this is used to provide a definition of an AWT component with a
- * VRML display capability. There is no reason why this could not be used for
- * other browser representations such as off screen renderers or file savers.
- *
- * @version 2.0 29 August 1998
- */
-public interface VrmlComponent
-{
-    /**
-    * Get a browser reference from this component that represents the
-    * internals of this browser.
-    *
-    * @return A reference to the browser object represented by this component.
-    */
-    Browser getBrowser();
-
-    /**
-     * Get a reference to the component implementation. For example, if this
-     * is an AWT component, it would return an instance
-     * of {@link java.awt.Component}.
-     * @return a reference to the component implementation
-     */
-    Object getImplementation();
-
-    /**
-     * Shutdown the component because it will no longer be needed. If the
-     * component has already had this method called, it will silently ignore
-     * any further requests.
-     */
-    void shutdown();
-}
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai;
+
+/**
+ * Provides for implementation of a VRML browser than runs as a
+ * component and able to extract a Browser reference from it.
+ *  <p>
+ * Generally this is used to provide a definition of an AWT component with a
+ * VRML display capability. There is no reason why this could not be used for
+ * other browser representations such as off screen renderers or file savers.
+ *
+ * @version 2.0 29 August 1998
+ */
+public interface VrmlComponent
+{
+    /**
+    * Get a browser reference from this component that represents the
+    * internals of this browser.
+    *
+    * @return A reference to the browser object represented by this component.
+    */
+    Browser getBrowser();
+
+    /**
+     * Get a reference to the component implementation. For example, if this
+     * is an AWT component, it would return an instance
+     * of {@link java.awt.Component}.
+     * @return a reference to the component implementation
+     */
+    Object getImplementation();
+
+    /**
+     * Shutdown the component because it will no longer be needed. If the
+     * component has already had this method called, it will silently ignore
+     * any further requests.
+     */
+    void shutdown();
+}
+
+
+
+
+
diff --git a/src/java/vrml/eai/VrmlException.java b/src/java/vrml/eai/VrmlException.java
index 6050adf1b6097f50071053f91705401d723d6b09..939a3ba305619dfbd4a98a4ee4fa10d443418873 100644
--- a/src/java/vrml/eai/VrmlException.java
+++ b/src/java/vrml/eai/VrmlException.java
@@ -1,44 +1,44 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai;
-
-/**
- * The basic exception that is thrown by any VRML method call that wishes to
- * throw events. Based on RuntimeException so that the user has the choice of
- * deciding whether to catch the exception or not.
- *
- * @version 1.0 30 April 1998
- */
-public class VrmlException extends RuntimeException
-{
-    /**
-     * Construct a basic instance of this exception with no error message
-     */
-    public VrmlException()
-    {
-        super();
-    }
-
-    /**
-     * Constructs a new exception with a particular message
-     *
-     * @param msg The message to use
-     */
-    public VrmlException(String msg)
-    {
-        super(msg);
-    }
-}
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai;
+
+/**
+ * The basic exception that is thrown by any VRML method call that wishes to
+ * throw events. Based on RuntimeException so that the user has the choice of
+ * deciding whether to catch the exception or not.
+ *
+ * @version 1.0 30 April 1998
+ */
+public class VrmlException extends RuntimeException
+{
+    /**
+     * Construct a basic instance of this exception with no error message
+     */
+    public VrmlException()
+    {
+        super();
+    }
+
+    /**
+     * Constructs a new exception with a particular message
+     *
+     * @param msg The message to use
+     */
+    public VrmlException(String msg)
+    {
+        super(msg);
+    }
+}
diff --git a/src/java/vrml/eai/event/BrowserEvent.java b/src/java/vrml/eai/event/BrowserEvent.java
index 71f5d8a17e8dc6414da10a7ab353aab863cf7e10..f5c4c7138863a487e84d99c6665fb56eb698483f 100644
--- a/src/java/vrml/eai/event/BrowserEvent.java
+++ b/src/java/vrml/eai/event/BrowserEvent.java
@@ -1,114 +1,114 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.event;
-
-import vrml.eai.Browser;
-
- /**
-  * Class representing events that happen to the VRML browser.
-  *  <p>
-  * This event notifies listener classes about changes to the browser that
-  * may be of interest to the client. VRML events cannot be consumed in the
-  * way that java AWT events can be.
-  *
-  * @version 1.1 3 August 1998
-  */
- public class BrowserEvent
- {
-    /**
-      * The browser has completed the initial loading of the world. Event is
-      * generated just after the scene has been loaded and just before the first
-      * event has been sent
-      */
-    public static final int INITIALIZED = 0;
-
-    /**
-     * The currently loaded world is about to be unloaded. Called just before
-     * the scene is about to be unloaded. If another world is to replace this,
-     * then an initialize event will be generated following this one.
-     */
-    public static final int SHUTDOWN = 1;
-
-    /**
-     * An error occurred in loading VRML from a URL call. Source could be either
-     * a createVrmlFromURL call or loadURL.
-     */
-    public static final int URL_ERROR = 2;
-
-    /**
-     * An error has occurred that has caused the connection between the browser
-     * and the external application to fail. This may be the VRML browser
-     * crashing, or a network connection falling over.
-     */
-    public static final int CONNECTION_ERROR = 10;
-
-    /**
-     * The number of reserved identifier numbers for event conditions. Any
-     * value below this is considered to be a general VRML defined event as
-     * specified in the External Authoring Interface specification. Any values
-     * above this are browser specific messages.
-     */
-    public static final int LAST_IDENTIFIER = 100;
-
-    /** The id of the event that this class instance represents */
-    private int id;
-
-    /** The reference to the browser that generated this event */
-    private Browser browser;
-
-    /**
-     * Create a new browser event.
-     *
-     * @param b The source of the browser that generated this event
-     * @param action The event type to create
-     * @exception IllegalArgumentException if the action or browser id are not
-     *   legal values
-     */
-    public BrowserEvent(Browser b, int action)
-    {
-        if(b == null)
-            throw new IllegalArgumentException("Null browser reference");
-
-        if(action < 0)
-            throw new IllegalArgumentException("Invalid event action type");
-
-        id = action;
-        browser = b;
-    }
-
-    /**
-     * Get the type of event that has occurred.
-     *
-     * @return The type of event as defined by the types
-     * @see #INITIALIZED
-     * @see #SHUTDOWN
-     */
-    public int getID()
-    {
-        return id;
-    }
-
-    /**
-     * Get the source of this event. A reference to the browser instance that
-     * generated this event.
-     *
-     * @return A reference to the browser that generated this event
-     */
-    public Browser getSource()
-    {
-        return browser;
-    }
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.event;
+
+import vrml.eai.Browser;
+
+ /**
+  * Class representing events that happen to the VRML browser.
+  *  <p>
+  * This event notifies listener classes about changes to the browser that
+  * may be of interest to the client. VRML events cannot be consumed in the
+  * way that java AWT events can be.
+  *
+  * @version 1.1 3 August 1998
+  */
+ public class BrowserEvent
+ {
+    /**
+      * The browser has completed the initial loading of the world. Event is
+      * generated just after the scene has been loaded and just before the first
+      * event has been sent
+      */
+    public static final int INITIALIZED = 0;
+
+    /**
+     * The currently loaded world is about to be unloaded. Called just before
+     * the scene is about to be unloaded. If another world is to replace this,
+     * then an initialize event will be generated following this one.
+     */
+    public static final int SHUTDOWN = 1;
+
+    /**
+     * An error occurred in loading VRML from a URL call. Source could be either
+     * a createVrmlFromURL call or loadURL.
+     */
+    public static final int URL_ERROR = 2;
+
+    /**
+     * An error has occurred that has caused the connection between the browser
+     * and the external application to fail. This may be the VRML browser
+     * crashing, or a network connection falling over.
+     */
+    public static final int CONNECTION_ERROR = 10;
+
+    /**
+     * The number of reserved identifier numbers for event conditions. Any
+     * value below this is considered to be a general VRML defined event as
+     * specified in the External Authoring Interface specification. Any values
+     * above this are browser specific messages.
+     */
+    public static final int LAST_IDENTIFIER = 100;
+
+    /** The id of the event that this class instance represents */
+    private int id;
+
+    /** The reference to the browser that generated this event */
+    private Browser browser;
+
+    /**
+     * Create a new browser event.
+     *
+     * @param b The source of the browser that generated this event
+     * @param action The event type to create
+     * @exception IllegalArgumentException if the action or browser id are not
+     *   legal values
+     */
+    public BrowserEvent(Browser b, int action)
+    {
+        if(b == null)
+            throw new IllegalArgumentException("Null browser reference");
+
+        if(action < 0)
+            throw new IllegalArgumentException("Invalid event action type");
+
+        id = action;
+        browser = b;
+    }
+
+    /**
+     * Get the type of event that has occurred.
+     *
+     * @return The type of event as defined by the types
+     * @see #INITIALIZED
+     * @see #SHUTDOWN
+     */
+    public int getID()
+    {
+        return id;
+    }
+
+    /**
+     * Get the source of this event. A reference to the browser instance that
+     * generated this event.
+     *
+     * @return A reference to the browser that generated this event
+     */
+    public Browser getSource()
+    {
+        return browser;
+    }
 }
\ No newline at end of file
diff --git a/src/java/vrml/eai/event/VrmlEvent.java b/src/java/vrml/eai/event/VrmlEvent.java
index 895b4a308e65b99c5f0861ede0d60ffc288eee3c..2fdcb01400a3d92e8ca97315901611ed86f92ad4 100644
--- a/src/java/vrml/eai/event/VrmlEvent.java
+++ b/src/java/vrml/eai/event/VrmlEvent.java
@@ -1,79 +1,79 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.event;
-
-import vrml.eai.field.BaseField;
-
-/**
- * The event that is generated when an eventOut changes a value.
- *
- * @version 1.0 7th march
- */
-public class VrmlEvent
-{
-    // who generated this event
-    private BaseField source;
-
-    // The timestamp, in VRML time, that this occurred at
-    private double timestamp;
-
-    // User associated data
-    private Object userData;
-
-    /**
-     * Construct a new event instance.
-     *
-     * @param src The source field that generated this event
-     * @param ts The timestamp of the event, In VRML time.
-     * @param data Any user associated data with this event
-     */
-    public VrmlEvent(BaseField src, double ts, Object data)
-    {
-        source = src;
-        timestamp = ts;
-        userData = data;
-    }
-
-    /**
-     * Get the source field of this event.
-     *
-     * @return A reference to the eventIn/Out that generated this event.
-     */
-    public BaseField getSource()
-    {
-        return source;
-    }
-
-    /**
-     * Get the timestamp that this event occurred at
-     *
-     * @return The time of this event, in VRML time coordinates.
-     */
-    public double getTime()
-    {
-        return timestamp;
-    }
-
-    /**
-     * Get any user associated data with this eventIn/Out.
-     *
-     * @return A reference to user associated data
-     */
-    public Object getData()
-    {
-        return userData;
-    }
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.event;
+
+import vrml.eai.field.BaseField;
+
+/**
+ * The event that is generated when an eventOut changes a value.
+ *
+ * @version 1.0 7th march
+ */
+public class VrmlEvent
+{
+    // who generated this event
+    private BaseField source;
+
+    // The timestamp, in VRML time, that this occurred at
+    private double timestamp;
+
+    // User associated data
+    private Object userData;
+
+    /**
+     * Construct a new event instance.
+     *
+     * @param src The source field that generated this event
+     * @param ts The timestamp of the event, In VRML time.
+     * @param data Any user associated data with this event
+     */
+    public VrmlEvent(BaseField src, double ts, Object data)
+    {
+        source = src;
+        timestamp = ts;
+        userData = data;
+    }
+
+    /**
+     * Get the source field of this event.
+     *
+     * @return A reference to the eventIn/Out that generated this event.
+     */
+    public BaseField getSource()
+    {
+        return source;
+    }
+
+    /**
+     * Get the timestamp that this event occurred at
+     *
+     * @return The time of this event, in VRML time coordinates.
+     */
+    public double getTime()
+    {
+        return timestamp;
+    }
+
+    /**
+     * Get any user associated data with this eventIn/Out.
+     *
+     * @return A reference to user associated data
+     */
+    public Object getData()
+    {
+        return userData;
+    }
 }
\ No newline at end of file
diff --git a/src/java/vrml/eai/event/VrmlEventListener.java b/src/java/vrml/eai/event/VrmlEventListener.java
index aa7a9b853709b5bc93c57cae78cda0640681facf..f79e4a8162018000d4280c6a95a63177adca568c 100644
--- a/src/java/vrml/eai/event/VrmlEventListener.java
+++ b/src/java/vrml/eai/event/VrmlEventListener.java
@@ -1,35 +1,35 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.event;
-
-/**
- * A listener for events on VRML fields
- *
- * @version 1.1 25 April 1998
- */
-public interface VrmlEventListener
-{
-    /**
-     * Process an event that has occurred on a node's eventOut
-     *
-     * @param evt The event that caused this method to be called
-     */
-    void eventOutChanged(VrmlEvent evt);
-
-}
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.event;
+
+/**
+ * A listener for events on VRML fields
+ *
+ * @version 1.1 25 April 1998
+ */
+public interface VrmlEventListener
+{
+    /**
+     * Process an event that has occurred on a node's eventOut
+     *
+     * @param evt The event that caused this method to be called
+     */
+    void eventOutChanged(VrmlEvent evt);
+
+}
+
+
+
diff --git a/src/java/vrml/eai/field/BaseField.java b/src/java/vrml/eai/field/BaseField.java
index cf8729ed615835737276aa29269d3f28f1cb4b5a..155014d222106faec41ff73c0eb8a222b7809ea1 100644
--- a/src/java/vrml/eai/field/BaseField.java
+++ b/src/java/vrml/eai/field/BaseField.java
@@ -1,75 +1,75 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * The base representation of any VRML field. Provides a core set of services
- * that all field types can use for introspection of classes.
- *
- * @version 1.0 7th March 1998
- */
-public abstract class BaseField
-{
-    //  single valued fields
-    public static final int SFBool = 1;
-    public static final int SFColor = 2;
-    public static final int SFFloat = 3;
-    public static final int SFImage = 4;
-    public static final int SFInt32 = 5;
-    public static final int SFNode = 6;
-    public static final int SFRotation = 7;
-    public static final int SFString = 8;
-    public static final int SFTime = 9;
-    public static final int SFVec2f = 10;
-    public static final int SFVec3f = 11;
-
-    // multi valued fields
-    public static final int MFColor = 12;
-    public static final int MFFloat = 13;
-    public static final int MFInt32 = 14;
-    public static final int MFNode = 15;
-    public static final int MFRotation = 16;
-    public static final int MFString = 17;
-    public static final int MFTime = 18;
-    public static final int MFVec2f = 19;
-    public static final int MFVec3f = 20;
-
-    protected static final int UNSET_FIELD = -1;
-
-    /** The type of values that this field represents. */
-    protected int fieldType = UNSET_FIELD;
-
-    /**
-     * Construct a new instance of a field.
-     *
-     * @param type The type of the field
-     */
-    protected BaseField(int type)
-    {
-        fieldType = type;
-    }
-
-    /**
-     * Get the basic type of this field.
-     *
-     * @return The type as defined by one of the above values
-     */
-    public int getType()
-    {
-        return fieldType;
-    }
-}
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * The base representation of any VRML field. Provides a core set of services
+ * that all field types can use for introspection of classes.
+ *
+ * @version 1.0 7th March 1998
+ */
+public abstract class BaseField
+{
+    //  single valued fields
+    public static final int SFBool = 1;
+    public static final int SFColor = 2;
+    public static final int SFFloat = 3;
+    public static final int SFImage = 4;
+    public static final int SFInt32 = 5;
+    public static final int SFNode = 6;
+    public static final int SFRotation = 7;
+    public static final int SFString = 8;
+    public static final int SFTime = 9;
+    public static final int SFVec2f = 10;
+    public static final int SFVec3f = 11;
+
+    // multi valued fields
+    public static final int MFColor = 12;
+    public static final int MFFloat = 13;
+    public static final int MFInt32 = 14;
+    public static final int MFNode = 15;
+    public static final int MFRotation = 16;
+    public static final int MFString = 17;
+    public static final int MFTime = 18;
+    public static final int MFVec2f = 19;
+    public static final int MFVec3f = 20;
+
+    protected static final int UNSET_FIELD = -1;
+
+    /** The type of values that this field represents. */
+    protected int fieldType = UNSET_FIELD;
+
+    /**
+     * Construct a new instance of a field.
+     *
+     * @param type The type of the field
+     */
+    protected BaseField(int type)
+    {
+        fieldType = type;
+    }
+
+    /**
+     * Get the basic type of this field.
+     *
+     * @return The type as defined by one of the above values
+     */
+    public int getType()
+    {
+        return fieldType;
+    }
+}
+
diff --git a/src/java/vrml/eai/field/EventIn.java b/src/java/vrml/eai/field/EventIn.java
index 85548cf5fe73e8a0cf823d3c3c6b3fa69273e095..790d3f9ff890232a36f6a49f1d1f6808b5d0bdd5 100644
--- a/src/java/vrml/eai/field/EventIn.java
+++ b/src/java/vrml/eai/field/EventIn.java
@@ -1,62 +1,62 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * A VRML eventIn class. Represents the VRML write only access type.
- *  <p>
- * The user can associate data and also listen for events on this eventIn.
- * These events are notified to the listener at the time that they arrive at
- * the field. This allows the addition of extra features like monitoring a
- * particular field for certain values being set (e.g. for debugging purposes)
- * without having to know every single node that has a ROUTE to this eventIn.
- *
- * @version 1.0 7th March 1998
- */
-public abstract class EventIn extends BaseField
-{
-    /**
-     * Construct an instance of this class.
-     *
-     * @param type The type of the field
-     */
-    protected EventIn(int type)
-    {
-        super(type);
-    }
-
-    /**
-     * Associate user data with this event. Whenever an event is generated
-     * on this eventIn. this data will be available with the Event through
-     * its getData method.
-     *
-     * @param data The data to associate with this eventIn instance
-     */
-    public abstract void setUserData(Object data);
-
-    /**
-     * Get the user data that is associated with this eventIn
-     *
-     * @return The user data, if any, associated with this eventIn
-     */
-    public abstract Object getUserData();
-}
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * A VRML eventIn class. Represents the VRML write only access type.
+ *  <p>
+ * The user can associate data and also listen for events on this eventIn.
+ * These events are notified to the listener at the time that they arrive at
+ * the field. This allows the addition of extra features like monitoring a
+ * particular field for certain values being set (e.g. for debugging purposes)
+ * without having to know every single node that has a ROUTE to this eventIn.
+ *
+ * @version 1.0 7th March 1998
+ */
+public abstract class EventIn extends BaseField
+{
+    /**
+     * Construct an instance of this class.
+     *
+     * @param type The type of the field
+     */
+    protected EventIn(int type)
+    {
+        super(type);
+    }
+
+    /**
+     * Associate user data with this event. Whenever an event is generated
+     * on this eventIn. this data will be available with the Event through
+     * its getData method.
+     *
+     * @param data The data to associate with this eventIn instance
+     */
+    public abstract void setUserData(Object data);
+
+    /**
+     * Get the user data that is associated with this eventIn
+     *
+     * @return The user data, if any, associated with this eventIn
+     */
+    public abstract Object getUserData();
+}
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventInMFColor.java b/src/java/vrml/eai/field/EventInMFColor.java
index b6534a645253065d902964e9d29d444f069bb356..6820636cb2e90e38c6e92516a922ffc2e1b8e983 100644
--- a/src/java/vrml/eai/field/EventInMFColor.java
+++ b/src/java/vrml/eai/field/EventInMFColor.java
@@ -1,92 +1,92 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventIn class for MFColor.
- *  <p>
- * Colour values are represented as floating point numbers between [0 - 1]
- * as per the VRML IS specification Section 4.4.5 Standard units and
- * coordinate system
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventInMFColor extends EventIn
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the type set to MFColor.
-   */
-  protected EventInMFColor()
-  {
-    super(MFColor);
-  }
-
-  /**
-   * Set the value of the array of colours. Input is an array of colour
-   * values in RGB order. All colour values are required to be in the
-   * range 0-1. Colour values outside of this range will generate an
-   * IllegalArgumentException. If value[i] that does not contain at
-   * least three values will generate an ArrayIndexOutOfBoundsException.
-   * If value[i] contains more than three items only the first three values
-   * will be used and the rest ignored.
-   *
-   * @param value The array of colour values where <br>
-   *    value[i][0] = Red component [0-1]  <br>
-   *    value[i][1] = Green component [0-1]  <br>
-   *    value[i][2] = Blue component [0-1]  <br>
-   *
-   * @exception IllegalArgumentException A colour value(s) was out of range
-   * @exception ArrayIndexOutOfBoundsException A value did not contain at least three
-   *    values for the colour component
-   */
-  public abstract void setValue(float[][] value);
-
-  /**
-   * Set a particular colour value in the given eventIn array. To the VRML
-   * world this will generate a full MFColor event with the nominated index
-   * value changed. Colour values are required to be in the range [0-1].
-   *  <p>
-   * The value array must contain at least three elements. If the array
-   * contains more than 3 values only the first three values will be used and
-   * the rest ignored.
-   *  <p>
-   * If the index is out of the bounds of the current array of data values or
-   * the array of values does not contain at least 3 elements an
-   * ArrayIndexOutOfBoundsException will be generated. If the colour values are
-   * out of range an IllegalArgumentException will be generated.
-   *
-   * @param index The position to set the colour value
-   * @param value The array of colour values where <br>
-   *    value[0] = Red component [0-1]  <br>
-   *    value[1] = Green component [0-1]  <br>
-   *    value[2] = Blue component [0-1]  <br>
-   *
-   * @exception IllegalArgumentException A colour value(s) was out of range
-   * @exception ArrayIndexOutOfBoundsException A value did not contain at least
-   *    three values for the colour component
-   */
-  public abstract void set1Value(int index, float[] value);
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventIn class for MFColor.
+ *  <p>
+ * Colour values are represented as floating point numbers between [0 - 1]
+ * as per the VRML IS specification Section 4.4.5 Standard units and
+ * coordinate system
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventInMFColor extends EventIn
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the type set to MFColor.
+   */
+  protected EventInMFColor()
+  {
+    super(MFColor);
+  }
+
+  /**
+   * Set the value of the array of colours. Input is an array of colour
+   * values in RGB order. All colour values are required to be in the
+   * range 0-1. Colour values outside of this range will generate an
+   * IllegalArgumentException. If value[i] that does not contain at
+   * least three values will generate an ArrayIndexOutOfBoundsException.
+   * If value[i] contains more than three items only the first three values
+   * will be used and the rest ignored.
+   *
+   * @param value The array of colour values where <br>
+   *    value[i][0] = Red component [0-1]  <br>
+   *    value[i][1] = Green component [0-1]  <br>
+   *    value[i][2] = Blue component [0-1]  <br>
+   *
+   * @exception IllegalArgumentException A colour value(s) was out of range
+   * @exception ArrayIndexOutOfBoundsException A value did not contain at least three
+   *    values for the colour component
+   */
+  public abstract void setValue(float[][] value);
+
+  /**
+   * Set a particular colour value in the given eventIn array. To the VRML
+   * world this will generate a full MFColor event with the nominated index
+   * value changed. Colour values are required to be in the range [0-1].
+   *  <p>
+   * The value array must contain at least three elements. If the array
+   * contains more than 3 values only the first three values will be used and
+   * the rest ignored.
+   *  <p>
+   * If the index is out of the bounds of the current array of data values or
+   * the array of values does not contain at least 3 elements an
+   * ArrayIndexOutOfBoundsException will be generated. If the colour values are
+   * out of range an IllegalArgumentException will be generated.
+   *
+   * @param index The position to set the colour value
+   * @param value The array of colour values where <br>
+   *    value[0] = Red component [0-1]  <br>
+   *    value[1] = Green component [0-1]  <br>
+   *    value[2] = Blue component [0-1]  <br>
+   *
+   * @exception IllegalArgumentException A colour value(s) was out of range
+   * @exception ArrayIndexOutOfBoundsException A value did not contain at least
+   *    three values for the colour component
+   */
+  public abstract void set1Value(int index, float[] value);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventInMFFloat.java b/src/java/vrml/eai/field/EventInMFFloat.java
index 277b5193aa4be6b7752e1e985a2f169fdf9366c7..a2cedd2ee78b781ed4b5e7cdd17b9f360b6e2db6 100644
--- a/src/java/vrml/eai/field/EventInMFFloat.java
+++ b/src/java/vrml/eai/field/EventInMFFloat.java
@@ -1,68 +1,68 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventIn class for MFFloat.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventInMFFloat extends EventIn
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the type MFFloat
-   */
-  protected EventInMFFloat()
-  {
-    super(MFFloat);
-  }
-
-  /**
-   * Set the value of the eventIn to the new array of float values. This array
-   * is copied internally so that the parameter array can be reused without
-   * effecting the valid values of the eventIn.
-   *
-   * @param value The array of values to be used.
-   */
-  public abstract void setValue(float[] value);
-
-  /**
-   * Set the value of an individual item in the eventIn's value. This results in
-   * a new event being generated that includes all of the array items with the
-   * single element set.
-   *
-   * If the index is out of the bounds of the current array of data values an
-   * ArrayIndexOutOfBoundsException will be generated.
-   *
-   * @param index The position to set the colour value
-   * @param value The value to be set
-   *
-   * @exception ArrayIndexOutOfBoundsException A value did not contain at least
-   *    three values for the colour component
-   */
-  public abstract void set1Value(int index, float value)
-    throws ArrayIndexOutOfBoundsException;
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventIn class for MFFloat.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventInMFFloat extends EventIn
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the type MFFloat
+   */
+  protected EventInMFFloat()
+  {
+    super(MFFloat);
+  }
+
+  /**
+   * Set the value of the eventIn to the new array of float values. This array
+   * is copied internally so that the parameter array can be reused without
+   * effecting the valid values of the eventIn.
+   *
+   * @param value The array of values to be used.
+   */
+  public abstract void setValue(float[] value);
+
+  /**
+   * Set the value of an individual item in the eventIn's value. This results in
+   * a new event being generated that includes all of the array items with the
+   * single element set.
+   *
+   * If the index is out of the bounds of the current array of data values an
+   * ArrayIndexOutOfBoundsException will be generated.
+   *
+   * @param index The position to set the colour value
+   * @param value The value to be set
+   *
+   * @exception ArrayIndexOutOfBoundsException A value did not contain at least
+   *    three values for the colour component
+   */
+  public abstract void set1Value(int index, float value)
+    throws ArrayIndexOutOfBoundsException;
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventInMFInt32.java b/src/java/vrml/eai/field/EventInMFInt32.java
index 4ec1cdc510b74ac847e081d466423b9092793b59..f7b43fb86e4810373d5cca97519931575a2de42d 100644
--- a/src/java/vrml/eai/field/EventInMFInt32.java
+++ b/src/java/vrml/eai/field/EventInMFInt32.java
@@ -1,67 +1,67 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventIn class for MFInt32.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventInMFInt32 extends EventIn
-{
-  /**
-   * Construct an instance of this class. The superclass is called with the
-   * type set to MFInt32.
-   */
-  protected EventInMFInt32()
-  {
-    super(MFInt32);
-  }
-
-  /**
-   * Set the value of the array of integers. If the value array is length zero
-   * this is equivalent of clearing the field.
-   *
-   * @param value The array of values to be set.
-   */
-  public abstract void setValue(int[] value);
-
-  /**
-   * Set a particular value in the given eventIn array. To the VRML
-   * world this will generate a full MFInt32 event with the nominated index
-   * value changed.
-   *  <p>
-   * If the index is out of the bounds of the current array of data values an
-   * ArrayIndexOutOfBoundsException will be generated.
-   *
-   * @param index The position to set the colour value
-   * @param value The value to be set.
-   *
-   * @exception ArrayIndexOutOfBoundsException A value did not contain at least three
-   *    values for the colour component
-   */
-  public abstract void set1Value(int index, int value)
-    throws ArrayIndexOutOfBoundsException;
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventIn class for MFInt32.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventInMFInt32 extends EventIn
+{
+  /**
+   * Construct an instance of this class. The superclass is called with the
+   * type set to MFInt32.
+   */
+  protected EventInMFInt32()
+  {
+    super(MFInt32);
+  }
+
+  /**
+   * Set the value of the array of integers. If the value array is length zero
+   * this is equivalent of clearing the field.
+   *
+   * @param value The array of values to be set.
+   */
+  public abstract void setValue(int[] value);
+
+  /**
+   * Set a particular value in the given eventIn array. To the VRML
+   * world this will generate a full MFInt32 event with the nominated index
+   * value changed.
+   *  <p>
+   * If the index is out of the bounds of the current array of data values an
+   * ArrayIndexOutOfBoundsException will be generated.
+   *
+   * @param index The position to set the colour value
+   * @param value The value to be set.
+   *
+   * @exception ArrayIndexOutOfBoundsException A value did not contain at least three
+   *    values for the colour component
+   */
+  public abstract void set1Value(int index, int value)
+    throws ArrayIndexOutOfBoundsException;
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventInMFRotation.java b/src/java/vrml/eai/field/EventInMFRotation.java
index 7589dee22d392b57e73632214ceaa688ec0ad332..4dfd3e4a4adcf4cbae67f17c970451f0e1b2acb9 100644
--- a/src/java/vrml/eai/field/EventInMFRotation.java
+++ b/src/java/vrml/eai/field/EventInMFRotation.java
@@ -1,88 +1,88 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventIn class for MFRotation.
- *  <p>
- * Rotation values are specified according to the VRML IS Specification
- *  Section 5.8 SFRotation and MFRotation.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventInMFRotation extends EventIn
-{
-  /**
-   * Construct an instance of this class. The superclass constructor is called
-   * with a type of MFRotation.
-   */
-  protected EventInMFRotation()
-  {
-    super(MFRotation);
-  }
-
-  /**
-   * Set the value of the array of rotations. Input is an array of floats
-   * values in order required to specify an SFRotation. If value[i] does not
-   * contain at least four values an ArrayIndexOutOfBoundsException will be
-   * generated. If value[i] contains more than four items only the first
-   * four values will be used and the rest ignored.
-   *
-   * @param value The array of rotation values where <br>
-   *    value[i][0] = X component [0-1]  <br>
-   *    value[i][1] = Y component [0-1]  <br>
-   *    value[i][2] = Z component [0-1]  <br>
-   *    value[i][3] = Angle of rotation [-PI - PI] (nominally).
-   *
-   * @exception ArrayIndexOutOfBoundsException A value did not contain at least four
-   *    values for the rotation
-   */
-  public abstract void setValue(float[][] value);
-
-  /**
-   * Set a particular rotation in the given eventIn array. To the VRML
-   * world this will generate a full MFRotation event with the nominated index
-   * value changed.
-   *  <p>
-   * The value array must contain at least four elements. If the array
-   * contains more than 4 values only the first four values will be used and
-   * the rest ignored.
-   *  <p>
-   * If the index is out of the bounds of the current array of data values or
-   * the array of values does not contain at least 4 elements an
-   * ArrayIndexOutOfBoundsException will be generated.
-   *
-   * @param index The position to set the rotation value
-   * @param value The array of rotation values where <br>
-   *    value[0] = X component [0-1]  <br>
-   *    value[1] = Y component [0-1]  <br>
-   *    value[2] = Z component [0-1]  <br>
-   *    value[3] = Angle of rotation [-PI - PI] (nominally).
-   *
-   * @exception ArrayIndexOutOfBoundsException A value did not contain at least four
-   *    values for the rotation
-   */
-  public abstract void set1Value(int index, float[] value);
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventIn class for MFRotation.
+ *  <p>
+ * Rotation values are specified according to the VRML IS Specification
+ *  Section 5.8 SFRotation and MFRotation.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventInMFRotation extends EventIn
+{
+  /**
+   * Construct an instance of this class. The superclass constructor is called
+   * with a type of MFRotation.
+   */
+  protected EventInMFRotation()
+  {
+    super(MFRotation);
+  }
+
+  /**
+   * Set the value of the array of rotations. Input is an array of floats
+   * values in order required to specify an SFRotation. If value[i] does not
+   * contain at least four values an ArrayIndexOutOfBoundsException will be
+   * generated. If value[i] contains more than four items only the first
+   * four values will be used and the rest ignored.
+   *
+   * @param value The array of rotation values where <br>
+   *    value[i][0] = X component [0-1]  <br>
+   *    value[i][1] = Y component [0-1]  <br>
+   *    value[i][2] = Z component [0-1]  <br>
+   *    value[i][3] = Angle of rotation [-PI - PI] (nominally).
+   *
+   * @exception ArrayIndexOutOfBoundsException A value did not contain at least four
+   *    values for the rotation
+   */
+  public abstract void setValue(float[][] value);
+
+  /**
+   * Set a particular rotation in the given eventIn array. To the VRML
+   * world this will generate a full MFRotation event with the nominated index
+   * value changed.
+   *  <p>
+   * The value array must contain at least four elements. If the array
+   * contains more than 4 values only the first four values will be used and
+   * the rest ignored.
+   *  <p>
+   * If the index is out of the bounds of the current array of data values or
+   * the array of values does not contain at least 4 elements an
+   * ArrayIndexOutOfBoundsException will be generated.
+   *
+   * @param index The position to set the rotation value
+   * @param value The array of rotation values where <br>
+   *    value[0] = X component [0-1]  <br>
+   *    value[1] = Y component [0-1]  <br>
+   *    value[2] = Z component [0-1]  <br>
+   *    value[3] = Angle of rotation [-PI - PI] (nominally).
+   *
+   * @exception ArrayIndexOutOfBoundsException A value did not contain at least four
+   *    values for the rotation
+   */
+  public abstract void set1Value(int index, float[] value);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventInMFString.java b/src/java/vrml/eai/field/EventInMFString.java
index e579737ee92e7fc2b8e390b983ac6b78c4e8f078..771eb8af3f13088df79b5d052390f97832bf4a7a 100644
--- a/src/java/vrml/eai/field/EventInMFString.java
+++ b/src/java/vrml/eai/field/EventInMFString.java
@@ -1,76 +1,76 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventIn class for MFColor.
- *  <p>
- * Strings are represented using standard java.lang.String representations.
- * The implementation of this class will provide any necessary conversions
- * to the UTF8 format required for VRML support.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventInMFString extends EventIn
-{
-  /**
-   * Construct an instance of this class. The superclass constructor is called
-   * with the type MFString
-   */
-  protected EventInMFString()
-  {
-    super(MFString);
-  }
-
-  /**
-   * Set the value of the array of strings.  If value[i] contains a null
-   * reference this will not cause an exception to be generated. However,
-   * the resulting event that the eventIn receives will be implementation
-   * specific as this is not dealt with in the VRML specification.
-   *
-   * @param value The array of strings.
-   */
-  public abstract void setValue(String[] value);
-
-  /**
-   * Set a particular string value in the given eventIn array. To the VRML
-   * world this will generate a full MFString event with the nominated index
-   * value changed.
-   *  <p>
-   * If the index is out of the bounds of the current array of data values an
-   * ArrayIndexOutOfBoundsException will be generated. If the value reference
-   * is null then the result is implementation specific in terms of the array
-   * reference that reaches the eventIn. In any case, an event will reach the
-   * destination eventIn, but the values in that array are implementation
-   * specific. No exception will be generated in this case.
-   *
-   * @param index The position to set the string value
-   * @param value The string value
-   *
-   * @exception ArrayIndexOutOfBoundsException The index value was out of bounds of
-   *     the current array.
-   */
-  public abstract void set1Value(int index, String value);
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventIn class for MFColor.
+ *  <p>
+ * Strings are represented using standard java.lang.String representations.
+ * The implementation of this class will provide any necessary conversions
+ * to the UTF8 format required for VRML support.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventInMFString extends EventIn
+{
+  /**
+   * Construct an instance of this class. The superclass constructor is called
+   * with the type MFString
+   */
+  protected EventInMFString()
+  {
+    super(MFString);
+  }
+
+  /**
+   * Set the value of the array of strings.  If value[i] contains a null
+   * reference this will not cause an exception to be generated. However,
+   * the resulting event that the eventIn receives will be implementation
+   * specific as this is not dealt with in the VRML specification.
+   *
+   * @param value The array of strings.
+   */
+  public abstract void setValue(String[] value);
+
+  /**
+   * Set a particular string value in the given eventIn array. To the VRML
+   * world this will generate a full MFString event with the nominated index
+   * value changed.
+   *  <p>
+   * If the index is out of the bounds of the current array of data values an
+   * ArrayIndexOutOfBoundsException will be generated. If the value reference
+   * is null then the result is implementation specific in terms of the array
+   * reference that reaches the eventIn. In any case, an event will reach the
+   * destination eventIn, but the values in that array are implementation
+   * specific. No exception will be generated in this case.
+   *
+   * @param index The position to set the string value
+   * @param value The string value
+   *
+   * @exception ArrayIndexOutOfBoundsException The index value was out of bounds of
+   *     the current array.
+   */
+  public abstract void set1Value(int index, String value);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventInMFTime.java b/src/java/vrml/eai/field/EventInMFTime.java
index 84ec1372d2514dbcd1a805acddb9433b4ab6c003..e18dc5d121b0162ce6e773469750394156ae19ff 100644
--- a/src/java/vrml/eai/field/EventInMFTime.java
+++ b/src/java/vrml/eai/field/EventInMFTime.java
@@ -1,80 +1,80 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventIn class for MFTime.
- *  <p>
- * Time values are represented as per the VRML IS specification Section
- * 4.11 Time. That is, time is set as VRML "Time" - the number of seconds since
- * Jan 1, 1970 GMT, rather than a Java time which is a long, the number
- * of milliseconds since Jan 1, 1970 GMT. To convert between the two simply
- * divide java time by 1000 and cast to a double.
- *  <p>
- * Note that in setting time values from an external application, the idea of
- * the time that java represents and the time that the VRML world currently
- * has set may well be different. It is best to source the current "time" from
- * a node or eventOut in the VRML world rather than relying exclusively on
- * the value returned from <code>System.currentTimeMillies</code>. This is
- * especially important to note if you are dealing with high speed, narrow
- * interval work such as controlling animation.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventInMFTime extends EventIn
-{
-  /**
-   * Construct an instance of this class. The superclass is called with the
-   * type MFTime.
-   */
-  protected EventInMFTime()
-  {
-    super(MFTime);
-  }
-
-  /**
-   * Set the value of the array of times. Time values are not required to
-   * conform to any range checks.
-   *
-   * @param value The array of time values
-   */
-  public abstract void setValue(double[] value);
-
-  /**
-   * Set a particular time value in the given eventIn array. To the VRML
-   * world this will generate a full MFTime event with the nominated index
-   * value changed.
-   *  <p>
-   * If the index is out of the bounds of the current array of data values an
-   * ArrayIndexOutOfBoundsException will be generated.
-   *
-   * @param index The position to set the time value
-   * @param value The time value to set.
-   *
-   * @exception ArrayIndexOutOfBoundsException The index was outside of the bounds of
-   * the current array.
-   */
-  public abstract void set1Value(int index, double value);
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventIn class for MFTime.
+ *  <p>
+ * Time values are represented as per the VRML IS specification Section
+ * 4.11 Time. That is, time is set as VRML "Time" - the number of seconds since
+ * Jan 1, 1970 GMT, rather than a Java time which is a long, the number
+ * of milliseconds since Jan 1, 1970 GMT. To convert between the two simply
+ * divide java time by 1000 and cast to a double.
+ *  <p>
+ * Note that in setting time values from an external application, the idea of
+ * the time that java represents and the time that the VRML world currently
+ * has set may well be different. It is best to source the current "time" from
+ * a node or eventOut in the VRML world rather than relying exclusively on
+ * the value returned from <code>System.currentTimeMillies</code>. This is
+ * especially important to note if you are dealing with high speed, narrow
+ * interval work such as controlling animation.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventInMFTime extends EventIn
+{
+  /**
+   * Construct an instance of this class. The superclass is called with the
+   * type MFTime.
+   */
+  protected EventInMFTime()
+  {
+    super(MFTime);
+  }
+
+  /**
+   * Set the value of the array of times. Time values are not required to
+   * conform to any range checks.
+   *
+   * @param value The array of time values
+   */
+  public abstract void setValue(double[] value);
+
+  /**
+   * Set a particular time value in the given eventIn array. To the VRML
+   * world this will generate a full MFTime event with the nominated index
+   * value changed.
+   *  <p>
+   * If the index is out of the bounds of the current array of data values an
+   * ArrayIndexOutOfBoundsException will be generated.
+   *
+   * @param index The position to set the time value
+   * @param value The time value to set.
+   *
+   * @exception ArrayIndexOutOfBoundsException The index was outside of the bounds of
+   * the current array.
+   */
+  public abstract void set1Value(int index, double value);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventInSFBool.java b/src/java/vrml/eai/field/EventInSFBool.java
index c31b6f1278d2970a42f01502b454d44a5fa1ede6..e2fcc877b518858f6879e0a089f57768b348fc6e 100644
--- a/src/java/vrml/eai/field/EventInSFBool.java
+++ b/src/java/vrml/eai/field/EventInSFBool.java
@@ -1,49 +1,49 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventIn class for SFBool.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventInSFBool extends EventIn
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the field type set to SFBool.
-   */
-  protected EventInSFBool()
-  {
-    super(SFBool);
-  }
-
-  /**
-   * Set the value in the given eventIn.
-   *  <p>
-   * @param value The boolean value to set the eventIn to.
-   */
-  public abstract void setValue(boolean value);
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventIn class for SFBool.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventInSFBool extends EventIn
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the field type set to SFBool.
+   */
+  protected EventInSFBool()
+  {
+    super(SFBool);
+  }
+
+  /**
+   * Set the value in the given eventIn.
+   *  <p>
+   * @param value The boolean value to set the eventIn to.
+   */
+  public abstract void setValue(boolean value);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventInSFColor.java b/src/java/vrml/eai/field/EventInSFColor.java
index 7ae3104ba646f01fcac772badf830d1b7038b47a..9dd0ef78d3bb8f9007bfe5136f9692001da61bad 100644
--- a/src/java/vrml/eai/field/EventInSFColor.java
+++ b/src/java/vrml/eai/field/EventInSFColor.java
@@ -1,69 +1,69 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventIn class for SFColor.
- *  <p>
- * Colour values are represented as floating point numbers between [0 - 1]
- * as per the VRML IS specification Section 4.4.5 Standard units and
- * coordinate system.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventInSFColor extends EventIn
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the field type set to SFColor.
-   */
-  protected EventInSFColor()
-  {
-    super(SFColor);
-  }
-
-  /**
-   * Set the colour value in the given eventIn.  Colour values are required
-   * to be in the range [0-1].
-   *  <p>
-   * The value array must contain at least three elements. If the array
-   * contains more than 3 values only the first three values will be used and
-   * the rest ignored.
-   *  <p>
-   * If the array of values does not contain at least 3 elements an
-   * ArrayIndexOutOfBoundsException will be generated. If the colour values are
-   * out of range an IllegalArgumentException will be generated.
-   *
-   * @param value The array of colour values where <br>
-   *    value[0] = Red component [0-1]  <br>
-   *    value[1] = Green component [0-1]  <br>
-   *    value[2] = Blue component [0-1]  <br>
-   *
-   * @exception IllegalArgumentException A colour value(s) was out of range
-   * @exception ArrayIndexOutOfBoundsException A value did not contain at least three
-   *    values for the colour component
-   */
-  public abstract void setValue(float[] value);
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventIn class for SFColor.
+ *  <p>
+ * Colour values are represented as floating point numbers between [0 - 1]
+ * as per the VRML IS specification Section 4.4.5 Standard units and
+ * coordinate system.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventInSFColor extends EventIn
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the field type set to SFColor.
+   */
+  protected EventInSFColor()
+  {
+    super(SFColor);
+  }
+
+  /**
+   * Set the colour value in the given eventIn.  Colour values are required
+   * to be in the range [0-1].
+   *  <p>
+   * The value array must contain at least three elements. If the array
+   * contains more than 3 values only the first three values will be used and
+   * the rest ignored.
+   *  <p>
+   * If the array of values does not contain at least 3 elements an
+   * ArrayIndexOutOfBoundsException will be generated. If the colour values are
+   * out of range an IllegalArgumentException will be generated.
+   *
+   * @param value The array of colour values where <br>
+   *    value[0] = Red component [0-1]  <br>
+   *    value[1] = Green component [0-1]  <br>
+   *    value[2] = Blue component [0-1]  <br>
+   *
+   * @exception IllegalArgumentException A colour value(s) was out of range
+   * @exception ArrayIndexOutOfBoundsException A value did not contain at least three
+   *    values for the colour component
+   */
+  public abstract void setValue(float[] value);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventInSFFloat.java b/src/java/vrml/eai/field/EventInSFFloat.java
index c1590a5dc678f615c09893c3c3b879724f21bdc8..6599482146ea8dc626655778297b1d29c0ffc482 100644
--- a/src/java/vrml/eai/field/EventInSFFloat.java
+++ b/src/java/vrml/eai/field/EventInSFFloat.java
@@ -1,49 +1,49 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventIn class for SFFloat.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventInSFFloat extends EventIn
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the field type set to SFFloat.
-   */
-  protected EventInSFFloat()
-  {
-    super(SFFloat);
-  }
-
-  /**
-   * Set the float value in the given eventIn.
-   *
-   * @param value The array of float value to set.
-   */
-  public abstract void setValue(float value);
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventIn class for SFFloat.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventInSFFloat extends EventIn
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the field type set to SFFloat.
+   */
+  protected EventInSFFloat()
+  {
+    super(SFFloat);
+  }
+
+  /**
+   * Set the float value in the given eventIn.
+   *
+   * @param value The array of float value to set.
+   */
+  public abstract void setValue(float value);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventInSFImage.java b/src/java/vrml/eai/field/EventInSFImage.java
index 678e1e5dac64a460118249ff87521cda25171b15..8527e8f82c7a9fb61c9339606d2a1bb2df801b4f 100644
--- a/src/java/vrml/eai/field/EventInSFImage.java
+++ b/src/java/vrml/eai/field/EventInSFImage.java
@@ -1,119 +1,119 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventIn class for SFImage.
- *  <p>
- * Images are represented as arrays of integers as per the VRML IS
- * specification Section 5.5 SFImage. Pixel values are between 0 and 256 and
- * represented as integers to maintain consistency with java's ImageConsumer
- * interface and PixelGrabber class.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventInSFImage extends EventIn
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the field type set to SFImage.
-   */
-  protected EventInSFImage()
-  {
-    super(SFImage);
-  }
-
-  /**
-   * Set the image value in the given eventIn.
-   *  <p>
-   * Image values are specified using a width, height and the number of
-   * components. The number of items in the pixels array must be at least
-   * <code>width * height</code>. If there are less items than this an
-   * ArrayIndexOutOfBoundsException will be generated. The integer values
-   * are represented according to the number of components. If the integer
-   * contains values in bytes that are not used by the number of components
-   * for that image, the values are ignored.
-   *  <p>
-   *  <b>1 Component Images </b> <br>
-   * The integer has the intensity value stored in the lowest byte and can be
-   * obtained:
-   *  <pre>
-   *    intensity = pixel[i] &amp;0xFF;
-   *  </pre>
-   *  <p>
-   *  <b>2 Component Images </b> <br>
-   * The integer has the intensity value stored in the lowest byte and the
-   * transparency in the top byte:
-   *  <pre>
-   *    intensity = pixel[i] &amp;0xFF;
-   *    alpha = (pixel[i] &gt;&gt; 24) &amp;0xFF00;
-   *  </pre>
-   * <i>Note</i> that this is different to the VRML representation of the image
-   * which would store the values in the text file as
-   * <code>alpha = pixel[i] &gt;&gt; 8) &amp;0xFF</code>. The reason for the difference
-   * is to maintain as much compatibility with the java image model as
-   * possible. Java does not contain a separate intensity only image model,
-   * instead it sets all three colour components to the same value. This way,
-   * the user of SFImages can take a full colour image and turn it to black + white by
-   * just setting the number of components to 2 - particularly if the three
-   * colour components are the same (which they are for an intensity only
-   * image) which will result in the correct intepretation of the image.
-   *  <p>
-   *  <b>3 Component Images </b> <br>
-   * The three colour components are stored in the integer array as follows:
-   *  <pre>
-        red   = (pixel[i] &gt;&gt; 16) &amp;0xFF;
-        green = (pixel[i] &gt;&gt;  8) &amp;0xFF;
-        blue  = (pixel[i]      ) &amp;0xFF;
-   *  </pre>
-   *  <p>
-   *  <b>4 Component Images </b> <br>
-   * The integer has the value stored in the array as follows:
-   *  <pre>
-        alpha = (pixel &gt;&gt; 24) &amp;0xff;
-        red   = (pixel &gt;&gt; 16) &amp;0xff;
-        green = (pixel &gt;&gt;  8) &amp;0xff;
-        blue  = (pixel      ) &amp;0xff;
-   *  </pre>
-   *  <p>
-   * The width and height values must be greater than or equal to zero. The
-   * number of components is between 1 and 4. Any value outside of these
-   * bounds will generate an IllegalArgumentException.
-   *
-   * @param width The width of the image in pixels
-   * @param height The height of the image in pixels
-   * @param components The number of colour components [1-4]
-   * @param pixels The array of pixel values as specified above.
-   *
-   * @exception IllegalArgumentException The number of components or width/
-   *    height are illegal values.
-   * @exception ArrayIndexOutOfBoundsException The number of pixels provided by the
-   *    caller is not enough for the width * height.
-   */
-  public abstract void setValue(int width,
-                                int height,
-                                int components,
-                                int[] pixels);
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventIn class for SFImage.
+ *  <p>
+ * Images are represented as arrays of integers as per the VRML IS
+ * specification Section 5.5 SFImage. Pixel values are between 0 and 256 and
+ * represented as integers to maintain consistency with java's ImageConsumer
+ * interface and PixelGrabber class.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventInSFImage extends EventIn
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the field type set to SFImage.
+   */
+  protected EventInSFImage()
+  {
+    super(SFImage);
+  }
+
+  /**
+   * Set the image value in the given eventIn.
+   *  <p>
+   * Image values are specified using a width, height and the number of
+   * components. The number of items in the pixels array must be at least
+   * <code>width * height</code>. If there are less items than this an
+   * ArrayIndexOutOfBoundsException will be generated. The integer values
+   * are represented according to the number of components. If the integer
+   * contains values in bytes that are not used by the number of components
+   * for that image, the values are ignored.
+   *  <p>
+   *  <b>1 Component Images </b> <br>
+   * The integer has the intensity value stored in the lowest byte and can be
+   * obtained:
+   *  <pre>
+   *    intensity = pixel[i] &amp;0xFF;
+   *  </pre>
+   *  <p>
+   *  <b>2 Component Images </b> <br>
+   * The integer has the intensity value stored in the lowest byte and the
+   * transparency in the top byte:
+   *  <pre>
+   *    intensity = pixel[i] &amp;0xFF;
+   *    alpha = (pixel[i] &gt;&gt; 24) &amp;0xFF00;
+   *  </pre>
+   * <i>Note</i> that this is different to the VRML representation of the image
+   * which would store the values in the text file as
+   * <code>alpha = pixel[i] &gt;&gt; 8) &amp;0xFF</code>. The reason for the difference
+   * is to maintain as much compatibility with the java image model as
+   * possible. Java does not contain a separate intensity only image model,
+   * instead it sets all three colour components to the same value. This way,
+   * the user of SFImages can take a full colour image and turn it to black + white by
+   * just setting the number of components to 2 - particularly if the three
+   * colour components are the same (which they are for an intensity only
+   * image) which will result in the correct intepretation of the image.
+   *  <p>
+   *  <b>3 Component Images </b> <br>
+   * The three colour components are stored in the integer array as follows:
+   *  <pre>
+        red   = (pixel[i] &gt;&gt; 16) &amp;0xFF;
+        green = (pixel[i] &gt;&gt;  8) &amp;0xFF;
+        blue  = (pixel[i]      ) &amp;0xFF;
+   *  </pre>
+   *  <p>
+   *  <b>4 Component Images </b> <br>
+   * The integer has the value stored in the array as follows:
+   *  <pre>
+        alpha = (pixel &gt;&gt; 24) &amp;0xff;
+        red   = (pixel &gt;&gt; 16) &amp;0xff;
+        green = (pixel &gt;&gt;  8) &amp;0xff;
+        blue  = (pixel      ) &amp;0xff;
+   *  </pre>
+   *  <p>
+   * The width and height values must be greater than or equal to zero. The
+   * number of components is between 1 and 4. Any value outside of these
+   * bounds will generate an IllegalArgumentException.
+   *
+   * @param width The width of the image in pixels
+   * @param height The height of the image in pixels
+   * @param components The number of colour components [1-4]
+   * @param pixels The array of pixel values as specified above.
+   *
+   * @exception IllegalArgumentException The number of components or width/
+   *    height are illegal values.
+   * @exception ArrayIndexOutOfBoundsException The number of pixels provided by the
+   *    caller is not enough for the width * height.
+   */
+  public abstract void setValue(int width,
+                                int height,
+                                int components,
+                                int[] pixels);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventInSFInt32.java b/src/java/vrml/eai/field/EventInSFInt32.java
index b6edc9e037e850c033eb02d9fd1e479e2cffd011..6e5b14b37a7d0da17068b40b07a183034d8325e0 100644
--- a/src/java/vrml/eai/field/EventInSFInt32.java
+++ b/src/java/vrml/eai/field/EventInSFInt32.java
@@ -1,51 +1,51 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventIn class for SFInt32.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventInSFInt32 extends EventIn
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the field type set to SFInt32.
-   */
-  protected EventInSFInt32()
-  {
-    super(SFInt32);
-  }
-
-  /**
-   * Set the value in the given eventIn.
-   *
-   * @param value The value to be set
-   */
-  public abstract void setValue(int value);
-}
-
-
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventIn class for SFInt32.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventInSFInt32 extends EventIn
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the field type set to SFInt32.
+   */
+  protected EventInSFInt32()
+  {
+    super(SFInt32);
+  }
+
+  /**
+   * Set the value in the given eventIn.
+   *
+   * @param value The value to be set
+   */
+  public abstract void setValue(int value);
+}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventInSFNode.java b/src/java/vrml/eai/field/EventInSFNode.java
index 2982fb443524f7ac095c9409fec990bbe24e4f01..fa4ade8373e81a809145c535c5c42fc137a2666a 100644
--- a/src/java/vrml/eai/field/EventInSFNode.java
+++ b/src/java/vrml/eai/field/EventInSFNode.java
@@ -1,69 +1,69 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-import vrml.eai.Node;
-import vrml.eai.InvalidNodeException;
-
-/**
- * VRML eventIn class for SFNode.
- *  <p>
- * Set the value of a node to the given value. The java <code>null</code>
- * reference is treated to be equivalent to the VRML <code>NULL</code> field
- * values.
- *  <p>
- * Calling the set method with a null node reference causes that field to
- * be cleared.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventInSFNode extends EventIn
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the field type set to SFNode.
-   */
-  protected EventInSFNode()
-  {
-    super(SFNode);
-  }
-
-  /**
-   * Set the node value in the given eventIn.
-   *  <p>
-   * If the node reference passed to this method has already had the dispose
-   * method called then an InvalidNodeException will be generated.
-   *
-   * @param value The new node reference to be used.
-   *
-   * @exception InvalidNodeException The node reference passed has already
-   *    been disposed.
-   */
-  public abstract void setValue(Node value)
-      throws InvalidNodeException;
-}
-
-
-
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+import vrml.eai.Node;
+import vrml.eai.InvalidNodeException;
+
+/**
+ * VRML eventIn class for SFNode.
+ *  <p>
+ * Set the value of a node to the given value. The java <code>null</code>
+ * reference is treated to be equivalent to the VRML <code>NULL</code> field
+ * values.
+ *  <p>
+ * Calling the set method with a null node reference causes that field to
+ * be cleared.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventInSFNode extends EventIn
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the field type set to SFNode.
+   */
+  protected EventInSFNode()
+  {
+    super(SFNode);
+  }
+
+  /**
+   * Set the node value in the given eventIn.
+   *  <p>
+   * If the node reference passed to this method has already had the dispose
+   * method called then an InvalidNodeException will be generated.
+   *
+   * @param value The new node reference to be used.
+   *
+   * @exception InvalidNodeException The node reference passed has already
+   *    been disposed.
+   */
+  public abstract void setValue(Node value)
+      throws InvalidNodeException;
+}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventInSFRotation.java b/src/java/vrml/eai/field/EventInSFRotation.java
index 6d0090b72bde1ac9e3731f1deef80438dfb25a7d..5520cfe2718ae036a40f526e6003a993898ccb08 100644
--- a/src/java/vrml/eai/field/EventInSFRotation.java
+++ b/src/java/vrml/eai/field/EventInSFRotation.java
@@ -1,66 +1,66 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventIn class for SFRotation.
- *  <p>
- * Rotation values are specified according to the VRML IS Specification
- * Section 5.8 SFRotation and MFRotation.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventInSFRotation extends EventIn
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the field type set to SFRotation
-   */
-  protected EventInSFRotation()
-  {
-    super(SFRotation);
-  }
-
-  /**
-   * Set the rotation value in the given eventIn.
-   *  <p>
-   * The value array must contain at least four elements. If the array
-   * contains more than 4 values only the first 4 values will be used and
-   * the rest ignored.
-   *  <p>
-   * If the array of values does not contain at least 4 elements an
-   * ArrayIndexOutOfBoundsException will be generated.
-   *
-   * @param value The array of rotation values where <br>
-   *    value[0] = X component [0-1]  <br>
-   *    value[1] = Y component [0-1]  <br>
-   *    value[2] = Z component [0-1]  <br>
-   *    value[3] = Angle of rotation [-PI - PI] (nominally).
-   *
-   * @exception ArrayIndexOutOfBoundsException The value did not contain at least 4
-   *    values for the rotation.
-   */
-  public abstract void setValue(float[] value);
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventIn class for SFRotation.
+ *  <p>
+ * Rotation values are specified according to the VRML IS Specification
+ * Section 5.8 SFRotation and MFRotation.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventInSFRotation extends EventIn
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the field type set to SFRotation
+   */
+  protected EventInSFRotation()
+  {
+    super(SFRotation);
+  }
+
+  /**
+   * Set the rotation value in the given eventIn.
+   *  <p>
+   * The value array must contain at least four elements. If the array
+   * contains more than 4 values only the first 4 values will be used and
+   * the rest ignored.
+   *  <p>
+   * If the array of values does not contain at least 4 elements an
+   * ArrayIndexOutOfBoundsException will be generated.
+   *
+   * @param value The array of rotation values where <br>
+   *    value[0] = X component [0-1]  <br>
+   *    value[1] = Y component [0-1]  <br>
+   *    value[2] = Z component [0-1]  <br>
+   *    value[3] = Angle of rotation [-PI - PI] (nominally).
+   *
+   * @exception ArrayIndexOutOfBoundsException The value did not contain at least 4
+   *    values for the rotation.
+   */
+  public abstract void setValue(float[] value);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventInSFString.java b/src/java/vrml/eai/field/EventInSFString.java
index dde67911bbd97eef0f1dc829315f75cd08877d9b..386f976bdf0eb72c3b6305a5079cd8505c611c1a 100644
--- a/src/java/vrml/eai/field/EventInSFString.java
+++ b/src/java/vrml/eai/field/EventInSFString.java
@@ -1,57 +1,57 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventIn class for SFString.
- *  <p>
- * Strings are represented using standard java.lang.String representations.
- * The implementation of this class will provide any necessary conversions
- * to the UTF8 format required for VRML support.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventInSFString extends EventIn
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the field type set to SFString.
-   */
-  protected EventInSFString()
-  {
-    super(SFString);
-  }
-
-  /**
-   * Set the string value in the given eventIn.
-   *  <p>
-   * A string is not required to be valid. A null string reference will
-   * be considered equivalent to a zero length string resulting in the
-   * string being cleared.
-   *
-   * @param value The string to set.
-   */
-  public abstract void setValue(String value);
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventIn class for SFString.
+ *  <p>
+ * Strings are represented using standard java.lang.String representations.
+ * The implementation of this class will provide any necessary conversions
+ * to the UTF8 format required for VRML support.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventInSFString extends EventIn
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the field type set to SFString.
+   */
+  protected EventInSFString()
+  {
+    super(SFString);
+  }
+
+  /**
+   * Set the string value in the given eventIn.
+   *  <p>
+   * A string is not required to be valid. A null string reference will
+   * be considered equivalent to a zero length string resulting in the
+   * string being cleared.
+   *
+   * @param value The string to set.
+   */
+  public abstract void setValue(String value);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventInSFTime.java b/src/java/vrml/eai/field/EventInSFTime.java
index e81ba815eabdbba5936603e4e203860770187ffc..9963e199928b35538cb1bbf3ed3ac3b691b30d9d 100644
--- a/src/java/vrml/eai/field/EventInSFTime.java
+++ b/src/java/vrml/eai/field/EventInSFTime.java
@@ -1,67 +1,67 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventIn class for SFTime.
- *  <p>
- * Time values are represented as per the VRML IS specification Section
- * 4.11 Time. That is, time is set as VRML "Time" - the number of seconds since
- * Jan 1, 1970 GMT, rather than a Java time which is a long, the number
- * of milliseconds since Jan 1, 1970 GMT. To convert between the two simply
- * divide java time by 1000 and cast to a double.
- *  <p>
- * Note that in setting time values from an external application, the idea of
- * the time that java represents and the time that the VRML world currently
- * has set may well be different. It is best to source the current "time" from
- * a node or eventOut in the VRML world rather than relying exclusively on
- * the value returned from <code>System.currentTimeMillies</code>. This is
- * especially important to note if you are dealing with high speed, narrow
- * interval work such as controlling animation.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventInSFTime extends EventIn
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the field type set to SFTime.
-   */
-  protected EventInSFTime()
-  {
-    super(SFTime);
-  }
-
-  /**
-   * Set the time value in the given eventIn. Time can be any value either
-   * positive or negative but always absolute in value. As per the VRML
-   * time specification, all time values are to be absolute.
-   *
-   * @param value The time value to be set.
-   */
-  public abstract void setValue(double value);
-}
-
-
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventIn class for SFTime.
+ *  <p>
+ * Time values are represented as per the VRML IS specification Section
+ * 4.11 Time. That is, time is set as VRML "Time" - the number of seconds since
+ * Jan 1, 1970 GMT, rather than a Java time which is a long, the number
+ * of milliseconds since Jan 1, 1970 GMT. To convert between the two simply
+ * divide java time by 1000 and cast to a double.
+ *  <p>
+ * Note that in setting time values from an external application, the idea of
+ * the time that java represents and the time that the VRML world currently
+ * has set may well be different. It is best to source the current "time" from
+ * a node or eventOut in the VRML world rather than relying exclusively on
+ * the value returned from <code>System.currentTimeMillies</code>. This is
+ * especially important to note if you are dealing with high speed, narrow
+ * interval work such as controlling animation.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventInSFTime extends EventIn
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the field type set to SFTime.
+   */
+  protected EventInSFTime()
+  {
+    super(SFTime);
+  }
+
+  /**
+   * Set the time value in the given eventIn. Time can be any value either
+   * positive or negative but always absolute in value. As per the VRML
+   * time specification, all time values are to be absolute.
+   *
+   * @param value The time value to be set.
+   */
+  public abstract void setValue(double value);
+}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventInSFVec2f.java b/src/java/vrml/eai/field/EventInSFVec2f.java
index 5fdf3d277989c54a7e3b1a08e6c1b11f45d4b300..99786960dc88d90c6f8ac895d3e04094d0dd7de7 100644
--- a/src/java/vrml/eai/field/EventInSFVec2f.java
+++ b/src/java/vrml/eai/field/EventInSFVec2f.java
@@ -1,61 +1,61 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventIn class for SFVec2f.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventInSFVec2f extends EventIn
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the field type set to SFVec2f.
-   */
-  protected EventInSFVec2f()
-  {
-    super(SFVec2f);
-  }
-
-  /**
-   * Set the vector value in the given eventIn.
-   *  <p>
-   * The value array must contain at least two elements. If the array
-   * contains more than 2 values only the first 2 values will be used and
-   * the rest ignored.
-   *  <p>
-   * If the array of values does not contain at least 2 elements an
-   * ArrayIndexOutOfBoundsException will be generated.
-   *
-   * @param value The array of vector components where <br>
-   *    value[0] = X <br>
-   *    value[1] = Y <br>
-   *
-   * @exception ArrayIndexOutOfBoundsException The value did not contain at least two
-   *    values for the vector
-   */
-  public abstract void setValue(float[] value);
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventIn class for SFVec2f.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventInSFVec2f extends EventIn
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the field type set to SFVec2f.
+   */
+  protected EventInSFVec2f()
+  {
+    super(SFVec2f);
+  }
+
+  /**
+   * Set the vector value in the given eventIn.
+   *  <p>
+   * The value array must contain at least two elements. If the array
+   * contains more than 2 values only the first 2 values will be used and
+   * the rest ignored.
+   *  <p>
+   * If the array of values does not contain at least 2 elements an
+   * ArrayIndexOutOfBoundsException will be generated.
+   *
+   * @param value The array of vector components where <br>
+   *    value[0] = X <br>
+   *    value[1] = Y <br>
+   *
+   * @exception ArrayIndexOutOfBoundsException The value did not contain at least two
+   *    values for the vector
+   */
+  public abstract void setValue(float[] value);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventOut.java b/src/java/vrml/eai/field/EventOut.java
index 347ead29ffdd7198c1bb42686d79482ef55e878d..74142b23a8e3c5e00d1670c40035f29fcda7a97a 100644
--- a/src/java/vrml/eai/field/EventOut.java
+++ b/src/java/vrml/eai/field/EventOut.java
@@ -1,70 +1,70 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-import vrml.eai.event.VrmlEventListener;
-
-/**
- * A VRML eventOut class. Represents the VRML read only access type.
- *  <p>
- * The user can encapsulate data and associate that with this field. The user
- * can register themselves as listeners for the output of this event changing
- * by adding themselves as a VRMLEvent listener.
- *
- * @version 1.0 7th March 1998
- */
-public abstract class EventOut extends BaseField
-{
-    /**
-     * Construct an instance of this class.
-     *
-     * @param type The type of the field
-     */
-    protected EventOut(int type)
-    {
-        super(type);
-    }
-
-    /**
-     * Add a listener for changes in this eventOut.
-     *
-     * @param l The listener to add
-     */
-    public abstract void addVrmlEventListener(VrmlEventListener l);
-
-    /**
-     * Remove a listener for changes in this eventOut.
-     *
-     * @param l The listener to remove
-     */
-    public abstract void removeVrmlEventListener(VrmlEventListener l);
-
-    /**
-     * Associate user data with this event. Whenever an event is generated
-     * on this eventOut. this data will be available with the Event through
-     * its getData method.
-     *
-     * @param data The data to associate with this eventOut instance
-     */
-    public abstract void setUserData(Object data);
-
-    /**
-     * Get the user data that is associated with this eventOut
-     *
-     * @return The user data, if any, associated with this eventOut
-     */
-    public abstract Object getUserData();
-}
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+import vrml.eai.event.VrmlEventListener;
+
+/**
+ * A VRML eventOut class. Represents the VRML read only access type.
+ *  <p>
+ * The user can encapsulate data and associate that with this field. The user
+ * can register themselves as listeners for the output of this event changing
+ * by adding themselves as a VRMLEvent listener.
+ *
+ * @version 1.0 7th March 1998
+ */
+public abstract class EventOut extends BaseField
+{
+    /**
+     * Construct an instance of this class.
+     *
+     * @param type The type of the field
+     */
+    protected EventOut(int type)
+    {
+        super(type);
+    }
+
+    /**
+     * Add a listener for changes in this eventOut.
+     *
+     * @param l The listener to add
+     */
+    public abstract void addVrmlEventListener(VrmlEventListener l);
+
+    /**
+     * Remove a listener for changes in this eventOut.
+     *
+     * @param l The listener to remove
+     */
+    public abstract void removeVrmlEventListener(VrmlEventListener l);
+
+    /**
+     * Associate user data with this event. Whenever an event is generated
+     * on this eventOut. this data will be available with the Event through
+     * its getData method.
+     *
+     * @param data The data to associate with this eventOut instance
+     */
+    public abstract void setUserData(Object data);
+
+    /**
+     * Get the user data that is associated with this eventOut
+     *
+     * @return The user data, if any, associated with this eventOut
+     */
+    public abstract Object getUserData();
+}
diff --git a/src/java/vrml/eai/field/EventOutMFColor.java b/src/java/vrml/eai/field/EventOutMFColor.java
index e0c27ed829c491352aa4b487c61d1a208de34b24..1eb2ae44abfe215cbb4b757993d10dcf5f7e2d85 100644
--- a/src/java/vrml/eai/field/EventOutMFColor.java
+++ b/src/java/vrml/eai/field/EventOutMFColor.java
@@ -1,112 +1,112 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventOut class for MFColor.
- *  <p>
- * Colour values are represented as floating point numbers between [0 - 1]
- * as per the VRML IS specification Section 4.4.5 Standard units and
- * coordinate system
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventOutMFColor extends EventOutMField
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the type set to MFColor.
-   */
-  protected EventOutMFColor()
-  {
-    super(MFColor);
-  }
-
-  /**
-   * Get the value of the array of colours. Input is an array of colour
-   * values in RGB order. All colour values will to be in the
-   * range 0-1.
-   *
-   * @return The array of colour values where <br>
-   *    value[i][0] = Red component [0-1]  <br>
-   *    value[i][1] = Green component [0-1]  <br>
-   *    value[i][2] = Blue component [0-1]  <br>
-   */
-  public abstract float[][] getValue();
-
-  /**
-   * Write the value of the event out to the given array.
-   *
-   * @param col The array to be filled in where <br>
-   *    col[i][0] = Red component [0-1]  <br>
-   *    col[i][1] = Green component [0-1]  <br>
-   *    col[i][2] = Blue component [0-1]  <br>
-   * @exception ArrayIndexOutOfBoundsException The provided array was too small
-   */
-  public abstract void getValue(float[][] col);
-
-  /**
-   * Get the values of the event out flattened into a single 1D array. The
-   * array must be at least 3 times the size of the array.
-   *
-   * @param col The array to be filled in where the
-   *    col[i + 0] = Red component [0-1]  <br>
-   *    col[i + 1] = Green component [0-1]  <br>
-   *    col[i + 2] = Blue component [0-1]  <br>
-   * @exception ArrayIndexOutOfBoundsException The provided array was too small
-   */
-  public abstract void getValue(float[] col);
-
-  /**
-   * Get a particular colour value in the given eventIn array. Colour values
-   * are in the range [0-1].
-   *  <p>
-   * If the index is out of the bounds of the current array of data values an
-   * ArrayIndexOutOfBoundsException will be generated.
-   *
-   * @param index The position to get the colour value
-   * @return value The array of colour values where <br>
-   *    value[0] = Red component [0-1]  <br>
-   *    value[1] = Green component [0-1]  <br>
-   *    value[2] = Blue component [0-1]  <br>
-   *
-   * @exception ArrayIndexOutOfBoundsException The index was outside the current data
-   *    array bounds.
-   */
-  public abstract float[] get1Value(int index);
-
-  /**
-   * Get the value of a particular vector value in the event out array.
-   *
-   * @param index The position to get the vector value from.
-   * @param col The array to place the value in where.
-   *    col[0] = Red component [0-1]  <br>
-   *    col[1] = Green component [0-1]  <br>
-   *    col[2] = Blue component [0-1]  <br>
-   * @exception ArrayIndexOutOfBoundsException The provided array was too small or
-   *     the index was outside the current data array bounds.
-   */
-  public abstract void get1Value(int index, float[] col);
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventOut class for MFColor.
+ *  <p>
+ * Colour values are represented as floating point numbers between [0 - 1]
+ * as per the VRML IS specification Section 4.4.5 Standard units and
+ * coordinate system
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventOutMFColor extends EventOutMField
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the type set to MFColor.
+   */
+  protected EventOutMFColor()
+  {
+    super(MFColor);
+  }
+
+  /**
+   * Get the value of the array of colours. Input is an array of colour
+   * values in RGB order. All colour values will to be in the
+   * range 0-1.
+   *
+   * @return The array of colour values where <br>
+   *    value[i][0] = Red component [0-1]  <br>
+   *    value[i][1] = Green component [0-1]  <br>
+   *    value[i][2] = Blue component [0-1]  <br>
+   */
+  public abstract float[][] getValue();
+
+  /**
+   * Write the value of the event out to the given array.
+   *
+   * @param col The array to be filled in where <br>
+   *    col[i][0] = Red component [0-1]  <br>
+   *    col[i][1] = Green component [0-1]  <br>
+   *    col[i][2] = Blue component [0-1]  <br>
+   * @exception ArrayIndexOutOfBoundsException The provided array was too small
+   */
+  public abstract void getValue(float[][] col);
+
+  /**
+   * Get the values of the event out flattened into a single 1D array. The
+   * array must be at least 3 times the size of the array.
+   *
+   * @param col The array to be filled in where the
+   *    col[i + 0] = Red component [0-1]  <br>
+   *    col[i + 1] = Green component [0-1]  <br>
+   *    col[i + 2] = Blue component [0-1]  <br>
+   * @exception ArrayIndexOutOfBoundsException The provided array was too small
+   */
+  public abstract void getValue(float[] col);
+
+  /**
+   * Get a particular colour value in the given eventIn array. Colour values
+   * are in the range [0-1].
+   *  <p>
+   * If the index is out of the bounds of the current array of data values an
+   * ArrayIndexOutOfBoundsException will be generated.
+   *
+   * @param index The position to get the colour value
+   * @return value The array of colour values where <br>
+   *    value[0] = Red component [0-1]  <br>
+   *    value[1] = Green component [0-1]  <br>
+   *    value[2] = Blue component [0-1]  <br>
+   *
+   * @exception ArrayIndexOutOfBoundsException The index was outside the current data
+   *    array bounds.
+   */
+  public abstract float[] get1Value(int index);
+
+  /**
+   * Get the value of a particular vector value in the event out array.
+   *
+   * @param index The position to get the vector value from.
+   * @param col The array to place the value in where.
+   *    col[0] = Red component [0-1]  <br>
+   *    col[1] = Green component [0-1]  <br>
+   *    col[2] = Blue component [0-1]  <br>
+   * @exception ArrayIndexOutOfBoundsException The provided array was too small or
+   *     the index was outside the current data array bounds.
+   */
+  public abstract void get1Value(int index, float[] col);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventOutMFFloat.java b/src/java/vrml/eai/field/EventOutMFFloat.java
index 50e2bb994882a9e1c46bd042b5c472b972efeaa7..c588dd5c2e89cb3bdd5827c994d0f3e6dd5c242a 100644
--- a/src/java/vrml/eai/field/EventOutMFFloat.java
+++ b/src/java/vrml/eai/field/EventOutMFFloat.java
@@ -1,75 +1,75 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventOut class for MFFloat.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventOutMFFloat extends EventOutMField
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the type MFFloat
-   */
-  protected EventOutMFFloat()
-  {
-    super(MFFloat);
-  }
-
-  /**
-   * Get the value of the eventOut array of float values.
-   *
-   * @return The array of values currently set.
-   */
-  public abstract float[] getValue();
-
-  /**
-   * Write the value of the array of the floats to the given array.
-   *
-   * @param values The array to be filled in
-   * @exception ArrayIndexOutOfBoundsException The provided array was too small
-   */
-  public abstract void getValue(float[] values);
-
-  /**
-   * Get the value of an individual item in the eventOut's value.
-   *
-   * If the index is out of the bounds of the current array of data values an
-   * ArrayIndexOutOfBoundsException will be generated.
-   *
-   * @param index The position to be retrieved
-   * @return The value to at that position
-   *
-   * @exception ArrayIndexOutOfBoundsException The index was outside the current data
-   *    array bounds.
-   */
-  public abstract float get1Value(int index)
-        throws ArrayIndexOutOfBoundsException;
-}
-
-
-
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventOut class for MFFloat.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventOutMFFloat extends EventOutMField
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the type MFFloat
+   */
+  protected EventOutMFFloat()
+  {
+    super(MFFloat);
+  }
+
+  /**
+   * Get the value of the eventOut array of float values.
+   *
+   * @return The array of values currently set.
+   */
+  public abstract float[] getValue();
+
+  /**
+   * Write the value of the array of the floats to the given array.
+   *
+   * @param values The array to be filled in
+   * @exception ArrayIndexOutOfBoundsException The provided array was too small
+   */
+  public abstract void getValue(float[] values);
+
+  /**
+   * Get the value of an individual item in the eventOut's value.
+   *
+   * If the index is out of the bounds of the current array of data values an
+   * ArrayIndexOutOfBoundsException will be generated.
+   *
+   * @param index The position to be retrieved
+   * @return The value to at that position
+   *
+   * @exception ArrayIndexOutOfBoundsException The index was outside the current data
+   *    array bounds.
+   */
+  public abstract float get1Value(int index)
+        throws ArrayIndexOutOfBoundsException;
+}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventOutMFInt32.java b/src/java/vrml/eai/field/EventOutMFInt32.java
index b63c0b46c690b51987aeea06d8be18b5767c04db..b4c60fde426bd081b8326d3c463c4a6acd5062b3 100644
--- a/src/java/vrml/eai/field/EventOutMFInt32.java
+++ b/src/java/vrml/eai/field/EventOutMFInt32.java
@@ -1,74 +1,74 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventOut class for MFInt32.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventOutMFInt32 extends EventOutMField
-{
-  /**
-   * Construct an instance of this class. The superclass is called with the
-   * type set to MFInt32.
-   */
-  protected EventOutMFInt32()
-  {
-    super(MFInt32);
-  }
-
-  /**
-   * Get the value of the array of integers.
-   *
-   * @return The current array of values.
-   */
-  public abstract int[] getValue();
-
-  /**
-   * Write the value of the array of the ints to the given array.
-   *
-   * @param values The array to be filled in
-   * @exception ArrayIndexOutOfBoundsException The provided array was too small
-   */
-  public abstract void getValue(int[] values);
-
-  /**
-   * Get a particular value from the eventOut array.
-   *  <p>
-   * If the index is out of the bounds of the current array of data values an
-   * ArrayIndexOutOfBoundsException will be generated.
-   *
-   * @param index The position to be retrieved
-   * @return The value at that position
-   *
-   * @exception ArrayIndexOutOfBoundsException The index was outside the current data
-   *    array bounds.
-   */
-  public abstract int get1Value(int index)
-        throws ArrayIndexOutOfBoundsException;
-}
-
-
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventOut class for MFInt32.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventOutMFInt32 extends EventOutMField
+{
+  /**
+   * Construct an instance of this class. The superclass is called with the
+   * type set to MFInt32.
+   */
+  protected EventOutMFInt32()
+  {
+    super(MFInt32);
+  }
+
+  /**
+   * Get the value of the array of integers.
+   *
+   * @return The current array of values.
+   */
+  public abstract int[] getValue();
+
+  /**
+   * Write the value of the array of the ints to the given array.
+   *
+   * @param values The array to be filled in
+   * @exception ArrayIndexOutOfBoundsException The provided array was too small
+   */
+  public abstract void getValue(int[] values);
+
+  /**
+   * Get a particular value from the eventOut array.
+   *  <p>
+   * If the index is out of the bounds of the current array of data values an
+   * ArrayIndexOutOfBoundsException will be generated.
+   *
+   * @param index The position to be retrieved
+   * @return The value at that position
+   *
+   * @exception ArrayIndexOutOfBoundsException The index was outside the current data
+   *    array bounds.
+   */
+  public abstract int get1Value(int index)
+        throws ArrayIndexOutOfBoundsException;
+}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventOutMFRotation.java b/src/java/vrml/eai/field/EventOutMFRotation.java
index 1536f4394a04c813eca75d617e82d8c75e79a836..8a53898d4a09010c76499a9d599e501a4c90fa30 100644
--- a/src/java/vrml/eai/field/EventOutMFRotation.java
+++ b/src/java/vrml/eai/field/EventOutMFRotation.java
@@ -1,114 +1,114 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventOut class for MFRotation.
- *  <p>
- * Rotation values are specified according to the VRML IS Specification
- *  Section 5.8 SFRotation and MFRotation.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventOutMFRotation extends EventOutMField
-{
-  /**
-   * Construct an instance of this class. The superclass constructor is called
-   * with a type of MFRotation.
-   */
-  protected EventOutMFRotation()
-  {
-    super(MFRotation);
-  }
-
-  /**
-   * Get the value of the array of rotations. Output is an array of floats
-   * values in order required to specify an SFRotation.
-   *
-   * @return The array of rotation values where <br>
-   *    value[i][0] = X component [0-1]  <br>
-   *    value[i][1] = Y component [0-1]  <br>
-   *    value[i][2] = Z component [0-1]  <br>
-   *    value[i][3] = Angle of rotation [-PI - PI] (nominally).
-   */
-  public abstract float[][] getValue();
-
-  /**
-   * Write the value of the event out to the given array.
-   *
-   * @param vec The array to be filled in where <br>
-   *    value[i][0] = X component [0-1]  <br>
-   *    value[i][1] = Y component [0-1]  <br>
-   *    value[i][2] = Z component [0-1]  <br>
-   *    value[i][3] = Angle of rotation [-PI - PI] (nominally).
-   * @exception ArrayIndexOutOfBoundsException The provided array was too small
-   */
-  public abstract void getValue(float[][] vec);
-
-  /**
-   * Get the values of the event out flattened into a single 1D array. The
-   * array must be at least 4 times the size of the array.
-   *
-   * @param vec The array to be filled in where the
-   *    value[i + 0] = X component [0-1]  <br>
-   *    value[i + 1] = Y component [0-1]  <br>
-   *    value[i + 2] = Z component [0-1]  <br>
-   *    value[i + 3] = Angle of rotation [-PI - PI] (nominally).
-   * @exception ArrayIndexOutOfBoundsException The provided array was too small
-   */
-  public abstract void getValue(float[] vec);
-
-  /**
-   * Get a particular rotation in the given eventOut array.
-   *  <p>
-   * If the index is out of the bounds of the current array of data values an
-   * ArrayIndexOutOfBoundsException will be generated.
-   *
-   * @param index The position to get the rotation value
-   * @return The array of rotation values where <br>
-   *    value[0] = X component [0-1]  <br>
-   *    value[1] = Y component [0-1]  <br>
-   *    value[2] = Z component [0-1]  <br>
-   *    value[3] = Angle of rotation [-PI - PI] (nominally).
-   *
-   * @exception ArrayIndexOutOfBoundsException The index was outside the current data
-   *    array bounds.
-   */
-  public abstract float[] get1Value(int index);
-
-  /**
-   * Get the value of a particular rotation value in the event out array.
-   *
-   * @param index The position to get the vector value from.
-   * @param vec The array to place the value in where.
-   *    vec[0] = X component [0-1]  <br>
-   *    vec[1] = Y component [0-1]  <br>
-   *    vec[2] = Z component [0-1]  <br>
-   *    vec[3] = Angle of rotation [-PI - PI] (nominally).
-   * @exception ArrayIndexOutOfBoundsException The provided array was too small or
-   *     the index was outside the current data array bounds.
-   */
-  public abstract void get1Value(int index, float[] vec);
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventOut class for MFRotation.
+ *  <p>
+ * Rotation values are specified according to the VRML IS Specification
+ *  Section 5.8 SFRotation and MFRotation.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventOutMFRotation extends EventOutMField
+{
+  /**
+   * Construct an instance of this class. The superclass constructor is called
+   * with a type of MFRotation.
+   */
+  protected EventOutMFRotation()
+  {
+    super(MFRotation);
+  }
+
+  /**
+   * Get the value of the array of rotations. Output is an array of floats
+   * values in order required to specify an SFRotation.
+   *
+   * @return The array of rotation values where <br>
+   *    value[i][0] = X component [0-1]  <br>
+   *    value[i][1] = Y component [0-1]  <br>
+   *    value[i][2] = Z component [0-1]  <br>
+   *    value[i][3] = Angle of rotation [-PI - PI] (nominally).
+   */
+  public abstract float[][] getValue();
+
+  /**
+   * Write the value of the event out to the given array.
+   *
+   * @param vec The array to be filled in where <br>
+   *    value[i][0] = X component [0-1]  <br>
+   *    value[i][1] = Y component [0-1]  <br>
+   *    value[i][2] = Z component [0-1]  <br>
+   *    value[i][3] = Angle of rotation [-PI - PI] (nominally).
+   * @exception ArrayIndexOutOfBoundsException The provided array was too small
+   */
+  public abstract void getValue(float[][] vec);
+
+  /**
+   * Get the values of the event out flattened into a single 1D array. The
+   * array must be at least 4 times the size of the array.
+   *
+   * @param vec The array to be filled in where the
+   *    value[i + 0] = X component [0-1]  <br>
+   *    value[i + 1] = Y component [0-1]  <br>
+   *    value[i + 2] = Z component [0-1]  <br>
+   *    value[i + 3] = Angle of rotation [-PI - PI] (nominally).
+   * @exception ArrayIndexOutOfBoundsException The provided array was too small
+   */
+  public abstract void getValue(float[] vec);
+
+  /**
+   * Get a particular rotation in the given eventOut array.
+   *  <p>
+   * If the index is out of the bounds of the current array of data values an
+   * ArrayIndexOutOfBoundsException will be generated.
+   *
+   * @param index The position to get the rotation value
+   * @return The array of rotation values where <br>
+   *    value[0] = X component [0-1]  <br>
+   *    value[1] = Y component [0-1]  <br>
+   *    value[2] = Z component [0-1]  <br>
+   *    value[3] = Angle of rotation [-PI - PI] (nominally).
+   *
+   * @exception ArrayIndexOutOfBoundsException The index was outside the current data
+   *    array bounds.
+   */
+  public abstract float[] get1Value(int index);
+
+  /**
+   * Get the value of a particular rotation value in the event out array.
+   *
+   * @param index The position to get the vector value from.
+   * @param vec The array to place the value in where.
+   *    vec[0] = X component [0-1]  <br>
+   *    vec[1] = Y component [0-1]  <br>
+   *    vec[2] = Z component [0-1]  <br>
+   *    vec[3] = Angle of rotation [-PI - PI] (nominally).
+   * @exception ArrayIndexOutOfBoundsException The provided array was too small or
+   *     the index was outside the current data array bounds.
+   */
+  public abstract void get1Value(int index, float[] vec);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventOutMFString.java b/src/java/vrml/eai/field/EventOutMFString.java
index 31b19d87c2fd0518740100d9a8c2dce0501e51ab..816627552d88a2b34d3cbaa178fe09c4e1e053aa 100644
--- a/src/java/vrml/eai/field/EventOutMFString.java
+++ b/src/java/vrml/eai/field/EventOutMFString.java
@@ -1,84 +1,84 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventOut class for MFString.
- *  <p>
- * Strings are represented using standard java.lang.String representations.
- * The implementation of this class will provide any necessary conversions
- * to the UTF8 format required for VRML support.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventOutMFString extends EventOutMField
-{
-  /**
-   * Construct an instance of this class. The superclass constructor is called
-   * with the type MFString
-   */
-  protected EventOutMFString()
-  {
-    super(MFString);
-  }
-
-  /**
-   * Get the value of the array of strings. Individual elements in the string
-   * array may be null depending on the implementation of the browser and
-   * whether it maintains null references
-   *
-   * @return The array of strings.
-   *
-   * @see EventInMFString#setValue
-   */
-  public abstract String[] getValue();
-
-  /**
-   * Write the value of the array of the strings to the given array. Individual
-   * elements in the string array may be null depending on the implementation
-   * of the browser and whether it maintains null references.
-   *
-   * @param value The string array to be filled in
-   * @exception ArrayIndexOutOfBoundsException The provided array was too small
-   */
-  public abstract void getValue(String[] value);
-
-  /**
-   * Get a particular string value in the given eventOut array.
-   *  <p>
-   * If the index is out of the bounds of the current array of data values an
-   * ArrayIndexOutOfBoundsException will be generated. If the array reference
-   * was null when set, an empty string will be returned to the caller.
-   *
-   * @param index The position to get the string value from
-   * @return The string value
-   *
-   * @exception ArrayIndexOutOfBoundsException The index value was out of bounds of
-   *     the current array.
-   *
-   * @see EventInMFString#set1Value
-   */
-  public abstract String get1Value(int index);
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventOut class for MFString.
+ *  <p>
+ * Strings are represented using standard java.lang.String representations.
+ * The implementation of this class will provide any necessary conversions
+ * to the UTF8 format required for VRML support.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventOutMFString extends EventOutMField
+{
+  /**
+   * Construct an instance of this class. The superclass constructor is called
+   * with the type MFString
+   */
+  protected EventOutMFString()
+  {
+    super(MFString);
+  }
+
+  /**
+   * Get the value of the array of strings. Individual elements in the string
+   * array may be null depending on the implementation of the browser and
+   * whether it maintains null references
+   *
+   * @return The array of strings.
+   *
+   * @see EventInMFString#setValue
+   */
+  public abstract String[] getValue();
+
+  /**
+   * Write the value of the array of the strings to the given array. Individual
+   * elements in the string array may be null depending on the implementation
+   * of the browser and whether it maintains null references.
+   *
+   * @param value The string array to be filled in
+   * @exception ArrayIndexOutOfBoundsException The provided array was too small
+   */
+  public abstract void getValue(String[] value);
+
+  /**
+   * Get a particular string value in the given eventOut array.
+   *  <p>
+   * If the index is out of the bounds of the current array of data values an
+   * ArrayIndexOutOfBoundsException will be generated. If the array reference
+   * was null when set, an empty string will be returned to the caller.
+   *
+   * @param index The position to get the string value from
+   * @return The string value
+   *
+   * @exception ArrayIndexOutOfBoundsException The index value was out of bounds of
+   *     the current array.
+   *
+   * @see EventInMFString#set1Value
+   */
+  public abstract String get1Value(int index);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventOutMFTime.java b/src/java/vrml/eai/field/EventOutMFTime.java
index e83eec14551d72637db67675f7fc583682301af3..ba1ffdc873da0168b31f7632bcaf2405e7333384 100644
--- a/src/java/vrml/eai/field/EventOutMFTime.java
+++ b/src/java/vrml/eai/field/EventOutMFTime.java
@@ -1,86 +1,86 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventIn class for MFTime.
- *  <p>
- * Time values are represented as per the VRML IS specification Section
- * 4.11 Time. That is, time is set as VRML "Time" - the number of seconds since
- * Jan 1, 1970 GMT, rather than a Java time which is a long, the number
- * of milliseconds since Jan 1, 1970 GMT. To convert between the two simply
- * divide java time by 1000 and cast to a double.
- *  <p>
- * Note that in setting time values from an external application, the idea of
- * the time that java represents and the time that the VRML world currently
- * has set may well be different. It is best to source the current "time" from
- * a node or eventOut in the VRML world rather than relying exclusively on
- * the value returned from <code>System.currentTimeMillies</code>. This is
- * especially important to note if you are dealing with high speed, narrow
- * interval work such as controlling animation.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventOutMFTime extends EventOutMField
-{
-  /**
-   * Construct an instance of this class. The superclass is called with the
-   * type MFTime.
-   */
-  protected EventOutMFTime()
-  {
-    super(MFTime);
-  }
-
-  /**
-   * Get the value of the array of times.
-   *
-   * @return The array of time values
-   */
-  public abstract double[] getValue();
-
-
-  /**
-   * Write the value of the event out to the given array.
-   *
-   * @param vec The array to be filled in where
-   * @exception ArrayIndexOutOfBoundsException The provided array was too small
-   */
-  public abstract void getValue(double[] vec);
-
-  /**
-   * Get a particular time value in the given eventOut array.
-   *  <p>
-   * If the index is out of the bounds of the current array of data values an
-   * ArrayIndexOutOfBoundsException will be generated.
-   *
-   * @param index The position to get the time value
-   * @return The time value.
-   *
-   * @exception ArrayIndexOutOfBoundsException The index was outside of the bounds of
-   * the current array.
-   */
-  public abstract double get1Value(int index);
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventIn class for MFTime.
+ *  <p>
+ * Time values are represented as per the VRML IS specification Section
+ * 4.11 Time. That is, time is set as VRML "Time" - the number of seconds since
+ * Jan 1, 1970 GMT, rather than a Java time which is a long, the number
+ * of milliseconds since Jan 1, 1970 GMT. To convert between the two simply
+ * divide java time by 1000 and cast to a double.
+ *  <p>
+ * Note that in setting time values from an external application, the idea of
+ * the time that java represents and the time that the VRML world currently
+ * has set may well be different. It is best to source the current "time" from
+ * a node or eventOut in the VRML world rather than relying exclusively on
+ * the value returned from <code>System.currentTimeMillies</code>. This is
+ * especially important to note if you are dealing with high speed, narrow
+ * interval work such as controlling animation.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventOutMFTime extends EventOutMField
+{
+  /**
+   * Construct an instance of this class. The superclass is called with the
+   * type MFTime.
+   */
+  protected EventOutMFTime()
+  {
+    super(MFTime);
+  }
+
+  /**
+   * Get the value of the array of times.
+   *
+   * @return The array of time values
+   */
+  public abstract double[] getValue();
+
+
+  /**
+   * Write the value of the event out to the given array.
+   *
+   * @param vec The array to be filled in where
+   * @exception ArrayIndexOutOfBoundsException The provided array was too small
+   */
+  public abstract void getValue(double[] vec);
+
+  /**
+   * Get a particular time value in the given eventOut array.
+   *  <p>
+   * If the index is out of the bounds of the current array of data values an
+   * ArrayIndexOutOfBoundsException will be generated.
+   *
+   * @param index The position to get the time value
+   * @return The time value.
+   *
+   * @exception ArrayIndexOutOfBoundsException The index was outside of the bounds of
+   * the current array.
+   */
+  public abstract double get1Value(int index);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventOutMFVec2f.java b/src/java/vrml/eai/field/EventOutMFVec2f.java
index cf6180cc051a66609e27d9a8f3fc9da724ff675e..2d08f9aba9408c679b994ffd5b1a9040f3fe18c0 100644
--- a/src/java/vrml/eai/field/EventOutMFVec2f.java
+++ b/src/java/vrml/eai/field/EventOutMFVec2f.java
@@ -1,101 +1,101 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventIn class for MFVec2f.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventOutMFVec2f extends EventOutMField
-{
-  /**
-   * Construct an instance of this class. The superclass is called with the
-   * type MFVec2f
-   */
-  protected EventOutMFVec2f()
-  {
-    super(MFVec2f);
-  }
-
-  /**
-   * Get the value of the array of 2D vectors. Output is an array of floats
-   *  <p>
-   * @return The array of vec2f values where <br>
-   *    value[i][0] = X <br>
-   *    value[i][1] = Y
-   */
-  public abstract float[][] getValue();
-
-
-  /**
-   * Write the value of the event out to the given array.
-   *
-   * @param vec The array to be filled in where <br>
-   *    vec[i][0] = X <br>
-   *    vec[i][1] = Y
-   * @exception ArrayIndexOutOfBoundsException The provided array was too small
-   */
-  public abstract void getValue(float[][] vec);
-
-  /**
-   * Get the values of the event out flattened into a single 1D array. The
-   * array must be at least 3 times the size of the array.
-   *
-   * @param vec The array to be filled in where the
-   *   vec[i + 0] = X <br>
-   *   vec[i + 1] = Y
-   * @exception ArrayIndexOutOfBoundsException The provided array was too small
-   */
-  public abstract void getValue(float[] vec);
-
-  /**
-   * Get a particular vector value in the given eventOut array.
-   *  <p>
-   * If the index is out of the bounds of the current array of data values an
-   * ArrayIndexOutOfBoundsException will be generated.
-   *
-   * @param index The position to get the vector value from
-   * @return The array of vector values where <br>
-   *    value[0] = X <br>
-   *    value[1] = Y
-   *
-   * @exception ArrayIndexOutOfBoundsException The index was outside the current data
-   *    array bounds.
-   */
-  public abstract float[] get1Value(int index);
-
-  /**
-   * Get the value of a particular vector value in the event out array.
-   *
-   * @param index The position to get the vector value from.
-   * @param vec The array to place the value in where.
-   *    vec[0] = X <br>
-   *    vec[1] = Y
-   * @exception ArrayIndexOutOfBoundsException The provided array was too small or
-   *     the index was outside the current data array bounds.
-   */
-  public abstract void get1Value(int index, float[] vec);
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventIn class for MFVec2f.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventOutMFVec2f extends EventOutMField
+{
+  /**
+   * Construct an instance of this class. The superclass is called with the
+   * type MFVec2f
+   */
+  protected EventOutMFVec2f()
+  {
+    super(MFVec2f);
+  }
+
+  /**
+   * Get the value of the array of 2D vectors. Output is an array of floats
+   *  <p>
+   * @return The array of vec2f values where <br>
+   *    value[i][0] = X <br>
+   *    value[i][1] = Y
+   */
+  public abstract float[][] getValue();
+
+
+  /**
+   * Write the value of the event out to the given array.
+   *
+   * @param vec The array to be filled in where <br>
+   *    vec[i][0] = X <br>
+   *    vec[i][1] = Y
+   * @exception ArrayIndexOutOfBoundsException The provided array was too small
+   */
+  public abstract void getValue(float[][] vec);
+
+  /**
+   * Get the values of the event out flattened into a single 1D array. The
+   * array must be at least 3 times the size of the array.
+   *
+   * @param vec The array to be filled in where the
+   *   vec[i + 0] = X <br>
+   *   vec[i + 1] = Y
+   * @exception ArrayIndexOutOfBoundsException The provided array was too small
+   */
+  public abstract void getValue(float[] vec);
+
+  /**
+   * Get a particular vector value in the given eventOut array.
+   *  <p>
+   * If the index is out of the bounds of the current array of data values an
+   * ArrayIndexOutOfBoundsException will be generated.
+   *
+   * @param index The position to get the vector value from
+   * @return The array of vector values where <br>
+   *    value[0] = X <br>
+   *    value[1] = Y
+   *
+   * @exception ArrayIndexOutOfBoundsException The index was outside the current data
+   *    array bounds.
+   */
+  public abstract float[] get1Value(int index);
+
+  /**
+   * Get the value of a particular vector value in the event out array.
+   *
+   * @param index The position to get the vector value from.
+   * @param vec The array to place the value in where.
+   *    vec[0] = X <br>
+   *    vec[1] = Y
+   * @exception ArrayIndexOutOfBoundsException The provided array was too small or
+   *     the index was outside the current data array bounds.
+   */
+  public abstract void get1Value(int index, float[] vec);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventOutMFVec3f.java b/src/java/vrml/eai/field/EventOutMFVec3f.java
index 3c98a78c0420d433c53031b20f811b9a40376e0e..fdfd8c20af86c3b5fc45ac5bb1cc28585d51a67e 100644
--- a/src/java/vrml/eai/field/EventOutMFVec3f.java
+++ b/src/java/vrml/eai/field/EventOutMFVec3f.java
@@ -1,108 +1,108 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventIn class for MFVec3f.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventOutMFVec3f extends EventOutMField
-{
-  /**
-   * Construct an instance of this class. The superclass is called with the
-   * type MFVec3f
-   */
-  protected EventOutMFVec3f()
-  {
-    super(MFVec3f);
-  }
-
-  /**
-   * Get the value of the array of 2D vectors. Output is an array of floats
-   *  <p>
-   * @return The array of vec2f values where <br>
-   *    value[i][0] = X <br>
-   *    value[i][1] = Y <br>
-   *    value[i][2] = Z
-   */
-  public abstract float[][] getValue();
-
-  /**
-   * Write the value of the event out to the given array.
-   *
-   * @param vec The array to be filled in where <br>
-   *    vec[i][0] = X <br>
-   *    vec[i][1] = Y <br>
-   *    vec[i][2] = Z
-   * @exception ArrayIndexOutOfBoundsException The provided array was too small
-   */
-  public abstract void getValue(float[][] vec);
-
-  /**
-   * Get the values of the event out flattened into a single 1D array. The
-   * array must be at least 3 times the size of the array.
-   *
-   * @param vec The array to be filled in where the
-   *   vec[i + 0] = X <br>
-   *   vec[i + 1] = Y <br>
-   *   vec[i + 2] = Z <br>
-   * @exception ArrayIndexOutOfBoundsException The provided array was too small
-   */
-  public abstract void getValue(float[] vec);
-
-  /**
-   * Get a particular vector value in the given eventOut array.
-   *  <p>
-   * If the index is out of the bounds of the current array of data values an
-   * ArrayIndexOutOfBoundsException will be generated.
-   *
-   * @param index The position to get the vector value from
-   * @return The array of vector values where <br>
-   *    value[0] = X <br>
-   *    value[1] = Y <br>
-   *    value[2] = Z
-   *
-   * @exception ArrayIndexOutOfBoundsException The index was outside the current data
-   *    array bounds.
-   */
-  public abstract float[] get1Value(int index);
-
-  /**
-   * Get the value of a particular vector value in the event out array.
-   *
-   * @param index The position to get the vector value from.
-   * @param vec The array to place the value in where.
-   *    vec[0] = X <br>
-   *    vec[1] = Y <br>
-   *    vec[2] = Z
-   * @exception ArrayIndexOutOfBoundsException The provided array was too small or
-   *     the index was outside the current data array bounds.
-   */
-  public abstract void get1Value(int index, float[] vec);
-}
-
-
-
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventIn class for MFVec3f.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventOutMFVec3f extends EventOutMField
+{
+  /**
+   * Construct an instance of this class. The superclass is called with the
+   * type MFVec3f
+   */
+  protected EventOutMFVec3f()
+  {
+    super(MFVec3f);
+  }
+
+  /**
+   * Get the value of the array of 2D vectors. Output is an array of floats
+   *  <p>
+   * @return The array of vec2f values where <br>
+   *    value[i][0] = X <br>
+   *    value[i][1] = Y <br>
+   *    value[i][2] = Z
+   */
+  public abstract float[][] getValue();
+
+  /**
+   * Write the value of the event out to the given array.
+   *
+   * @param vec The array to be filled in where <br>
+   *    vec[i][0] = X <br>
+   *    vec[i][1] = Y <br>
+   *    vec[i][2] = Z
+   * @exception ArrayIndexOutOfBoundsException The provided array was too small
+   */
+  public abstract void getValue(float[][] vec);
+
+  /**
+   * Get the values of the event out flattened into a single 1D array. The
+   * array must be at least 3 times the size of the array.
+   *
+   * @param vec The array to be filled in where the
+   *   vec[i + 0] = X <br>
+   *   vec[i + 1] = Y <br>
+   *   vec[i + 2] = Z <br>
+   * @exception ArrayIndexOutOfBoundsException The provided array was too small
+   */
+  public abstract void getValue(float[] vec);
+
+  /**
+   * Get a particular vector value in the given eventOut array.
+   *  <p>
+   * If the index is out of the bounds of the current array of data values an
+   * ArrayIndexOutOfBoundsException will be generated.
+   *
+   * @param index The position to get the vector value from
+   * @return The array of vector values where <br>
+   *    value[0] = X <br>
+   *    value[1] = Y <br>
+   *    value[2] = Z
+   *
+   * @exception ArrayIndexOutOfBoundsException The index was outside the current data
+   *    array bounds.
+   */
+  public abstract float[] get1Value(int index);
+
+  /**
+   * Get the value of a particular vector value in the event out array.
+   *
+   * @param index The position to get the vector value from.
+   * @param vec The array to place the value in where.
+   *    vec[0] = X <br>
+   *    vec[1] = Y <br>
+   *    vec[2] = Z
+   * @exception ArrayIndexOutOfBoundsException The provided array was too small or
+   *     the index was outside the current data array bounds.
+   */
+  public abstract void get1Value(int index, float[] vec);
+}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventOutMField.java b/src/java/vrml/eai/field/EventOutMField.java
index 11a31ad173f7fa17e2554b0ca822a8336a0659de..378602970c7864d1efb6d0c6757c762f28498002 100644
--- a/src/java/vrml/eai/field/EventOutMField.java
+++ b/src/java/vrml/eai/field/EventOutMField.java
@@ -1,60 +1,60 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventOut base class for MF field values.
- *  <p>
- * Class provides a size method that determines the number of items available
- * in this array of values. Normally used in conjunction with the get1Value()
- * method of the MF field classes so that exceptions are not generated.
- *  <p>
- * It is possible, although not recommended, that the size of the arrays
- * returned by the get methods may be larger than the actual amount of data
- * that is to be represented. Calling size() beforehand ensures that the
- * correct number of items in the array will be read.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventOutMField extends EventOut
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the type set to MFColor.
-   *
-   * @param type The type of this eventOut
-   */
-  protected EventOutMField(int type)
-  {
-    super(type);
-  }
-
-  /**
-   * Get the size of the underlying data array.
-   *
-   * @return The size of the array
-   */
-  public abstract int size();
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventOut base class for MF field values.
+ *  <p>
+ * Class provides a size method that determines the number of items available
+ * in this array of values. Normally used in conjunction with the get1Value()
+ * method of the MF field classes so that exceptions are not generated.
+ *  <p>
+ * It is possible, although not recommended, that the size of the arrays
+ * returned by the get methods may be larger than the actual amount of data
+ * that is to be represented. Calling size() beforehand ensures that the
+ * correct number of items in the array will be read.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventOutMField extends EventOut
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the type set to MFColor.
+   *
+   * @param type The type of this eventOut
+   */
+  protected EventOutMField(int type)
+  {
+    super(type);
+  }
+
+  /**
+   * Get the size of the underlying data array.
+   *
+   * @return The size of the array
+   */
+  public abstract int size();
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventOutSFBool.java b/src/java/vrml/eai/field/EventOutSFBool.java
index bfc8dff984ee2556b5a97a6bcbf24e0bb0576125..c586259d0c8be5cb3620dd566f4e8575352c0725 100644
--- a/src/java/vrml/eai/field/EventOutSFBool.java
+++ b/src/java/vrml/eai/field/EventOutSFBool.java
@@ -1,49 +1,49 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventOut class for SFBool.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventOutSFBool extends EventOut
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the field type set to SFBool.
-   */
-  protected EventOutSFBool()
-  {
-    super(SFBool);
-  }
-
-  /**
-   * Get the value in the given eventOut.
-   *  <p>
-   * @return The boolean value of the eventOut
-   */
-  public abstract boolean getValue();
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventOut class for SFBool.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventOutSFBool extends EventOut
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the field type set to SFBool.
+   */
+  protected EventOutSFBool()
+  {
+    super(SFBool);
+  }
+
+  /**
+   * Get the value in the given eventOut.
+   *  <p>
+   * @return The boolean value of the eventOut
+   */
+  public abstract boolean getValue();
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventOutSFColor.java b/src/java/vrml/eai/field/EventOutSFColor.java
index 87726b69c97808055ebced46326b12a33042e75e..feda1793d34a565079face20d72ceaf2da7e2fc7 100644
--- a/src/java/vrml/eai/field/EventOutSFColor.java
+++ b/src/java/vrml/eai/field/EventOutSFColor.java
@@ -1,68 +1,68 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventOut class for SFColor.
- *  <p>
- * Colour values are represented as floating point numbers between [0 - 1]
- * as per the VRML IS specification Section 4.4.5 Standard units and
- * coordinate system.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventOutSFColor extends EventOut
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the field type set to SFColor.
-   */
-  protected EventOutSFColor()
-  {
-    super(SFColor);
-  }
-
-  /**
-   * Get a the colour value in the given eventIn.  Colour values are
-   * in the range [0-1].
-   *
-   * @return The array of colour values where <br>
-   *    value[0] = Red component [0-1]  <br>
-   *    value[1] = Green component [0-1]  <br>
-   *    value[2] = Blue component [0-1]  <br>
-   */
-  public abstract float[] getValue();
-
-  /**
-   * Write the value of the colour to the given array.
-   *
-   * @param col The array of colour values to be filled in where <br>
-   *    value[0] = Red component [0-1]  <br>
-   *    value[1] = Green component [0-1]  <br>
-   *    value[2] = Blue component [0-1]  <br>
-   * @exception ArrayIndexOutOfBoundsException The provided array was too small
-   */
-  public abstract void getValue(float[] col);
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventOut class for SFColor.
+ *  <p>
+ * Colour values are represented as floating point numbers between [0 - 1]
+ * as per the VRML IS specification Section 4.4.5 Standard units and
+ * coordinate system.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventOutSFColor extends EventOut
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the field type set to SFColor.
+   */
+  protected EventOutSFColor()
+  {
+    super(SFColor);
+  }
+
+  /**
+   * Get a the colour value in the given eventIn.  Colour values are
+   * in the range [0-1].
+   *
+   * @return The array of colour values where <br>
+   *    value[0] = Red component [0-1]  <br>
+   *    value[1] = Green component [0-1]  <br>
+   *    value[2] = Blue component [0-1]  <br>
+   */
+  public abstract float[] getValue();
+
+  /**
+   * Write the value of the colour to the given array.
+   *
+   * @param col The array of colour values to be filled in where <br>
+   *    value[0] = Red component [0-1]  <br>
+   *    value[1] = Green component [0-1]  <br>
+   *    value[2] = Blue component [0-1]  <br>
+   * @exception ArrayIndexOutOfBoundsException The provided array was too small
+   */
+  public abstract void getValue(float[] col);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventOutSFImage.java b/src/java/vrml/eai/field/EventOutSFImage.java
index b2f7c3a1615151461e88b5488442306462e8a0cc..2392cd6024eac715140910bbdf2323ea28106cbb 100644
--- a/src/java/vrml/eai/field/EventOutSFImage.java
+++ b/src/java/vrml/eai/field/EventOutSFImage.java
@@ -1,136 +1,136 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventOut class for SFImage.
- *  <p>
- * Images are represented as arrays of integers as per the VRML IS
- * specification Section 5.5 SFImage. Pixel values are between 0 and 256 and
- * represented as integers to maintain consistency with java's ImageConsumer
- * interface and PixelGrabber class.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventOutSFImage extends EventOut
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the field type set to SFImage.
-   */
-  protected EventOutSFImage()
-  {
-    super(SFImage);
-  }
-
-  /**
-   * Get the width of the image.
-   *
-   * @return The width of the image in pixels
-   */
-  public abstract int getWidth();
-
-  /**
-   * Get the height of the image.
-   *
-   * @return The height of the image in pixels
-   */
-  public abstract int getHeight();
-
-  /**
-   * Get the number of colour components in the image. The value will
-   * always be between 1 and 4 indicating the number of components of
-   * the colour specification to be read from the image pixel data.
-   *
-   * @return The number of components
-   */
-  public abstract int getComponents();
-
-  /**
-   * Get the image pixel value in the given eventOut.
-   *  <p>
-   * The number of items in the pixels array will be
-   * <code>width * height</code>. If there are less items than this an
-   * ArrayIndexOutOfBoundsException will be generated. The integer values
-   * are represented according to the number of components.
-   *  <p>
-   *  <b>1 Component Images </b> <br>
-   * The integer has the intensity value stored in the lowest byte and can be
-   * obtained:
-   *  <pre>
-   *    intensity = pixel[i] &amp;0xFF;
-   *  </pre>
-   *  <p>
-   *  <b>2 Component Images </b> <br>
-   * The integer has the intensity value stored in the lowest byte and the
-   * transparency in the top byte:
-   *  <pre>
-   *    intensity = pixel[i] &amp;0xFF;
-   *    alpha = (pixel[i] &gt;&gt; 24) &amp;0xFF00;
-   *  </pre>
-   * <i>Note</i> that this is different to the VRML representation of the image
-   * which would store the values in the text file as
-   * <code>alpha = pixel[i] &gt;&gt; 8) &amp;0xFF</code>. The reason for the difference
-   * is to maintain as much compatibility with the java image model as
-   * possible. Java does not contain a separate intensity only image model,
-   * instead it sets all three colour components to the same value. This way,
-   * the user of SFImages can take a full colour image and turn it to black + white by
-   * just setting each of the bytes to the same value as the lowest byte.
-   *  <p>
-   *  <b>3 Component Images </b> <br>
-   * The three colour components are stored in the integer array as follows:
-   *  <pre>
-   *    red   = (pixel[i] &gt;&gt; 16) &amp;0xFF;
-   *    green = (pixel[i] &gt;&gt;  8) &amp;0xFF;
-   *    blue  = (pixel[i]      ) &amp;0xFF;
-   *  </pre>
-   *  <p>
-   *  <b>4 Component Images </b> <br>
-   * The integer has the value stored in the array as follows:
-   *  <pre>
-   *    alpha = (pixel &gt;&gt; 24) &amp;0xff;
-   *    red   = (pixel &gt;&gt; 16) &amp;0xff;
-   *    green = (pixel &gt;&gt;  8) &amp;0xff;
-   *    blue  = (pixel      ) &amp;0xff;
-   *  </pre>
-   *  <p>
-   * The width and height values must be greater than or equal to zero. The
-   * number of components is between 1 and 4. Any value outside of these
-   * bounds will generate an IllegalArgumentException.
-   *
-   * @return The array of pixel values as specified above.
-   */
-  public abstract int[] getPixels();
-
-  /**
-   * Write the pixel values to the given array. Returns values in the same
-   * format as that used by the no argument version of this method. The length
-   * of the array must be at least width * height elements.
-   *
-   * @param pixels The array to write pixels to.
-   * @exception ArrayIndexOutOfBoundsException The provided array was too small
-   */
-  public abstract void getPixels(int[] pixels);
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventOut class for SFImage.
+ *  <p>
+ * Images are represented as arrays of integers as per the VRML IS
+ * specification Section 5.5 SFImage. Pixel values are between 0 and 256 and
+ * represented as integers to maintain consistency with java's ImageConsumer
+ * interface and PixelGrabber class.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventOutSFImage extends EventOut
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the field type set to SFImage.
+   */
+  protected EventOutSFImage()
+  {
+    super(SFImage);
+  }
+
+  /**
+   * Get the width of the image.
+   *
+   * @return The width of the image in pixels
+   */
+  public abstract int getWidth();
+
+  /**
+   * Get the height of the image.
+   *
+   * @return The height of the image in pixels
+   */
+  public abstract int getHeight();
+
+  /**
+   * Get the number of colour components in the image. The value will
+   * always be between 1 and 4 indicating the number of components of
+   * the colour specification to be read from the image pixel data.
+   *
+   * @return The number of components
+   */
+  public abstract int getComponents();
+
+  /**
+   * Get the image pixel value in the given eventOut.
+   *  <p>
+   * The number of items in the pixels array will be
+   * <code>width * height</code>. If there are less items than this an
+   * ArrayIndexOutOfBoundsException will be generated. The integer values
+   * are represented according to the number of components.
+   *  <p>
+   *  <b>1 Component Images </b> <br>
+   * The integer has the intensity value stored in the lowest byte and can be
+   * obtained:
+   *  <pre>
+   *    intensity = pixel[i] &amp;0xFF;
+   *  </pre>
+   *  <p>
+   *  <b>2 Component Images </b> <br>
+   * The integer has the intensity value stored in the lowest byte and the
+   * transparency in the top byte:
+   *  <pre>
+   *    intensity = pixel[i] &amp;0xFF;
+   *    alpha = (pixel[i] &gt;&gt; 24) &amp;0xFF00;
+   *  </pre>
+   * <i>Note</i> that this is different to the VRML representation of the image
+   * which would store the values in the text file as
+   * <code>alpha = pixel[i] &gt;&gt; 8) &amp;0xFF</code>. The reason for the difference
+   * is to maintain as much compatibility with the java image model as
+   * possible. Java does not contain a separate intensity only image model,
+   * instead it sets all three colour components to the same value. This way,
+   * the user of SFImages can take a full colour image and turn it to black + white by
+   * just setting each of the bytes to the same value as the lowest byte.
+   *  <p>
+   *  <b>3 Component Images </b> <br>
+   * The three colour components are stored in the integer array as follows:
+   *  <pre>
+   *    red   = (pixel[i] &gt;&gt; 16) &amp;0xFF;
+   *    green = (pixel[i] &gt;&gt;  8) &amp;0xFF;
+   *    blue  = (pixel[i]      ) &amp;0xFF;
+   *  </pre>
+   *  <p>
+   *  <b>4 Component Images </b> <br>
+   * The integer has the value stored in the array as follows:
+   *  <pre>
+   *    alpha = (pixel &gt;&gt; 24) &amp;0xff;
+   *    red   = (pixel &gt;&gt; 16) &amp;0xff;
+   *    green = (pixel &gt;&gt;  8) &amp;0xff;
+   *    blue  = (pixel      ) &amp;0xff;
+   *  </pre>
+   *  <p>
+   * The width and height values must be greater than or equal to zero. The
+   * number of components is between 1 and 4. Any value outside of these
+   * bounds will generate an IllegalArgumentException.
+   *
+   * @return The array of pixel values as specified above.
+   */
+  public abstract int[] getPixels();
+
+  /**
+   * Write the pixel values to the given array. Returns values in the same
+   * format as that used by the no argument version of this method. The length
+   * of the array must be at least width * height elements.
+   *
+   * @param pixels The array to write pixels to.
+   * @exception ArrayIndexOutOfBoundsException The provided array was too small
+   */
+  public abstract void getPixels(int[] pixels);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventOutSFInt32.java b/src/java/vrml/eai/field/EventOutSFInt32.java
index ff98d9878f7dba5b3ca1ca55a8da2d803876ec93..321db178cfb65c9db9c4f37347059d37f423eef6 100644
--- a/src/java/vrml/eai/field/EventOutSFInt32.java
+++ b/src/java/vrml/eai/field/EventOutSFInt32.java
@@ -1,51 +1,51 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventOut class for SFInt32.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventOutSFInt32 extends EventOut
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the field type set to SFInt32.
-   */
-  protected EventOutSFInt32()
-  {
-    super(SFInt32);
-  }
-
-  /**
-   * Get the value in the given eventOut.
-   *
-   * @return The value of the eventOut
-   */
-  public abstract int getValue();
-}
-
-
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventOut class for SFInt32.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventOutSFInt32 extends EventOut
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the field type set to SFInt32.
+   */
+  protected EventOutSFInt32()
+  {
+    super(SFInt32);
+  }
+
+  /**
+   * Get the value in the given eventOut.
+   *
+   * @return The value of the eventOut
+   */
+  public abstract int getValue();
+}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventOutSFNode.java b/src/java/vrml/eai/field/EventOutSFNode.java
index 545214cd4906bda734326bebdab43f5135a66563..5dbd36137801a8644b91a6ee7c1616a38c19a89a 100644
--- a/src/java/vrml/eai/field/EventOutSFNode.java
+++ b/src/java/vrml/eai/field/EventOutSFNode.java
@@ -1,57 +1,57 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-import vrml.eai.Node;
-
-/**
- * VRML eventIn class for SFNode.
- *  <p>
- * Get the value of a node. The java <code>null</code> reference is treated to
- * be equivalent to the VRML <code>NULL</code> field values. If the node field
- * contains a NULL reference then reading this eventOut will result in a
- * java null being returned.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventOutSFNode extends EventOut
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the field type set to SFNode.
-   */
-  protected EventOutSFNode()
-  {
-    super(SFNode);
-  }
-
-  /**
-   * Get the node value in the given eventOut. If no node reference is set then
-   * null is returned to the user.
-   *  <p>
-   * @return The new node reference set.
-   */
-  public abstract Node getValue();
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+import vrml.eai.Node;
+
+/**
+ * VRML eventIn class for SFNode.
+ *  <p>
+ * Get the value of a node. The java <code>null</code> reference is treated to
+ * be equivalent to the VRML <code>NULL</code> field values. If the node field
+ * contains a NULL reference then reading this eventOut will result in a
+ * java null being returned.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventOutSFNode extends EventOut
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the field type set to SFNode.
+   */
+  protected EventOutSFNode()
+  {
+    super(SFNode);
+  }
+
+  /**
+   * Get the node value in the given eventOut. If no node reference is set then
+   * null is returned to the user.
+   *  <p>
+   * @return The new node reference set.
+   */
+  public abstract Node getValue();
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventOutSFRotation.java b/src/java/vrml/eai/field/EventOutSFRotation.java
index 5443f89d2009891c76de6034e554442f91ff5e2b..14dee5d4eb69f5a0da2787cf91d064a9df27013e 100644
--- a/src/java/vrml/eai/field/EventOutSFRotation.java
+++ b/src/java/vrml/eai/field/EventOutSFRotation.java
@@ -1,68 +1,68 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventOut class for SFRotation.
- *  <p>
- * Rotation values are specified according to the VRML IS Specification
- * Section 5.8 SFRotation and MFRotation.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventOutSFRotation extends EventOut
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the field type set to SFRotation
-   */
-  protected EventOutSFRotation()
-  {
-    super(SFRotation);
-  }
-
-  /**
-   * Get the rotation value in the given eventOut.
-   *
-   * @return The array of rotation values where <br>
-   *    value[0] = X component [0-1]  <br>
-   *    value[1] = Y component [0-1]  <br>
-   *    value[2] = Z component [0-1]  <br>
-   *    value[3] = Angle of rotation [-PI - PI] (nominally).
-   */
-  public abstract float[] getValue();
-
-  /**
-   * Write the rotation value to the given eventOut
-   *
-   * @param vec The array of vector values to be filled in where <br>
-   *    value[0] = X component [0-1]  <br>
-   *    value[1] = Y component [0-1]  <br>
-   *    value[2] = Z component [0-1]  <br>
-   *    value[3] = Angle of rotation [-PI - PI] (nominally).
-   * @exception ArrayIndexOutOfBoundsException The provided array was too small
-   */
-  public abstract void getValue(float[] vec);
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventOut class for SFRotation.
+ *  <p>
+ * Rotation values are specified according to the VRML IS Specification
+ * Section 5.8 SFRotation and MFRotation.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventOutSFRotation extends EventOut
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the field type set to SFRotation
+   */
+  protected EventOutSFRotation()
+  {
+    super(SFRotation);
+  }
+
+  /**
+   * Get the rotation value in the given eventOut.
+   *
+   * @return The array of rotation values where <br>
+   *    value[0] = X component [0-1]  <br>
+   *    value[1] = Y component [0-1]  <br>
+   *    value[2] = Z component [0-1]  <br>
+   *    value[3] = Angle of rotation [-PI - PI] (nominally).
+   */
+  public abstract float[] getValue();
+
+  /**
+   * Write the rotation value to the given eventOut
+   *
+   * @param vec The array of vector values to be filled in where <br>
+   *    value[0] = X component [0-1]  <br>
+   *    value[1] = Y component [0-1]  <br>
+   *    value[2] = Z component [0-1]  <br>
+   *    value[3] = Angle of rotation [-PI - PI] (nominally).
+   * @exception ArrayIndexOutOfBoundsException The provided array was too small
+   */
+  public abstract void getValue(float[] vec);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventOutSFString.java b/src/java/vrml/eai/field/EventOutSFString.java
index 1a8c2792d73b62488edc0bff9a427cd3430db147..0fb0dea79d2e397da7ff70e646aff8f65675db99 100644
--- a/src/java/vrml/eai/field/EventOutSFString.java
+++ b/src/java/vrml/eai/field/EventOutSFString.java
@@ -1,53 +1,53 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventOut class for SFString.
- *  <p>
- * Strings are represented using standard java.lang.String representations.
- * The implementation of this class will provide any necessary conversions
- * to the UTF8 format required for VRML support.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventOutSFString extends EventOut
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the field type set to SFString.
-   */
-  protected EventOutSFString()
-  {
-    super(SFString);
-  }
-
-  /**
-   * Get the string value in the given eventOut.
-   *
-   * @return The current string value.
-   */
-  public abstract String getValue();
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventOut class for SFString.
+ *  <p>
+ * Strings are represented using standard java.lang.String representations.
+ * The implementation of this class will provide any necessary conversions
+ * to the UTF8 format required for VRML support.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventOutSFString extends EventOut
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the field type set to SFString.
+   */
+  protected EventOutSFString()
+  {
+    super(SFString);
+  }
+
+  /**
+   * Get the string value in the given eventOut.
+   *
+   * @return The current string value.
+   */
+  public abstract String getValue();
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventOutSFTime.java b/src/java/vrml/eai/field/EventOutSFTime.java
index dcffce522e01f23d6aee0efa0170fdaffdff4f36..d80785d80dcd8fc7d74305f8c2e37be6d5841f33 100644
--- a/src/java/vrml/eai/field/EventOutSFTime.java
+++ b/src/java/vrml/eai/field/EventOutSFTime.java
@@ -1,65 +1,65 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventOut class for SFTime.
- *  <p>
- * Time values are represented as per the VRML IS specification Section
- * 4.11 Time. That is, time is set as VRML "Time" - the number of seconds since
- * Jan 1, 1970 GMT, rather than a Java time which is a long, the number
- * of milliseconds since Jan 1, 1970 GMT. To convert between the two simply
- * divide java time by 1000 and cast to a double.
- *  <p>
- * Note that in setting time values from an external application, the idea of
- * the time that java represents and the time that the VRML world currently
- * has set may well be different. It is best to source the current "time" from
- * a node or eventOut in the VRML world rather than relying exclusively on
- * the value returned from <code>System.currentTimeMillies</code>. This is
- * especially important to note if you are dealing with high speed, narrow
- * interval work such as controlling animation.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventOutSFTime extends EventOut
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the field type set to SFTime.
-   */
-  protected EventOutSFTime()
-  {
-    super(SFTime);
-  }
-
-  /**
-   * Get the time value in the given eventOut. Time can be any value either
-   * positive or negative but always absolute in value. As per the VRML
-   * time specification, all time values are absolute.
-   *
-   * @return The current time of this eventOut.
-   */
-  public abstract double getValue();
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventOut class for SFTime.
+ *  <p>
+ * Time values are represented as per the VRML IS specification Section
+ * 4.11 Time. That is, time is set as VRML "Time" - the number of seconds since
+ * Jan 1, 1970 GMT, rather than a Java time which is a long, the number
+ * of milliseconds since Jan 1, 1970 GMT. To convert between the two simply
+ * divide java time by 1000 and cast to a double.
+ *  <p>
+ * Note that in setting time values from an external application, the idea of
+ * the time that java represents and the time that the VRML world currently
+ * has set may well be different. It is best to source the current "time" from
+ * a node or eventOut in the VRML world rather than relying exclusively on
+ * the value returned from <code>System.currentTimeMillies</code>. This is
+ * especially important to note if you are dealing with high speed, narrow
+ * interval work such as controlling animation.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventOutSFTime extends EventOut
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the field type set to SFTime.
+   */
+  protected EventOutSFTime()
+  {
+    super(SFTime);
+  }
+
+  /**
+   * Get the time value in the given eventOut. Time can be any value either
+   * positive or negative but always absolute in value. As per the VRML
+   * time specification, all time values are absolute.
+   *
+   * @return The current time of this eventOut.
+   */
+  public abstract double getValue();
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventOutSFVec2f.java b/src/java/vrml/eai/field/EventOutSFVec2f.java
index c8f1c25f332a2a94fbe10a4cd79c531b2e853215..50c6e906b6938c727685c531c5913b0f578e7d36 100644
--- a/src/java/vrml/eai/field/EventOutSFVec2f.java
+++ b/src/java/vrml/eai/field/EventOutSFVec2f.java
@@ -1,61 +1,61 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventOut class for SFVec2f.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventOutSFVec2f extends EventOut
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the field type set to SFVec2f.
-   */
-  protected EventOutSFVec2f()
-  {
-    super(SFVec2f);
-  }
-
-  /**
-   * Get the vector value in the given eventOut.
-   *
-   * @return The array of vector components where <br>
-   *    value[0] = X <br>
-   *    value[1] = Y <br>
-   */
-  public abstract float[] getValue();
-
-  /**
-   * Write the vector value to the given eventOut
-   *
-   * @param vec The array of vector values to be filled in where <br>
-   *    vec[0] = X <br>
-   *    vec[1] = Y
-   * @exception ArrayIndexOutOfBoundsException The provided array was too small
-   */
-  public abstract void getValue(float[] vec);
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventOut class for SFVec2f.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventOutSFVec2f extends EventOut
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the field type set to SFVec2f.
+   */
+  protected EventOutSFVec2f()
+  {
+    super(SFVec2f);
+  }
+
+  /**
+   * Get the vector value in the given eventOut.
+   *
+   * @return The array of vector components where <br>
+   *    value[0] = X <br>
+   *    value[1] = Y <br>
+   */
+  public abstract float[] getValue();
+
+  /**
+   * Write the vector value to the given eventOut
+   *
+   * @param vec The array of vector values to be filled in where <br>
+   *    vec[0] = X <br>
+   *    vec[1] = Y
+   * @exception ArrayIndexOutOfBoundsException The provided array was too small
+   */
+  public abstract void getValue(float[] vec);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/EventOutSFVec3f.java b/src/java/vrml/eai/field/EventOutSFVec3f.java
index 71def5afb7c8b4500e9dd32a01c88e73d74ed338..092fd98d51ad8983486c803d77e8bad5c2571cc5 100644
--- a/src/java/vrml/eai/field/EventOutSFVec3f.java
+++ b/src/java/vrml/eai/field/EventOutSFVec3f.java
@@ -1,63 +1,63 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * VRML eventOut class for SFVec3f.
- *
- * @version 1.0 30 April 1998
- */
-public abstract class EventOutSFVec3f extends EventOut
-{
-  /**
-   * Construct an instance of this class. Calls the superclass constructor
-   * with the field type set to SFVec3f.
-   */
-  protected EventOutSFVec3f()
-  {
-    super(SFVec3f);
-  }
-
-  /**
-   * Get the vector value in the given eventOut.
-   *
-   * @return The array of vector components where <br>
-   *    value[0] = X <br>
-   *    value[1] = Y <br>
-   *    value[2] = Z
-   */
-  public abstract float[] getValue();
-
-  /**
-   * Write the vector value to the given eventOut
-   *
-   * @param vec The array of vector values to be filled in where <br>
-   *    vec[0] = X <br>
-   *    vec[1] = Y <br>
-   *    vec[2] = Z
-   * @exception ArrayIndexOutOfBoundsException The provided array was too small
-   */
-  public abstract void getValue(float[] vec);
-}
-
-
-
-
-
-
-
-
-
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * VRML eventOut class for SFVec3f.
+ *
+ * @version 1.0 30 April 1998
+ */
+public abstract class EventOutSFVec3f extends EventOut
+{
+  /**
+   * Construct an instance of this class. Calls the superclass constructor
+   * with the field type set to SFVec3f.
+   */
+  protected EventOutSFVec3f()
+  {
+    super(SFVec3f);
+  }
+
+  /**
+   * Get the vector value in the given eventOut.
+   *
+   * @return The array of vector components where <br>
+   *    value[0] = X <br>
+   *    value[1] = Y <br>
+   *    value[2] = Z
+   */
+  public abstract float[] getValue();
+
+  /**
+   * Write the vector value to the given eventOut
+   *
+   * @param vec The array of vector values to be filled in where <br>
+   *    vec[0] = X <br>
+   *    vec[1] = Y <br>
+   *    vec[2] = Z
+   * @exception ArrayIndexOutOfBoundsException The provided array was too small
+   */
+  public abstract void getValue(float[] vec);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/vrml/eai/field/InvalidEventInException.java b/src/java/vrml/eai/field/InvalidEventInException.java
index 57e2bbb5084b522cb0ec0ffb3d258559f431315e..7d435f47eba00bf2c7b6b239201bf35b92a5dbbd 100644
--- a/src/java/vrml/eai/field/InvalidEventInException.java
+++ b/src/java/vrml/eai/field/InvalidEventInException.java
@@ -1,50 +1,50 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * The exception that is thrown when a reference to an eventIn is not valid.
- *  <p>
- * An eventIn may be invalid for a number of reasons:
- * <UL>
- * <LI>The user may have typed in the wrong name through a typo.
- * <LI>The name may not correspond to a field in that node at all.
- * <LI>The name given refers to a valid field but the field cannot be
- *     accessed as an eventIn.
- * </UL>
- *
- * @version 1.0 7th March 1998
- */
-public class InvalidEventInException extends InvalidFieldException
-{
-    /**
-     * Construct a basic instance of this exception with no error message
-     */
-    public InvalidEventInException()
-    {
-        super();
-    }
-
-    /**
-     * Constructs a new exception with a particular message
-     *
-     * @param msg The message to use
-     */
-    public InvalidEventInException(String msg)
-    {
-        super(msg);
-    }
-}
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * The exception that is thrown when a reference to an eventIn is not valid.
+ *  <p>
+ * An eventIn may be invalid for a number of reasons:
+ * <UL>
+ * <LI>The user may have typed in the wrong name through a typo.
+ * <LI>The name may not correspond to a field in that node at all.
+ * <LI>The name given refers to a valid field but the field cannot be
+ *     accessed as an eventIn.
+ * </UL>
+ *
+ * @version 1.0 7th March 1998
+ */
+public class InvalidEventInException extends InvalidFieldException
+{
+    /**
+     * Construct a basic instance of this exception with no error message
+     */
+    public InvalidEventInException()
+    {
+        super();
+    }
+
+    /**
+     * Constructs a new exception with a particular message
+     *
+     * @param msg The message to use
+     */
+    public InvalidEventInException(String msg)
+    {
+        super(msg);
+    }
+}
diff --git a/src/java/vrml/eai/field/InvalidEventOutException.java b/src/java/vrml/eai/field/InvalidEventOutException.java
index 886e76367eb1c8e2024ab37b69a65d4618648041..df60563f64732ddf5b129113ea0371f62b863f5e 100644
--- a/src/java/vrml/eai/field/InvalidEventOutException.java
+++ b/src/java/vrml/eai/field/InvalidEventOutException.java
@@ -1,50 +1,50 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-/**
- * The exception that is thrown when a reference to an eventOut is not valid.
- *  <p>
- * An eventOut may be invalid for a number of reasons:
- * <UL>
- * <LI>The user may have typed in the wrong name through a typo.
- * <LI>The name may not correspond to a field in that node at all.
- * <LI>The name given refers to a valid field but the field cannot be
- *     accessed as an eventOut.
- * </UL>
- *
- * @version 1.0 7th March 1998
- */
-public class InvalidEventOutException extends InvalidFieldException
-{
-    /**
-     * Construct a basic instance of this exception with no error message
-     */
-    public InvalidEventOutException()
-    {
-        super();
-    }
-
-    /**
-     * Constructs a new exception with a particular message
-     *
-     * @param msg The message to use
-     */
-    public InvalidEventOutException(String msg)
-    {
-        super(msg);
-    }
-}
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+/**
+ * The exception that is thrown when a reference to an eventOut is not valid.
+ *  <p>
+ * An eventOut may be invalid for a number of reasons:
+ * <UL>
+ * <LI>The user may have typed in the wrong name through a typo.
+ * <LI>The name may not correspond to a field in that node at all.
+ * <LI>The name given refers to a valid field but the field cannot be
+ *     accessed as an eventOut.
+ * </UL>
+ *
+ * @version 1.0 7th March 1998
+ */
+public class InvalidEventOutException extends InvalidFieldException
+{
+    /**
+     * Construct a basic instance of this exception with no error message
+     */
+    public InvalidEventOutException()
+    {
+        super();
+    }
+
+    /**
+     * Constructs a new exception with a particular message
+     *
+     * @param msg The message to use
+     */
+    public InvalidEventOutException(String msg)
+    {
+        super(msg);
+    }
+}
diff --git a/src/java/vrml/eai/field/InvalidFieldException.java b/src/java/vrml/eai/field/InvalidFieldException.java
index be4ef619f594276ae9cb307c935adf4bae239f3e..897ff7a18b6f1ac648fd7a5b5e0e869e41c7249d 100644
--- a/src/java/vrml/eai/field/InvalidFieldException.java
+++ b/src/java/vrml/eai/field/InvalidFieldException.java
@@ -1,55 +1,55 @@
-/******************************************************************************
- *
- *                      VRML Browser basic classes
- *                   For External Authoring Interface
- *
- *                   (C) 1998 Justin Couch
- *
- *  Written by Justin Couch: justin@vlc.com.au
- *
- * This code is free software and is distributed under the terms implied by
- * the GNU LGPL. A full version of this license can be found at
- * http://www.gnu.org/copyleft/lgpl.html
- *
- *****************************************************************************/
-
-package vrml.eai.field;
-
-import vrml.eai.VrmlException;
-
-/**
- * The exception that is thrown when a reference to any field is not valid.
- * Generally used as a base class to more specific invalid field methods.
- *  <p>
- * An eventOut may be invalid for a number of reasons:
- * <UL>
- * <LI>The user may have typed in the wrong name through a typo.
- * <LI>The name may not correspond to a field in that node at all.
- * <LI>The name given refers to a valid field but the field cannot be
- *     accessed as an eventOut.
- * </UL>
- *
- * @version 1.0 7th March 1998
- * @see InvalidEventInException
- * @see InvalidEventOutException
- */
-public class InvalidFieldException extends VrmlException
-{
-    /**
-     * Construct a basic instance of this exception with no error message
-     */
-    public InvalidFieldException()
-    {
-        super();
-    }
-
-    /**
-     * Constructs a new exception with a particular message
-     *
-     * @param msg The message to use
-     */
-    public InvalidFieldException(String msg)
-    {
-        super(msg);
-    }
-}
+/******************************************************************************
+ *
+ *                      VRML Browser basic classes
+ *                   For External Authoring Interface
+ *
+ *                   (C) 1998 Justin Couch
+ *
+ *  Written by Justin Couch: justin@vlc.com.au
+ *
+ * This code is free software and is distributed under the terms implied by
+ * the GNU LGPL. A full version of this license can be found at
+ * http://www.gnu.org/copyleft/lgpl.html
+ *
+ *****************************************************************************/
+
+package vrml.eai.field;
+
+import vrml.eai.VrmlException;
+
+/**
+ * The exception that is thrown when a reference to any field is not valid.
+ * Generally used as a base class to more specific invalid field methods.
+ *  <p>
+ * An eventOut may be invalid for a number of reasons:
+ * <UL>
+ * <LI>The user may have typed in the wrong name through a typo.
+ * <LI>The name may not correspond to a field in that node at all.
+ * <LI>The name given refers to a valid field but the field cannot be
+ *     accessed as an eventOut.
+ * </UL>
+ *
+ * @version 1.0 7th March 1998
+ * @see InvalidEventInException
+ * @see InvalidEventOutException
+ */
+public class InvalidFieldException extends VrmlException
+{
+    /**
+     * Construct a basic instance of this exception with no error message
+     */
+    public InvalidFieldException()
+    {
+        super();
+    }
+
+    /**
+     * Constructs a new exception with a particular message
+     *
+     * @param msg The message to use
+     */
+    public InvalidFieldException(String msg)
+    {
+        super(msg);
+    }
+}