You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by eb...@apache.org on 2019/11/27 01:23:29 UTC

[netbeans] branch master updated (bd154f8 -> 23ccd9d)

This is an automated email from the ASF dual-hosted git repository.

ebakke pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git.


    from bd154f8  [NETBEANS-3432] Removed the auto activation code from Dark LaF Support
     new 51a01eb  [NETBEANS-2604] Support SVG icon loading from ImageUtilities
     new 23ccd9d  Simplify/improve the HiDPI splash screen support code.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 nbbuild/cluster.properties                         |   6 +-
 .../licenses/Apache-2.0-XML-Commons-APIs           |  61 +++++-
 .../netbeans/core/startup/ScaledBitmapIcon.java    | 127 ++++-------
 .../libs.batik.read}/build.xml                     |   8 +-
 .../external/batik-1.12-license.txt                |  10 +-
 .../libs.batik.read/external/batik-1.12-notice.txt |  18 ++
 platform/libs.batik.read/external/binaries-list    |  34 +++
 .../external/xml-apis-ext-1.3.04-license.txt       |  65 +++++-
 .../external/xml-apis-ext-1.3.04-notice.txt        |  10 +
 .../external/xmlgraphics-commons-2.4-license.txt   |   9 +-
 .../external/xmlgraphics-commons-2.4-notice.txt    |   5 +
 platform/libs.batik.read/manifest.mf               |   5 +
 .../libs.batik.read/nbproject/project.properties   |  56 +++++
 platform/libs.batik.read/nbproject/project.xml     | 203 ++++++++++++++++++
 .../org/netbeans/libs/batik/read/Bundle.properties |   8 +-
 {ide => platform}/o.apache.commons.io/build.xml    |   2 +-
 .../o.apache.commons.io/external/binaries-list     |   0
 .../external/commons-io-1.4-license.txt            |   0
 .../external/commons-io-1.4-notice.txt             |   0
 {ide => platform}/o.apache.commons.io/manifest.mf  |   0
 .../nbproject/project.properties                   |   0
 .../o.apache.commons.io/nbproject/project.xml      |   0
 .../o.apache.commons.logging/build.xml             |   2 +-
 .../external/binaries-list                         |   0
 .../external/commons-logging-1.1.1-license.txt     |   0
 .../external/commons-logging-1.1.1-notice.txt      |   0
 .../o.apache.commons.logging/manifest.mf           |   0
 .../nbproject/project.properties                   |   0
 .../o.apache.commons.logging/nbproject/project.xml |   0
 .../src/org/openide/resources/actions/redo.svg     |  82 +++++++
 .../src/org/openide/resources/actions/undo.svg     |  82 +++++++
 .../openide.util.ui.svg}/build.xml                 |   4 +-
 platform/openide.util.ui.svg/manifest.mf           |   4 +
 .../nbproject/project.properties                   |   5 +-
 .../nbproject/project.xml                          |  51 ++---
 .../src/org/openide/util/svg/Bundle.properties     |   7 +-
 .../src/org/openide/util/svg/SVGIcon.java          | 209 ++++++++++++++++++
 .../src/org/openide/util/svg/SVGLoaderImpl.java    |  33 +++
 platform/openide.util.ui/apichanges.xml            |  27 +++
 platform/openide.util.ui/arch.xml                  |   7 +-
 platform/openide.util.ui/nbproject/project.xml     |   1 +
 .../src/org/openide/util/CachedHiDPIIcon.java      |  81 +++++--
 .../src/org/openide/util/FilteredIcon.java         |  11 +-
 .../src/org/openide/util/ImageUtilities.java       | 236 ++++++++++++++-------
 .../src/org/openide/util/spi/SVGLoader.java        |  40 ++++
 .../openide/util/ImageUtilitiesGetLoaderTest.java  |   4 +-
 .../modules/javascript/nodejs/ui/resources/npm.svg |   2 +-
 47 files changed, 1257 insertions(+), 258 deletions(-)
 copy ide/o.apache.commons.io/external/commons-io-1.4-license.txt => nbbuild/licenses/Apache-2.0-XML-Commons-APIs (78%)
 copy {ide/o.apache.commons.io => platform/libs.batik.read}/build.xml (70%)
 copy ide/o.apache.commons.logging/external/commons-logging-1.1.1-license.txt => platform/libs.batik.read/external/batik-1.12-license.txt (95%)
 create mode 100644 platform/libs.batik.read/external/batik-1.12-notice.txt
 create mode 100644 platform/libs.batik.read/external/binaries-list
 copy ide/o.apache.commons.io/external/commons-io-1.4-license.txt => platform/libs.batik.read/external/xml-apis-ext-1.3.04-license.txt (77%)
 create mode 100644 platform/libs.batik.read/external/xml-apis-ext-1.3.04-notice.txt
 copy ide/o.apache.commons.logging/external/commons-logging-1.1.1-license.txt => platform/libs.batik.read/external/xmlgraphics-commons-2.4-license.txt (98%)
 create mode 100644 platform/libs.batik.read/external/xmlgraphics-commons-2.4-notice.txt
 create mode 100644 platform/libs.batik.read/manifest.mf
 create mode 100644 platform/libs.batik.read/nbproject/project.properties
 create mode 100644 platform/libs.batik.read/nbproject/project.xml
 copy ide/o.apache.commons.logging/nbproject/project.properties => platform/libs.batik.read/src/org/netbeans/libs/batik/read/Bundle.properties (73%)
 copy {ide => platform}/o.apache.commons.io/build.xml (92%)
 rename {ide => platform}/o.apache.commons.io/external/binaries-list (100%)
 rename {ide => platform}/o.apache.commons.io/external/commons-io-1.4-license.txt (100%)
 rename {ide => platform}/o.apache.commons.io/external/commons-io-1.4-notice.txt (100%)
 rename {ide => platform}/o.apache.commons.io/manifest.mf (100%)
 rename {ide => platform}/o.apache.commons.io/nbproject/project.properties (100%)
 rename {ide => platform}/o.apache.commons.io/nbproject/project.xml (100%)
 rename {ide => platform}/o.apache.commons.logging/build.xml (95%)
 rename {ide => platform}/o.apache.commons.logging/external/binaries-list (100%)
 rename {ide => platform}/o.apache.commons.logging/external/commons-logging-1.1.1-license.txt (100%)
 rename {ide => platform}/o.apache.commons.logging/external/commons-logging-1.1.1-notice.txt (100%)
 rename {ide => platform}/o.apache.commons.logging/manifest.mf (100%)
 copy {ide => platform}/o.apache.commons.logging/nbproject/project.properties (100%)
 rename {ide => platform}/o.apache.commons.logging/nbproject/project.xml (100%)
 create mode 100644 platform/openide.actions/src/org/openide/resources/actions/redo.svg
 create mode 100644 platform/openide.actions/src/org/openide/resources/actions/undo.svg
 rename {ide/o.apache.commons.io => platform/openide.util.ui.svg}/build.xml (90%)
 create mode 100644 platform/openide.util.ui.svg/manifest.mf
 copy {ide/o.apache.commons.logging => platform/openide.util.ui.svg}/nbproject/project.properties (94%)
 copy platform/{openide.util.ui => openide.util.ui.svg}/nbproject/project.xml (56%)
 rename ide/o.apache.commons.logging/nbproject/project.properties => platform/openide.util.ui.svg/src/org/openide/util/svg/Bundle.properties (78%)
 create mode 100644 platform/openide.util.ui.svg/src/org/openide/util/svg/SVGIcon.java
 create mode 100644 platform/openide.util.ui.svg/src/org/openide/util/svg/SVGLoaderImpl.java
 create mode 100644 platform/openide.util.ui/src/org/openide/util/spi/SVGLoader.java


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[netbeans] 02/02: Simplify/improve the HiDPI splash screen support code.

Posted by eb...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ebakke pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git

commit 23ccd9d64f7e4a30316444b56eeea330c161f916
Author: Eirik Bakke <eb...@ultorg.com>
AuthorDate: Thu Jul 25 04:45:33 2019 -0400

    Simplify/improve the HiDPI splash screen support code.
    
    Details:
    * Use the shared caching logic for scaled HiDPI image variants now available by
      subclassing from org.openide.util.CachedHiDPIIcon.
    * Properly wait for the image to load before scaling (via ImageIcon's
      MediaTracker).
    * Rename ScaledBitmapIcon.width/height to sourceWidth/sourceHeight.
    * Document some known image scaling issues on Java.
---
 .../netbeans/core/startup/ScaledBitmapIcon.java    | 127 +++++++--------------
 1 file changed, 42 insertions(+), 85 deletions(-)

diff --git a/platform/core.startup/src/org/netbeans/core/startup/ScaledBitmapIcon.java b/platform/core.startup/src/org/netbeans/core/startup/ScaledBitmapIcon.java
index dec4ee0..2f222f4 100644
--- a/platform/core.startup/src/org/netbeans/core/startup/ScaledBitmapIcon.java
+++ b/platform/core.startup/src/org/netbeans/core/startup/ScaledBitmapIcon.java
@@ -19,110 +19,67 @@
 package org.netbeans.core.startup;
 
 import java.awt.Component;
-import java.awt.Graphics;
 import java.awt.Graphics2D;
-import java.awt.GraphicsConfiguration;
 import java.awt.Image;
 import java.awt.RenderingHints;
-import java.awt.Transparency;
 import java.awt.geom.AffineTransform;
 import java.awt.image.BufferedImage;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
+import java.awt.image.ColorModel;
 import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import org.openide.util.CachedHiDPIIcon;
+import org.openide.util.Parameters;
 
-/* Package-private for now. At some later point it might be useful to expose the DPI-based caching
-functionality in this class as a more general utility. */
 /**
  * An Icon implementation that scales a source image to the specified dimensions. Can be used to
  * produce sharp images on HiDPI displays, without relying on MultiResolutionImage, which exists
  * only since JDK 9. This also sidesteps https://bugs.openjdk.java.net/browse/JDK-8212226 on
- * Windows. For HiDPI displays, the source image's dimensions should be at least double those of the
- * icon's logical dimensions. A double-resolution source image will automatically be scaled down
- * to 1x, 1.5x, or other HiDPI scaling factors as needed.
+ * Windows. It's recommended to use a source image with dimensions that are exactly twice those of
+ * the icon's logical dimensions. A double-resolution source image will automatically be scaled
+ * down to 1x, 1.5x, or other HiDPI scaling factors as needed.
  */
-final class ScaledBitmapIcon implements Icon {
-    private final Map<Double,Image> cache = new ConcurrentHashMap<>();
+final class ScaledBitmapIcon extends CachedHiDPIIcon {
     private final Image sourceImage;
-    private final int width;
-    private final int height;
+    private final int sourceWidth;
+    private final int sourceHeight;
 
     public ScaledBitmapIcon(Image sourceImage, int width, int height) {
-        if (sourceImage == null)
-            throw new NullPointerException();
-        if (width <= 0)
-            throw new IllegalArgumentException();
-        if (height <= 0)
-            throw new IllegalArgumentException();
+        super(width, height);
+        Parameters.notNull("sourceImage", sourceImage);
         this.sourceImage = sourceImage;
-        this.width = width;
-        this.height = height;
-    }
-
-    private Image getScaledImage(GraphicsConfiguration gc, double dpiScaling) {
-        Image ret = cache.get(dpiScaling);
-        if (ret != null) {
-            return ret;
-        }
-        final BufferedImage img = gc.createCompatibleImage(
-                (int) Math.ceil(getIconWidth() * dpiScaling),
-                (int) Math.ceil(getIconHeight() * dpiScaling), Transparency.TRANSLUCENT);
-        final double sourceWidth = sourceImage.getWidth(null);
-        final double sourceHeight = sourceImage.getHeight(null);
-        if (sourceWidth >= 1 && sourceHeight >= 1) {
-          final Graphics2D imgG = (Graphics2D) img.getGraphics();
-          try {
-              imgG.setTransform(AffineTransform.getScaleInstance(
-                      dpiScaling * getIconWidth() / sourceWidth,
-                      dpiScaling * getIconHeight() / sourceHeight));
-              imgG.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-              imgG.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
-              imgG.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
-              imgG.drawImage(sourceImage, 0, 0, null);
-          } finally {
-              imgG.dispose();
-          }
-          if (dpiScaling <= 3.0)
-              cache.put(dpiScaling, img);
-        }
-        return img;
+        /* Like ImageIcon, we block until the image is fully loaded. Just rely on ImageIcon's
+        implementation here (it will ll get a MediaTracker, call waitForID etc.). */
+        Icon imageIcon = new ImageIcon(sourceImage);
+        sourceWidth = imageIcon.getIconWidth();
+        sourceHeight = imageIcon.getIconHeight();
     }
 
     @Override
-    public void paintIcon(Component c, Graphics g0, int x, int y) {
-        final Graphics2D g = (Graphics2D) g0;
-        final AffineTransform oldTransform = g.getTransform();
-        g.translate(x, y);
-        final AffineTransform tx = g.getTransform();
-
-        final double dpiScaling;
-        final int txType = tx.getType();
-        if (txType == AffineTransform.TYPE_UNIFORM_SCALE ||
-            txType == (AffineTransform.TYPE_UNIFORM_SCALE | AffineTransform.TYPE_TRANSLATION))
-        {
-            dpiScaling = tx.getScaleX();
-        } else {
-            dpiScaling = 1.0;
-        }
-        // Scale the image down to its logical dimensions, then draw it at the device pixel boundary.
-        Image scaledImage = getScaledImage(g.getDeviceConfiguration(), dpiScaling);
-        if (dpiScaling != 1.0) {
-            AffineTransform tx2 = g.getTransform();
-            g.setTransform(new AffineTransform(1, 0, 0, 1,
-                (int) tx2.getTranslateX(),
-                (int) tx2.getTranslateY()));
+    protected Image createAndPaintImage(
+        Component c, ColorModel colorModel, int deviceWidth, int deviceHeight, double scale)
+    {
+        final BufferedImage img = createBufferedImage(colorModel, deviceWidth, deviceHeight);
+        if (sourceWidth > 0 && sourceHeight > 0) {
+            final Graphics2D g = img.createGraphics();
+            try {
+                /* Despite these hints, downscaling by more than 2x tends to give low-quality
+                results compared to image resizing in, say, Photoshop or IrfanView. This is a known
+                quality/performance trade-off in Java2D; see
+                https://stackoverflow.com/questions/24745147/java-resize-image-without-losing-quality .
+                Our Javadoc recommendation to use a scaling of exactly 2x should avoid these
+                problems. */
+                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+                g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
+                g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
+                g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+                g.setTransform(AffineTransform.getScaleInstance(
+                        scale * getIconWidth() / (double) sourceWidth,
+                        scale * getIconHeight() / (double) sourceHeight));
+                g.drawImage(sourceImage, 0, 0, null);
+            } finally {
+                g.dispose();
+            }
         }
-        g.drawImage(scaledImage, 0, 0, null);
-        g.setTransform(oldTransform);
-    }
-
-    @Override
-    public int getIconWidth() {
-        return width;
-    }
-
-    @Override
-    public int getIconHeight() {
-        return height;
+        return img;
     }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[netbeans] 01/02: [NETBEANS-2604] Support SVG icon loading from ImageUtilities

Posted by eb...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ebakke pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git

commit 51a01eb9cbfc6f342a1827d47f0b37e1b2f070a3
Author: Eirik Bakke <eb...@ultorg.com>
AuthorDate: Sat Jun 1 00:20:11 2019 -0400

    [NETBEANS-2604] Support SVG icon loading from ImageUtilities
    
    As a part of the effort to make NetBeans look better on HiDPI displays, the
    ImageUtilities class has now been completely updated to support scalable
    implementations of the java.awt.Icon interface, and to support loading of icons
    and images from SVG files. If an SVG file resource exists with the same base
    name as an existing bitmap icon, and the SVG loader implementation modules is
    installed, the SVG file will be loaded instead (e.g. "icon.svg" will be loaded
    instead of "icon.png"). SVG file resources can also be loaded explicitly.
    
    Details:
    * Have ImageUtilities support SVG image loading via an optional pluggable
      service provider, and add an implementation based on the Batik SVG library.
      The latter is enabled by default in the "platform" cluster.
    * Add SVG versions of the Undo/Redo action icons (visible in the Edit menu and
      in the NetBeans toolbar in "Small Toolbar Icons" mode). This will serve to
      test SVG icon loading and painting.
    * Moved the o.apache.commons.io and o.apache.commons.logging modules from the
      "ide" cluster and into the "platform" cluster, as Batik depends on these
      libraries.
    * Refactor, clean up, and generalize ImageUtilities.getLoader; it is used to
      fetch and cache both the ClassLoader and the SVGLoader implementation. The
      SVG loader implementation module will only be loaded once an actual SVG file
      is found and needs to be loaded.
---
 nbbuild/cluster.properties                         |   6 +-
 .../licenses/Apache-2.0-XML-Commons-APIs           |  61 +++++-
 .../libs.batik.read}/build.xml                     |   8 +-
 .../external/batik-1.12-license.txt                |  10 +-
 .../libs.batik.read/external/batik-1.12-notice.txt |  18 ++
 platform/libs.batik.read/external/binaries-list    |  34 +++
 .../external/xml-apis-ext-1.3.04-license.txt       |  65 +++++-
 .../external/xml-apis-ext-1.3.04-notice.txt        |  10 +
 .../external/xmlgraphics-commons-2.4-license.txt   |   9 +-
 .../external/xmlgraphics-commons-2.4-notice.txt    |   5 +
 platform/libs.batik.read/manifest.mf               |   5 +
 .../libs.batik.read/nbproject/project.properties   |  56 +++++
 platform/libs.batik.read/nbproject/project.xml     | 203 ++++++++++++++++++
 .../org/netbeans/libs/batik/read/Bundle.properties |   8 +-
 {ide => platform}/o.apache.commons.io/build.xml    |   2 +-
 .../o.apache.commons.io/external/binaries-list     |   0
 .../external/commons-io-1.4-license.txt            |   0
 .../external/commons-io-1.4-notice.txt             |   0
 {ide => platform}/o.apache.commons.io/manifest.mf  |   0
 .../nbproject/project.properties                   |   0
 .../o.apache.commons.io/nbproject/project.xml      |   0
 .../o.apache.commons.logging/build.xml             |   2 +-
 .../external/binaries-list                         |   0
 .../external/commons-logging-1.1.1-license.txt     |   0
 .../external/commons-logging-1.1.1-notice.txt      |   0
 .../o.apache.commons.logging/manifest.mf           |   0
 .../nbproject/project.properties                   |   0
 .../o.apache.commons.logging/nbproject/project.xml |   0
 .../src/org/openide/resources/actions/redo.svg     |  82 +++++++
 .../src/org/openide/resources/actions/undo.svg     |  82 +++++++
 .../openide.util.ui.svg}/build.xml                 |   4 +-
 platform/openide.util.ui.svg/manifest.mf           |   4 +
 .../nbproject/project.properties                   |   5 +-
 .../nbproject/project.xml                          |  51 ++---
 .../src/org/openide/util/svg/Bundle.properties     |   7 +-
 .../src/org/openide/util/svg/SVGIcon.java          | 209 ++++++++++++++++++
 .../src/org/openide/util/svg/SVGLoaderImpl.java    |  33 +++
 platform/openide.util.ui/apichanges.xml            |  27 +++
 platform/openide.util.ui/arch.xml                  |   7 +-
 platform/openide.util.ui/nbproject/project.xml     |   1 +
 .../src/org/openide/util/CachedHiDPIIcon.java      |  81 +++++--
 .../src/org/openide/util/FilteredIcon.java         |  11 +-
 .../src/org/openide/util/ImageUtilities.java       | 236 ++++++++++++++-------
 .../src/org/openide/util/spi/SVGLoader.java        |  40 ++++
 .../openide/util/ImageUtilitiesGetLoaderTest.java  |   4 +-
 .../modules/javascript/nodejs/ui/resources/npm.svg |   2 +-
 46 files changed, 1215 insertions(+), 173 deletions(-)

diff --git a/nbbuild/cluster.properties b/nbbuild/cluster.properties
index 588849e..783e5ba 100644
--- a/nbbuild/cluster.properties
+++ b/nbbuild/cluster.properties
@@ -224,6 +224,7 @@ nb.cluster.platform=\
         keyring.fallback,\
         keyring.impl,\
         lib.uihandler,\
+        libs.batik.read,\
         libs.felix,\
         libs.javafx,\
         libs.jna,\
@@ -247,6 +248,8 @@ nb.cluster.platform=\
         net.java.html.json,\
         net.java.html.sound,\
         netbinox,\
+        o.apache.commons.io,\
+        o.apache.commons.logging,\
         o.n.core,\
         o.n.html.ko4j,\
         o.n.html.xhr4j,\
@@ -270,6 +273,7 @@ nb.cluster.platform=\
         openide.options,\
         openide.text,\
         openide.util.enumerations,\
+        openide.util.ui.svg,\
         openide.windows,\
         options.api,\
         options.keymap,\
@@ -437,9 +441,7 @@ nb.cluster.ide=\
         notifications,\
         o.apache.commons.codec,\
         o.apache.commons.httpclient,\
-        o.apache.commons.io,\
         o.apache.commons.lang,\
-        o.apache.commons.logging,\
         o.apache.ws.commons.util,\
         o.apache.xml.resolver,\
         o.apache.xmlrpc,\
diff --git a/ide/o.apache.commons.io/external/commons-io-1.4-license.txt b/nbbuild/licenses/Apache-2.0-XML-Commons-APIs
similarity index 78%
copy from ide/o.apache.commons.io/external/commons-io-1.4-license.txt
copy to nbbuild/licenses/Apache-2.0-XML-Commons-APIs
index 9544faf..1f71363 100644
--- a/ide/o.apache.commons.io/external/commons-io-1.4-license.txt
+++ b/nbbuild/licenses/Apache-2.0-XML-Commons-APIs
@@ -1,11 +1,4 @@
-Name: Apache Commons IO
-Description: Assist with developing IO functionality
-Origin: Apache Software Foundation
-Version: 1.4
-License: Apache-2.0
-URL: http://commons.apache.org/io/
-
-
+======================  Parts of this work are licensed: ======================
 
                                  Apache License
                            Version 2.0, January 2004
@@ -209,3 +202,55 @@ URL: http://commons.apache.org/io/
    See the License for the specific language governing permissions and
    limitations under the License.
 
+======================  Parts of this work are licensed: ======================
+
+W3C® SOFTWARE NOTICE AND LICENSE
+Copyright © 2004 World Wide Web Consortium, (Massachusetts Institute of Technology,
+European Research Consortium for Informatics and Mathematics, Keio University).
+All Rights Reserved.
+
+The DOM bindings are published under the W3C Software Copyright Notice and
+License. The software license requires "Notice of any changes or modifications
+to the W3C files, including the date changes were made." Consequently, modified
+versions of the DOM bindings must document that they do not conform to the W3C
+standard; in the case of the IDL definitions, the pragma prefix can no longer
+be 'w3c.org'; in the case of the Java language binding, the package names can no
+longer be in the 'org.w3c' package.
+
+Note: The original version of the W3C Software Copyright Notice and License could
+be found at http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
+
+This work (and included software, documentation such as READMEs, or other
+related items) is being provided by the copyright holders under the following
+license. By obtaining, using and/or copying this work, you (the licensee) agree
+that you have read, understood, and will comply with the following terms and
+conditions.
+
+Permission to copy, modify, and distribute this software and its documentation,
+with or without modification, for any purpose and without fee or royalty is
+hereby granted, provided that you include the following on ALL copies of the
+software and documentation or portions thereof, including modifications:
+
+  1. The full text of this NOTICE in a location viewable to users of the
+     redistributed or derivative work.
+  2. Any pre-existing intellectual property disclaimers, notices, or terms
+     and conditions. If none exist, the W3C Software Short Notice should be
+     included (hypertext is preferred, text is permitted) within the body
+     of any redistributed or derivative code.
+  3. Notice of any changes or modifications to the files, including the date
+     changes were made. (We recommend you provide URIs to the location from
+     which the code is derived.)
+
+THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE
+NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT
+THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY
+PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+
+COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION.
+
+The name and trademarks of copyright holders may NOT be used in advertising or
+publicity pertaining to the software without specific, written prior permission.
+Title to copyright in this software and any associated documentation will at
+all times remain with copyright holders.
diff --git a/ide/o.apache.commons.io/build.xml b/platform/libs.batik.read/build.xml
similarity index 70%
copy from ide/o.apache.commons.io/build.xml
copy to platform/libs.batik.read/build.xml
index 5a07067..afa2656 100644
--- a/ide/o.apache.commons.io/build.xml
+++ b/platform/libs.batik.read/build.xml
@@ -19,7 +19,11 @@
     under the License.
 
 -->
-<project name="ide/o.apache.commons.io" default="build" basedir=".">
+
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="platform/libs.batik.read" default="build" basedir=".">
+    <description>Builds the Batik SVG reading library wrapper module.</description>
     <import file="../../nbbuild/templates/projectized.xml"/>
-    <target name="jar"/>
 </project>
diff --git a/ide/o.apache.commons.logging/external/commons-logging-1.1.1-license.txt b/platform/libs.batik.read/external/batik-1.12-license.txt
similarity index 95%
copy from ide/o.apache.commons.logging/external/commons-logging-1.1.1-license.txt
copy to platform/libs.batik.read/external/batik-1.12-license.txt
index d68b66f..07d1a9b 100644
--- a/ide/o.apache.commons.logging/external/commons-logging-1.1.1-license.txt
+++ b/platform/libs.batik.read/external/batik-1.12-license.txt
@@ -1,9 +1,9 @@
-Name: Apache Jakarta Commons Logging
-Origin: Apache Software Foundation
-Version: 1.1.1
+Name: Apache Batik
+Version: 1.12
+Description: Batik is a toolkit for applications that want to use images in the Scalable Vector Graphics (SVG) format for various purposes, such as display, generation or manipulation.
 License: Apache-2.0
-Description: Logging component
-URL: http://commons.apache.org/logging/
+Origin: https://xmlgraphics.apache.org/batik/
+Files: batik-anim-1.12.jar, batik-awt-util-1.12.jar, batik-bridge-1.12.jar, batik-constants-1.12.jar, batik-css-1.12.jar, batik-dom-1.12.jar, batik-ext-1.12.jar, batik-gvt-1.12.jar, batik-i18n-1.12.jar, batik-parser-1.12.jar, batik-script-1.12.jar, batik-svg-dom-1.12.jar, batik-util-1.12.jar, batik-xml-1.12.jar
 
                                  Apache License
                            Version 2.0, January 2004
diff --git a/platform/libs.batik.read/external/batik-1.12-notice.txt b/platform/libs.batik.read/external/batik-1.12-notice.txt
new file mode 100644
index 0000000..f973b7c
--- /dev/null
+++ b/platform/libs.batik.read/external/batik-1.12-notice.txt
@@ -0,0 +1,18 @@
+Apache Batik
+Copyright 1999-2019 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+This software contains code from the World Wide Web Consortium (W3C) for the 
+Document Object Model API (DOM API) and SVG Document Type Definition (DTD).
+
+This software contains code from the International Organisation for
+Standardization for the definition of character entities used in the software's
+documentation.
+
+This product includes images from the Tango Desktop Project
+(http://tango.freedesktop.org/).
+
+This product includes images from the Pasodoble Icon Theme
+(http://www.jesusda.com/projects/pasodoble).
diff --git a/platform/libs.batik.read/external/binaries-list b/platform/libs.batik.read/external/binaries-list
new file mode 100644
index 0000000..8e371c2
--- /dev/null
+++ b/platform/libs.batik.read/external/binaries-list
@@ -0,0 +1,34 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+639288C6A28F0EFCFEA84EBB17E50F189A22E3E8 org.apache.xmlgraphics:batik-anim:1.12
+652BADD31839669CFA5F01442F8569FBECD21E8F org.apache.xmlgraphics:batik-awt-util:1.12
+FBE0DDB2479947B626488A9782A6CF10358A5316 org.apache.xmlgraphics:batik-bridge:1.12
+5B29253D1CFA01E04C69E7C28BB8300FEEA8CC56 org.apache.xmlgraphics:batik-constants:1.12
+2BE539A021BFB638880A7394AD5D5A7403FBE3C9 org.apache.xmlgraphics:batik-css:1.12
+1F7A51F02419A5B20333EC8116382FD7BCA78BD5 org.apache.xmlgraphics:batik-dom:1.12
+A5850A5AE69A88EE18E961F8044DCBA452D26E8F org.apache.xmlgraphics:batik-ext:1.12
+C2B801412806277ADE24CAE0A2AF286523105D71 org.apache.xmlgraphics:batik-gvt:1.12
+06044C6026B1178C078371E271222455671B5BD7 org.apache.xmlgraphics:batik-i18n:1.12
+90BFC41579C890D543ACDB99B2B6390B09298B85 org.apache.xmlgraphics:batik-parser:1.12
+1359DA49BDBF10786FC9CB592833DED11B97E432 org.apache.xmlgraphics:batik-script:1.12
+CCC87493A4074348B2E090B2CE7A3ECCD4E8AF44 org.apache.xmlgraphics:batik-svg-dom:1.12
+A6D07D042AE8C8343EADD125D9EB76E25FFD908A org.apache.xmlgraphics:batik-util:1.12
+104615BA0F67A463BB70E2638D87E158C882AE79 org.apache.xmlgraphics:batik-xml:1.12
+41A8B86B358E87F3F13CF46069721719105AFF66 xml-apis:xml-apis-ext:1.3.04
+8D261DF049A23D40A053D2700399EA76080FE0A8 org.apache.xmlgraphics:xmlgraphics-commons:2.4
+
diff --git a/ide/o.apache.commons.io/external/commons-io-1.4-license.txt b/platform/libs.batik.read/external/xml-apis-ext-1.3.04-license.txt
similarity index 77%
copy from ide/o.apache.commons.io/external/commons-io-1.4-license.txt
copy to platform/libs.batik.read/external/xml-apis-ext-1.3.04-license.txt
index 9544faf..3c35073 100644
--- a/ide/o.apache.commons.io/external/commons-io-1.4-license.txt
+++ b/platform/libs.batik.read/external/xml-apis-ext-1.3.04-license.txt
@@ -1,11 +1,10 @@
-Name: Apache Commons IO
-Description: Assist with developing IO functionality
-Origin: Apache Software Foundation
-Version: 1.4
-License: Apache-2.0
-URL: http://commons.apache.org/io/
-
+Name: Apache XML Commons XML APIs
+Version: 1.3.04
+Description: Apache XML Graphics Commons is a library that consists of several reusable components used by Apache Batik and Apache FOP.
+License: Apache-2.0-XML-Commons-APIs
+Origin: https://xmlgraphics.apache.org/commons/
 
+======================  Parts of this work are licensed: ======================
 
                                  Apache License
                            Version 2.0, January 2004
@@ -209,3 +208,55 @@ URL: http://commons.apache.org/io/
    See the License for the specific language governing permissions and
    limitations under the License.
 
+======================  Parts of this work are licensed: ======================
+
+W3C® SOFTWARE NOTICE AND LICENSE
+Copyright © 2004 World Wide Web Consortium, (Massachusetts Institute of Technology,
+European Research Consortium for Informatics and Mathematics, Keio University).
+All Rights Reserved.
+
+The DOM bindings are published under the W3C Software Copyright Notice and
+License. The software license requires "Notice of any changes or modifications
+to the W3C files, including the date changes were made." Consequently, modified
+versions of the DOM bindings must document that they do not conform to the W3C
+standard; in the case of the IDL definitions, the pragma prefix can no longer
+be 'w3c.org'; in the case of the Java language binding, the package names can no
+longer be in the 'org.w3c' package.
+
+Note: The original version of the W3C Software Copyright Notice and License could
+be found at http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
+
+This work (and included software, documentation such as READMEs, or other
+related items) is being provided by the copyright holders under the following
+license. By obtaining, using and/or copying this work, you (the licensee) agree
+that you have read, understood, and will comply with the following terms and
+conditions.
+
+Permission to copy, modify, and distribute this software and its documentation,
+with or without modification, for any purpose and without fee or royalty is
+hereby granted, provided that you include the following on ALL copies of the
+software and documentation or portions thereof, including modifications:
+
+  1. The full text of this NOTICE in a location viewable to users of the
+     redistributed or derivative work.
+  2. Any pre-existing intellectual property disclaimers, notices, or terms
+     and conditions. If none exist, the W3C Software Short Notice should be
+     included (hypertext is preferred, text is permitted) within the body
+     of any redistributed or derivative code.
+  3. Notice of any changes or modifications to the files, including the date
+     changes were made. (We recommend you provide URIs to the location from
+     which the code is derived.)
+
+THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE
+NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT
+THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY
+PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+
+COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION.
+
+The name and trademarks of copyright holders may NOT be used in advertising or
+publicity pertaining to the software without specific, written prior permission.
+Title to copyright in this software and any associated documentation will at
+all times remain with copyright holders.
diff --git a/platform/libs.batik.read/external/xml-apis-ext-1.3.04-notice.txt b/platform/libs.batik.read/external/xml-apis-ext-1.3.04-notice.txt
new file mode 100644
index 0000000..dfd7644
--- /dev/null
+++ b/platform/libs.batik.read/external/xml-apis-ext-1.3.04-notice.txt
@@ -0,0 +1,10 @@
+Apache XML Commons XML APIs
+Copyright 2006 The Apache Software Foundation.
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+Portions of this software were originally based on the following:
+  - software copyright (c) 1999, IBM Corporation., http://www.ibm.com.
+  - software copyright (c) 1999, Sun Microsystems., http://www.sun.com.
+  - software copyright (c) 2000 World Wide Web Consortium, http://www.w3.org
diff --git a/ide/o.apache.commons.logging/external/commons-logging-1.1.1-license.txt b/platform/libs.batik.read/external/xmlgraphics-commons-2.4-license.txt
similarity index 98%
copy from ide/o.apache.commons.logging/external/commons-logging-1.1.1-license.txt
copy to platform/libs.batik.read/external/xmlgraphics-commons-2.4-license.txt
index d68b66f..308dd56 100644
--- a/ide/o.apache.commons.logging/external/commons-logging-1.1.1-license.txt
+++ b/platform/libs.batik.read/external/xmlgraphics-commons-2.4-license.txt
@@ -1,9 +1,8 @@
-Name: Apache Jakarta Commons Logging
-Origin: Apache Software Foundation
-Version: 1.1.1
+Name: Apache XML Graphics Commons
+Version: 2.4
+Description: Apache XML Graphics Commons is a library that consists of several reusable components used by Apache Batik and Apache FOP.
 License: Apache-2.0
-Description: Logging component
-URL: http://commons.apache.org/logging/
+Origin: https://xmlgraphics.apache.org/commons/
 
                                  Apache License
                            Version 2.0, January 2004
diff --git a/platform/libs.batik.read/external/xmlgraphics-commons-2.4-notice.txt b/platform/libs.batik.read/external/xmlgraphics-commons-2.4-notice.txt
new file mode 100644
index 0000000..e8c8002
--- /dev/null
+++ b/platform/libs.batik.read/external/xmlgraphics-commons-2.4-notice.txt
@@ -0,0 +1,5 @@
+Apache XML Graphics Commons
+Copyright 2006-2019 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/platform/libs.batik.read/manifest.mf b/platform/libs.batik.read/manifest.mf
new file mode 100644
index 0000000..f3f7026
--- /dev/null
+++ b/platform/libs.batik.read/manifest.mf
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+OpenIDE-Module: org.netbeans.libs.batik.read
+OpenIDE-Module-Implementation-Version: 1
+OpenIDE-Module-Localizing-Bundle: org/netbeans/libs/batik/read/Bundle.properties
+AutoUpdate-Show-In-Client: false
diff --git a/platform/libs.batik.read/nbproject/project.properties b/platform/libs.batik.read/nbproject/project.properties
new file mode 100644
index 0000000..5b10912
--- /dev/null
+++ b/platform/libs.batik.read/nbproject/project.properties
@@ -0,0 +1,56 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+file.reference.batik-anim-1.12.jar=external/batik-anim-1.12.jar
+file.reference.batik-awt-util-1.12.jar=external/batik-awt-util-1.12.jar
+file.reference.batik-bridge-1.12.jar=external/batik-bridge-1.12.jar
+file.reference.batik-constants-1.12.jar=external/batik-constants-1.12.jar
+file.reference.batik-css-1.12.jar=external/batik-css-1.12.jar
+file.reference.batik-dom-1.12.jar=external/batik-dom-1.12.jar
+file.reference.batik-ext-1.12.jar=external/batik-ext-1.12.jar
+file.reference.batik-gvt-1.12.jar=external/batik-gvt-1.12.jar
+file.reference.batik-i18n-1.12.jar=external/batik-i18n-1.12.jar
+file.reference.batik-parser-1.12.jar=external/batik-parser-1.12.jar
+file.reference.batik-script-1.12.jar=external/batik-script-1.12.jar
+file.reference.batik-svg-dom-1.12.jar=external/batik-svg-dom-1.12.jar
+file.reference.batik-util-1.12.jar=external/batik-util-1.12.jar
+file.reference.batik-xml-1.12.jar=external/batik-xml-1.12.jar
+file.reference.xml-apis-ext-1.3.04.jar=external/xml-apis-ext-1.3.04.jar
+file.reference.xmlgraphics-commons-2.4.jar=external/xmlgraphics-commons-2.4.jar
+release.external/batik-anim-1.12.jar=modules/ext/batik-anim-1.12.jar
+release.external/batik-awt-util-1.12.jar=modules/ext/batik-awt-util-1.12.jar
+release.external/batik-bridge-1.12.jar=modules/ext/batik-bridge-1.12.jar
+release.external/batik-constants-1.12.jar=modules/ext/batik-constants-1.12.jar
+release.external/batik-css-1.12.jar=modules/ext/batik-css-1.12.jar
+release.external/batik-dom-1.12.jar=modules/ext/batik-dom-1.12.jar
+release.external/batik-ext-1.12.jar=modules/ext/batik-ext-1.12.jar
+release.external/batik-gvt-1.12.jar=modules/ext/batik-gvt-1.12.jar
+release.external/batik-i18n-1.12.jar=modules/ext/batik-i18n-1.12.jar
+release.external/batik-parser-1.12.jar=modules/ext/batik-parser-1.12.jar
+release.external/batik-script-1.12.jar=modules/ext/batik-script-1.12.jar
+release.external/batik-svg-dom-1.12.jar=modules/ext/batik-svg-dom-1.12.jar
+release.external/batik-util-1.12.jar=modules/ext/batik-util-1.12.jar
+release.external/batik-xml-1.12.jar=modules/ext/batik-xml-1.12.jar
+release.external/xml-apis-ext-1.3.04.jar=modules/ext/xml-apis-ext-1.3.04.jar
+release.external/xmlgraphics-commons-2.4.jar=modules/ext/xmlgraphics-commons-2.4.jar
+
+is.autoload=true
+javac.source=1.6
+
+nbm.homepage=https://xmlgraphics.apache.org/batik/
+sigtest.gen.fail.on.error=false
+spec.version.base=1.0.0
diff --git a/platform/libs.batik.read/nbproject/project.xml b/platform/libs.batik.read/nbproject/project.xml
new file mode 100644
index 0000000..8a7fa98
--- /dev/null
+++ b/platform/libs.batik.read/nbproject/project.xml
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/2">
+            <code-name-base>org.netbeans.libs.batik.read</code-name-base>
+            <module-dependencies>
+                <!-- Use compile-dependency for these rather than
+                run-dependency, otherwise,
+                o.n.core.startup.layers.CachingPreventsFileTouchesTest will
+                fail with a "No reads during startup" error. Not sure why. The
+                test failure appears even if all the Batik JAR
+                class-path-extension dependencies are commented out, and if we
+                are only depending on org.apache.commons.logging. So the problem
+                is unrelated to Batik. -->
+                <dependency>
+                    <code-name-base>org.apache.commons.io</code-name-base>
+                    <compile-dependency/>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.apache.commons.logging</code-name-base>
+                    <compile-dependency/>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <!-- Just expose all packages from the wrapped JARs. -->
+                <package>org.apache.batik</package>
+                <package>org.apache.batik.anim</package>
+                <package>org.apache.batik.anim.dom</package>
+                <package>org.apache.batik.anim.timing</package>
+                <package>org.apache.batik.anim.values</package>
+                <package>org.apache.batik.bridge</package>
+                <package>org.apache.batik.bridge.svg12</package>
+                <package>org.apache.batik.constants</package>
+                <package>org.apache.batik.css.dom</package>
+                <package>org.apache.batik.css.engine</package>
+                <package>org.apache.batik.css.engine.sac</package>
+                <package>org.apache.batik.css.engine.value</package>
+                <package>org.apache.batik.css.engine.value.css2</package>
+                <package>org.apache.batik.css.engine.value.svg</package>
+                <package>org.apache.batik.css.engine.value.svg12</package>
+                <package>org.apache.batik.css.parser</package>
+                <package>org.apache.batik.dom</package>
+                <package>org.apache.batik.dom.events</package>
+                <package>org.apache.batik.dom.svg</package>
+                <package>org.apache.batik.dom.svg12</package>
+                <package>org.apache.batik.dom.traversal</package>
+                <package>org.apache.batik.dom.util</package>
+                <package>org.apache.batik.dom.xbl</package>
+                <package>org.apache.batik.ext.awt</package>
+                <package>org.apache.batik.ext.awt.color</package>
+                <package>org.apache.batik.ext.awt.font</package>
+                <package>org.apache.batik.ext.awt.g2d</package>
+                <package>org.apache.batik.ext.awt.geom</package>
+                <package>org.apache.batik.ext.awt.image</package>
+                <package>org.apache.batik.ext.awt.image.renderable</package>
+                <package>org.apache.batik.ext.awt.image.rendered</package>
+                <package>org.apache.batik.ext.awt.image.spi</package>
+                <package>org.apache.batik.ext.swing</package>
+                <package>org.apache.batik.gvt</package>
+                <package>org.apache.batik.gvt.event</package>
+                <package>org.apache.batik.gvt.filter</package>
+                <package>org.apache.batik.gvt.flow</package>
+                <package>org.apache.batik.gvt.font</package>
+                <package>org.apache.batik.gvt.renderer</package>
+                <package>org.apache.batik.gvt.text</package>
+                <package>org.apache.batik.i18n</package>
+                <package>org.apache.batik.parser</package>
+                <package>org.apache.batik.script</package>
+                <package>org.apache.batik.script.jpython</package>
+                <package>org.apache.batik.script.rhino</package>
+                <package>org.apache.batik.util</package>
+                <package>org.apache.batik.util.io</package>
+                <package>org.apache.batik.util.resources</package>
+                <package>org.apache.batik.w3c.dom</package>
+                <package>org.apache.batik.w3c.dom.events</package>
+                <package>org.apache.batik.xml</package>
+                <package>org.apache.xmlgraphics.fonts</package>
+                <package>org.apache.xmlgraphics.image</package>
+                <package>org.apache.xmlgraphics.image.codec.png</package>
+                <package>org.apache.xmlgraphics.image.codec.tiff</package>
+                <package>org.apache.xmlgraphics.image.codec.util</package>
+                <package>org.apache.xmlgraphics.image.loader</package>
+                <package>org.apache.xmlgraphics.image.loader.cache</package>
+                <package>org.apache.xmlgraphics.image.loader.impl</package>
+                <package>org.apache.xmlgraphics.image.loader.impl.imageio</package>
+                <package>org.apache.xmlgraphics.image.loader.pipeline</package>
+                <package>org.apache.xmlgraphics.image.loader.spi</package>
+                <package>org.apache.xmlgraphics.image.loader.util</package>
+                <package>org.apache.xmlgraphics.image.rendered</package>
+                <package>org.apache.xmlgraphics.image.writer</package>
+                <package>org.apache.xmlgraphics.image.writer.imageio</package>
+                <package>org.apache.xmlgraphics.image.writer.internal</package>
+                <package>org.apache.xmlgraphics.io</package>
+                <package>org.apache.xmlgraphics.java2d</package>
+                <package>org.apache.xmlgraphics.java2d.color</package>
+                <package>org.apache.xmlgraphics.java2d.color.profile</package>
+                <package>org.apache.xmlgraphics.java2d.ps</package>
+                <package>org.apache.xmlgraphics.ps</package>
+                <package>org.apache.xmlgraphics.ps.dsc</package>
+                <package>org.apache.xmlgraphics.ps.dsc.events</package>
+                <package>org.apache.xmlgraphics.ps.dsc.tools</package>
+                <package>org.apache.xmlgraphics.util</package>
+                <package>org.apache.xmlgraphics.util.dijkstra</package>
+                <package>org.apache.xmlgraphics.util.i18n</package>
+                <package>org.apache.xmlgraphics.util.io</package>
+                <package>org.apache.xmlgraphics.util.uri</package>
+                <package>org.apache.xmlgraphics.xmp</package>
+                <package>org.apache.xmlgraphics.xmp.merge</package>
+                <package>org.apache.xmlgraphics.xmp.schemas</package>
+                <package>org.apache.xmlgraphics.xmp.schemas.pdf</package>
+                <package>org.w3c.css.sac</package>
+                <package>org.w3c.css.sac.helpers</package>
+                <package>org.w3c.dom.smil</package>
+                <package>org.w3c.dom.svg</package>
+            </public-packages>
+            <class-path-extension>
+                <runtime-relative-path>ext/batik-constants-1.12.jar</runtime-relative-path>
+                <binary-origin>external/batik-constants-1.12.jar</binary-origin>
+            </class-path-extension>
+            <class-path-extension>
+                <runtime-relative-path>ext/batik-util-1.12.jar</runtime-relative-path>
+                <binary-origin>external/batik-util-1.12.jar</binary-origin>
+            </class-path-extension>
+            <class-path-extension>
+                <runtime-relative-path>ext/batik-svg-dom-1.12.jar</runtime-relative-path>
+                <binary-origin>external/batik-svg-dom-1.12.jar</binary-origin>
+            </class-path-extension>
+            <class-path-extension>
+                <runtime-relative-path>ext/batik-xml-1.12.jar</runtime-relative-path>
+                <binary-origin>external/batik-xml-1.12.jar</binary-origin>
+            </class-path-extension>
+            <class-path-extension>
+                <runtime-relative-path>ext/batik-anim-1.12.jar</runtime-relative-path>
+                <binary-origin>external/batik-anim-1.12.jar</binary-origin>
+            </class-path-extension>
+            <class-path-extension>
+                <runtime-relative-path>ext/batik-gvt-1.12.jar</runtime-relative-path>
+                <binary-origin>external/batik-gvt-1.12.jar</binary-origin>
+            </class-path-extension>
+            <class-path-extension>
+                <runtime-relative-path>ext/batik-dom-1.12.jar</runtime-relative-path>
+                <binary-origin>external/batik-dom-1.12.jar</binary-origin>
+            </class-path-extension>
+            <class-path-extension>
+                <runtime-relative-path>ext/batik-bridge-1.12.jar</runtime-relative-path>
+                <binary-origin>external/batik-bridge-1.12.jar</binary-origin>
+            </class-path-extension>
+            <class-path-extension>
+                <runtime-relative-path>ext/batik-css-1.12.jar</runtime-relative-path>
+                <binary-origin>external/batik-css-1.12.jar</binary-origin>
+            </class-path-extension>
+            <class-path-extension>
+                <runtime-relative-path>ext/batik-i18n-1.12.jar</runtime-relative-path>
+                <binary-origin>external/batik-i18n-1.12.jar</binary-origin>
+            </class-path-extension>
+            <class-path-extension>
+                <runtime-relative-path>ext/batik-ext-1.12.jar</runtime-relative-path>
+                <binary-origin>external/batik-ext-1.12.jar</binary-origin>
+            </class-path-extension>
+            <class-path-extension>
+                <runtime-relative-path>ext/batik-script-1.12.jar</runtime-relative-path>
+                <binary-origin>external/batik-script-1.12.jar</binary-origin>
+            </class-path-extension>
+            <class-path-extension>
+                <runtime-relative-path>ext/xmlgraphics-commons-2.4.jar</runtime-relative-path>
+                <binary-origin>external/xmlgraphics-commons-2.4.jar</binary-origin>
+            </class-path-extension>
+            <class-path-extension>
+                <runtime-relative-path>ext/batik-parser-1.12.jar</runtime-relative-path>
+                <binary-origin>external/batik-parser-1.12.jar</binary-origin>
+            </class-path-extension>
+            <class-path-extension>
+                <runtime-relative-path>ext/xml-apis-ext-1.3.04.jar</runtime-relative-path>
+                <binary-origin>external/xml-apis-ext-1.3.04.jar</binary-origin>
+            </class-path-extension>
+            <class-path-extension>
+                <runtime-relative-path>ext/batik-awt-util-1.12.jar</runtime-relative-path>
+                <binary-origin>external/batik-awt-util-1.12.jar</binary-origin>
+            </class-path-extension>
+        </data>
+    </configuration>
+</project>
diff --git a/ide/o.apache.commons.logging/nbproject/project.properties b/platform/libs.batik.read/src/org/netbeans/libs/batik/read/Bundle.properties
similarity index 73%
copy from ide/o.apache.commons.logging/nbproject/project.properties
copy to platform/libs.batik.read/src/org/netbeans/libs/batik/read/Bundle.properties
index 8788807..f99e527 100644
--- a/ide/o.apache.commons.logging/nbproject/project.properties
+++ b/platform/libs.batik.read/src/org/netbeans/libs/batik/read/Bundle.properties
@@ -14,5 +14,9 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-is.autoload=true
-nbm.module.author=Tomas Stupka
+
+
+OpenIDE-Module-Name=Batik SVG Reading Library
+OpenIDE-Module-Short-Description=Batik SVG Reading Library
+OpenIDE-Module-Long-Description=Contains the subset of JARs from the Apache Batik library necessary to read and paint SVG files.
+OpenIDE-Module-Display-Category=Libraries
diff --git a/ide/o.apache.commons.io/build.xml b/platform/o.apache.commons.io/build.xml
similarity index 92%
copy from ide/o.apache.commons.io/build.xml
copy to platform/o.apache.commons.io/build.xml
index 5a07067..70c3748 100644
--- a/ide/o.apache.commons.io/build.xml
+++ b/platform/o.apache.commons.io/build.xml
@@ -19,7 +19,7 @@
     under the License.
 
 -->
-<project name="ide/o.apache.commons.io" default="build" basedir=".">
+<project name="platform/o.apache.commons.io" default="build" basedir=".">
     <import file="../../nbbuild/templates/projectized.xml"/>
     <target name="jar"/>
 </project>
diff --git a/ide/o.apache.commons.io/external/binaries-list b/platform/o.apache.commons.io/external/binaries-list
similarity index 100%
rename from ide/o.apache.commons.io/external/binaries-list
rename to platform/o.apache.commons.io/external/binaries-list
diff --git a/ide/o.apache.commons.io/external/commons-io-1.4-license.txt b/platform/o.apache.commons.io/external/commons-io-1.4-license.txt
similarity index 100%
rename from ide/o.apache.commons.io/external/commons-io-1.4-license.txt
rename to platform/o.apache.commons.io/external/commons-io-1.4-license.txt
diff --git a/ide/o.apache.commons.io/external/commons-io-1.4-notice.txt b/platform/o.apache.commons.io/external/commons-io-1.4-notice.txt
similarity index 100%
rename from ide/o.apache.commons.io/external/commons-io-1.4-notice.txt
rename to platform/o.apache.commons.io/external/commons-io-1.4-notice.txt
diff --git a/ide/o.apache.commons.io/manifest.mf b/platform/o.apache.commons.io/manifest.mf
similarity index 100%
rename from ide/o.apache.commons.io/manifest.mf
rename to platform/o.apache.commons.io/manifest.mf
diff --git a/ide/o.apache.commons.io/nbproject/project.properties b/platform/o.apache.commons.io/nbproject/project.properties
similarity index 100%
rename from ide/o.apache.commons.io/nbproject/project.properties
rename to platform/o.apache.commons.io/nbproject/project.properties
diff --git a/ide/o.apache.commons.io/nbproject/project.xml b/platform/o.apache.commons.io/nbproject/project.xml
similarity index 100%
rename from ide/o.apache.commons.io/nbproject/project.xml
rename to platform/o.apache.commons.io/nbproject/project.xml
diff --git a/ide/o.apache.commons.logging/build.xml b/platform/o.apache.commons.logging/build.xml
similarity index 95%
rename from ide/o.apache.commons.logging/build.xml
rename to platform/o.apache.commons.logging/build.xml
index 9a1137c..ae93fd5 100644
--- a/ide/o.apache.commons.logging/build.xml
+++ b/platform/o.apache.commons.logging/build.xml
@@ -19,7 +19,7 @@
     under the License.
 
 -->
-<project name="ide/o.apache.commons.logging" default="build" basedir=".">
+<project name="platform/o.apache.commons.logging" default="build" basedir=".">
     <import file="../../nbbuild/templates/projectized.xml"/>
     <target name="jar" depends="-define-FileCRC32Calculator">
         <FileCRC32Calculator file="external/commons-logging-1.1.1.jar" property="o.apache.commons.logging.crc32" />
diff --git a/ide/o.apache.commons.logging/external/binaries-list b/platform/o.apache.commons.logging/external/binaries-list
similarity index 100%
rename from ide/o.apache.commons.logging/external/binaries-list
rename to platform/o.apache.commons.logging/external/binaries-list
diff --git a/ide/o.apache.commons.logging/external/commons-logging-1.1.1-license.txt b/platform/o.apache.commons.logging/external/commons-logging-1.1.1-license.txt
similarity index 100%
rename from ide/o.apache.commons.logging/external/commons-logging-1.1.1-license.txt
rename to platform/o.apache.commons.logging/external/commons-logging-1.1.1-license.txt
diff --git a/ide/o.apache.commons.logging/external/commons-logging-1.1.1-notice.txt b/platform/o.apache.commons.logging/external/commons-logging-1.1.1-notice.txt
similarity index 100%
rename from ide/o.apache.commons.logging/external/commons-logging-1.1.1-notice.txt
rename to platform/o.apache.commons.logging/external/commons-logging-1.1.1-notice.txt
diff --git a/ide/o.apache.commons.logging/manifest.mf b/platform/o.apache.commons.logging/manifest.mf
similarity index 100%
rename from ide/o.apache.commons.logging/manifest.mf
rename to platform/o.apache.commons.logging/manifest.mf
diff --git a/ide/o.apache.commons.logging/nbproject/project.properties b/platform/o.apache.commons.logging/nbproject/project.properties
similarity index 100%
copy from ide/o.apache.commons.logging/nbproject/project.properties
copy to platform/o.apache.commons.logging/nbproject/project.properties
diff --git a/ide/o.apache.commons.logging/nbproject/project.xml b/platform/o.apache.commons.logging/nbproject/project.xml
similarity index 100%
rename from ide/o.apache.commons.logging/nbproject/project.xml
rename to platform/o.apache.commons.logging/nbproject/project.xml
diff --git a/platform/openide.actions/src/org/openide/resources/actions/redo.svg b/platform/openide.actions/src/org/openide/resources/actions/redo.svg
new file mode 100644
index 0000000..3df7e9b
--- /dev/null
+++ b/platform/openide.actions/src/org/openide/resources/actions/redo.svg
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
+	<!ENTITY st0 "fill:#CAE3FF;">
+	<!ENTITY st1 "fill:#FAFAFA;">
+	<!ENTITY st2 "opacity:0.2;">
+	<!ENTITY st3 "opacity:0.03;">
+	<!ENTITY st4 "opacity:0.1;">
+	<!ENTITY st5 "opacity:0.15;">
+	<!ENTITY st6 "opacity:0.25;">
+	<!ENTITY st7 "fill:#FFFFFF;">
+	<!ENTITY st8 "opacity:0.45;">
+	<!ENTITY st9 "fill:#FFE1B0;">
+	<!ENTITY st10 "fill:#B3DBFF;">
+	<!ENTITY st11 "opacity:0.33;">
+	<!ENTITY st12 "fill:#FBDC7C;">
+	<!ENTITY st13 "fill:#FFDB43;">
+	<!ENTITY st14 "fill:#E79B00;">
+	<!ENTITY st15 "fill:#3883CE;">
+	<!ENTITY st16 "fill:none;stroke:#003399;stroke-width:1.375;stroke-miterlimit:10;">
+	<!ENTITY st17 "fill:#E8513D;">
+	<!ENTITY st18 "fill:#1E1E1E;">
+	<!ENTITY st19 "fill:#FFC36D;">
+	<!ENTITY st20 "fill:#9FCBFF;">
+	<!ENTITY st21 "fill:#E9F7FF;">
+	<!ENTITY st22 "fill:#62707C;">
+	<!ENTITY st23 "fill:#7A8896;">
+	<!ENTITY st24 "fill:#57BFFF;">
+	<!ENTITY st25 "fill:#E69D35;">
+	<!ENTITY st26 "fill:#9CFF73;">
+	<!ENTITY st27 "fill:none;stroke:#000000;stroke-miterlimit:10;">
+	<!ENTITY st28 "fill:#4891CC;">
+	<!ENTITY st29 "fill:#474747;">
+	<!ENTITY st30 "fill:#CCA05E;">
+	<!ENTITY st31 "opacity:0.67;">
+	<!ENTITY st32 "opacity:0.3;">
+	<!ENTITY st33 "fill:#EAEAEA;">
+	<!ENTITY st34 "fill:#FFE945;">
+	<!ENTITY st35 "fill:#FFCF8C;">
+	<!ENTITY st36 "fill:#E2BF8E;">
+	<!ENTITY st37 "fill:#FF5252;">
+	<!ENTITY st38 "fill:#512EFF;">
+	<!ENTITY st39 "opacity:0.12;">
+	<!ENTITY st40 "fill:#45A5F4;">
+	<!ENTITY st41 "fill:url(#SVGID_1_);">
+	<!ENTITY st42 "fill:url(#SVGID_2_);">
+	<!ENTITY st43 "fill:none;stroke:#000000;stroke-width:0.3359;stroke-miterlimit:10;">
+	<!ENTITY st44 "opacity:0.05;">
+]>
+<svg version="1.1" id="Vector_Icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
+	 y="0px" width="16px" height="16px" viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
+<g>
+	<path style="&st24;" d="M6,10h10V0h-1l-3.05,3.05C10.683,1.783,8.933,1,7,1C3.134,1,0,4.134,0,8s3.134,7,7,7v-3.75
+		c-1.795,0-3.25-1.455-3.25-3.25S5.205,4.75,7,4.75c0.897,0,1.71,0.364,2.298,0.952L6,9V10z"/>
+	<g style="&st11;">
+		<path d="M15,1.414V9H7.414l2.591-2.591l0.707-0.707l-0.707-0.707C9.202,4.192,8.135,3.75,7,3.75C4.656,3.75,2.75,5.656,2.75,8
+			c0,1.999,1.387,3.68,3.25,4.131v1.786C3.166,13.439,1,10.968,1,8c0-3.308,2.692-6,6-6c1.603,0,3.109,0.624,4.243,1.757
+			l0.707,0.707l0.707-0.707L15,1.414 M16,0h-1l-3.05,3.05C10.683,1.783,8.933,1,7,1C3.134,1,0,4.134,0,8s3.134,7,7,7v-3.75
+			c-1.795,0-3.25-1.455-3.25-3.25S5.205,4.75,7,4.75c0.897,0,1.71,0.364,2.298,0.952L6,9v1h10V0L16,0z"/>
+	</g>
+</g>
+</svg>
diff --git a/platform/openide.actions/src/org/openide/resources/actions/undo.svg b/platform/openide.actions/src/org/openide/resources/actions/undo.svg
new file mode 100644
index 0000000..e9b703e
--- /dev/null
+++ b/platform/openide.actions/src/org/openide/resources/actions/undo.svg
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
+	<!ENTITY st0 "fill:#CAE3FF;">
+	<!ENTITY st1 "fill:#FAFAFA;">
+	<!ENTITY st2 "opacity:0.2;">
+	<!ENTITY st3 "opacity:0.03;">
+	<!ENTITY st4 "opacity:0.1;">
+	<!ENTITY st5 "opacity:0.15;">
+	<!ENTITY st6 "opacity:0.25;">
+	<!ENTITY st7 "fill:#FFFFFF;">
+	<!ENTITY st8 "opacity:0.45;">
+	<!ENTITY st9 "fill:#FFE1B0;">
+	<!ENTITY st10 "fill:#B3DBFF;">
+	<!ENTITY st11 "opacity:0.33;">
+	<!ENTITY st12 "fill:#FBDC7C;">
+	<!ENTITY st13 "fill:#FFDB43;">
+	<!ENTITY st14 "fill:#E79B00;">
+	<!ENTITY st15 "fill:#3883CE;">
+	<!ENTITY st16 "fill:none;stroke:#003399;stroke-width:1.375;stroke-miterlimit:10;">
+	<!ENTITY st17 "fill:#E8513D;">
+	<!ENTITY st18 "fill:#1E1E1E;">
+	<!ENTITY st19 "fill:#FFC36D;">
+	<!ENTITY st20 "fill:#9FCBFF;">
+	<!ENTITY st21 "fill:#E9F7FF;">
+	<!ENTITY st22 "fill:#62707C;">
+	<!ENTITY st23 "fill:#7A8896;">
+	<!ENTITY st24 "fill:#57BFFF;">
+	<!ENTITY st25 "fill:#E69D35;">
+	<!ENTITY st26 "fill:#9CFF73;">
+	<!ENTITY st27 "fill:none;stroke:#000000;stroke-miterlimit:10;">
+	<!ENTITY st28 "fill:#4891CC;">
+	<!ENTITY st29 "fill:#474747;">
+	<!ENTITY st30 "fill:#CCA05E;">
+	<!ENTITY st31 "opacity:0.67;">
+	<!ENTITY st32 "opacity:0.3;">
+	<!ENTITY st33 "fill:#EAEAEA;">
+	<!ENTITY st34 "fill:#FFE945;">
+	<!ENTITY st35 "fill:#FFCF8C;">
+	<!ENTITY st36 "fill:#E2BF8E;">
+	<!ENTITY st37 "fill:#FF5252;">
+	<!ENTITY st38 "fill:#512EFF;">
+	<!ENTITY st39 "opacity:0.12;">
+	<!ENTITY st40 "fill:#45A5F4;">
+	<!ENTITY st41 "fill:url(#SVGID_1_);">
+	<!ENTITY st42 "fill:url(#SVGID_2_);">
+	<!ENTITY st43 "fill:none;stroke:#000000;stroke-width:0.3359;stroke-miterlimit:10;">
+	<!ENTITY st44 "opacity:0.05;">
+]>
+<svg version="1.1" id="Vector_Icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
+	 y="0px" width="16px" height="16px" viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
+<g>
+	<path style="&st25;" d="M10,10H0V0h1l3.05,3.05C5.317,1.783,7.067,1,9,1c3.866,0,7,3.134,7,7s-3.134,7-7,7v-3.75
+		c1.795,0,3.25-1.455,3.25-3.25S10.795,4.75,9,4.75c-0.898,0-1.71,0.364-2.298,0.952L10,9V10z"/>
+	<g style="&st11;">
+		<path d="M1,1.414l2.343,2.343L4.05,4.464l0.707-0.707C5.891,2.624,7.397,2,9,2c3.308,0,6,2.692,6,6c0,2.968-2.166,5.439-5,5.917
+			v-1.786C11.863,11.68,13.25,9.999,13.25,8c0-2.344-1.907-4.25-4.25-4.25c-1.135,0-2.203,0.442-3.005,1.245L5.288,5.702
+			l0.707,0.707L8.586,9H1V1.414 M1,0H0v10h10V9L6.702,5.702C7.29,5.114,8.102,4.75,9,4.75c1.795,0,3.25,1.455,3.25,3.25
+			S10.795,11.25,9,11.25V15c3.866,0,7-3.134,7-7s-3.134-7-7-7C7.067,1,5.317,1.783,4.05,3.05L1,0L1,0z"/>
+	</g>
+</g>
+</svg>
diff --git a/ide/o.apache.commons.io/build.xml b/platform/openide.util.ui.svg/build.xml
similarity index 90%
rename from ide/o.apache.commons.io/build.xml
rename to platform/openide.util.ui.svg/build.xml
index 5a07067..a001567 100644
--- a/ide/o.apache.commons.io/build.xml
+++ b/platform/openide.util.ui.svg/build.xml
@@ -19,7 +19,7 @@
     under the License.
 
 -->
-<project name="ide/o.apache.commons.io" default="build" basedir=".">
+
+<project name="platform/openide.util.ui.svg" default="build" basedir=".">
     <import file="../../nbbuild/templates/projectized.xml"/>
-    <target name="jar"/>
 </project>
diff --git a/platform/openide.util.ui.svg/manifest.mf b/platform/openide.util.ui.svg/manifest.mf
new file mode 100644
index 0000000..2101cca
--- /dev/null
+++ b/platform/openide.util.ui.svg/manifest.mf
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+OpenIDE-Module: org.openide.util.ui.svg
+OpenIDE-Module-Localizing-Bundle: org/openide/util/svg/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
diff --git a/ide/o.apache.commons.logging/nbproject/project.properties b/platform/openide.util.ui.svg/nbproject/project.properties
similarity index 94%
copy from ide/o.apache.commons.logging/nbproject/project.properties
copy to platform/openide.util.ui.svg/nbproject/project.properties
index 8788807..0527df9 100644
--- a/ide/o.apache.commons.logging/nbproject/project.properties
+++ b/platform/openide.util.ui.svg/nbproject/project.properties
@@ -14,5 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-is.autoload=true
-nbm.module.author=Tomas Stupka
+
+javac.source=1.6
+javac.target=1.7
diff --git a/platform/openide.util.ui/nbproject/project.xml b/platform/openide.util.ui.svg/nbproject/project.xml
similarity index 56%
copy from platform/openide.util.ui/nbproject/project.xml
copy to platform/openide.util.ui.svg/nbproject/project.xml
index 1f9c6be..d0c8838 100644
--- a/platform/openide.util.ui/nbproject/project.xml
+++ b/platform/openide.util.ui.svg/nbproject/project.xml
@@ -23,9 +23,17 @@
     <type>org.netbeans.modules.apisupport.project</type>
     <configuration>
         <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
-            <code-name-base>org.openide.util.ui</code-name-base>
+            <code-name-base>org.openide.util.ui.svg</code-name-base>
             <module-dependencies>
                 <dependency>
+                    <code-name-base>org.netbeans.libs.batik.read</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
                     <code-name-base>org.openide.util</code-name-base>
                     <build-prerequisite/>
                     <compile-dependency/>
@@ -34,6 +42,14 @@
                     </run-dependency>
                 </dependency>
                 <dependency>
+                    <code-name-base>org.openide.util.ui</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>9.14</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
                     <code-name-base>org.openide.util.lookup</code-name-base>
                     <build-prerequisite/>
                     <compile-dependency/>
@@ -42,38 +58,7 @@
                     </run-dependency>
                 </dependency>
             </module-dependencies>
-            <test-dependencies>
-                <test-type>
-                    <name>unit</name>
-                    <test-dependency>
-                        <code-name-base>org.netbeans.libs.junit4</code-name-base>
-                        <compile-dependency/>
-                    </test-dependency>
-                    <test-dependency>
-                        <code-name-base>org.netbeans.modules.nbjunit</code-name-base>
-                        <recursive/>
-                        <compile-dependency/>
-                    </test-dependency>
-                    <test-dependency>
-                        <code-name-base>org.openide.util.lookup</code-name-base>
-                        <compile-dependency/>
-                        <test/>
-                    </test-dependency>
-                    <test-dependency>
-                        <code-name-base>org.openide.util</code-name-base>
-                        <compile-dependency/>
-                        <test/>
-                    </test-dependency>
-                </test-type>
-            </test-dependencies>
-            <public-packages>
-                <package>org.openide</package>
-                <package>org.openide.util</package>
-                <package>org.openide.util.actions</package>
-                <package>org.openide.util.datatransfer</package>
-                <package>org.openide.util.io</package>
-                <package>org.openide.xml</package>
-            </public-packages>
+            <public-packages/>
         </data>
     </configuration>
 </project>
diff --git a/ide/o.apache.commons.logging/nbproject/project.properties b/platform/openide.util.ui.svg/src/org/openide/util/svg/Bundle.properties
similarity index 78%
rename from ide/o.apache.commons.logging/nbproject/project.properties
rename to platform/openide.util.ui.svg/src/org/openide/util/svg/Bundle.properties
index 8788807..5a9266d 100644
--- a/ide/o.apache.commons.logging/nbproject/project.properties
+++ b/platform/openide.util.ui.svg/src/org/openide/util/svg/Bundle.properties
@@ -14,5 +14,8 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-is.autoload=true
-nbm.module.author=Tomas Stupka
+
+OpenIDE-Module-Name=SVG Loader
+OpenIDE-Module-Short-Description=SVG Loader
+OpenIDE-Module-Long-Description=Service provider for ImageUtilities' SVGLoader interface.
+OpenIDE-Module-Display-Category=Infrastructure
diff --git a/platform/openide.util.ui.svg/src/org/openide/util/svg/SVGIcon.java b/platform/openide.util.ui.svg/src/org/openide/util/svg/SVGIcon.java
new file mode 100644
index 0000000..f6e0347
--- /dev/null
+++ b/platform/openide.util.ui.svg/src/org/openide/util/svg/SVGIcon.java
@@ -0,0 +1,209 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.openide.util.svg;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.RenderingHints;
+import java.awt.geom.Dimension2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.WeakReference;
+import java.net.URL;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.Icon;
+import org.apache.batik.anim.dom.SAXSVGDocumentFactory;
+import org.apache.batik.bridge.BridgeContext;
+import org.apache.batik.bridge.DocumentLoader;
+import org.apache.batik.bridge.GVTBuilder;
+import org.apache.batik.bridge.UserAgent;
+import org.apache.batik.bridge.UserAgentAdapter;
+import org.apache.batik.ext.awt.image.GraphicsUtil;
+import org.apache.batik.gvt.GraphicsNode;
+import org.apache.batik.util.XMLResourceDescriptor;
+import org.openide.util.CachedHiDPIIcon;
+import org.openide.util.Parameters;
+import org.w3c.dom.Document;
+
+/**
+ * An icon loaded from an SVG file resource. Renders in high resolution on HiDPI displays.
+ * Thread-safe.
+ */
+final class SVGIcon extends CachedHiDPIIcon {
+    private static final Logger LOG = Logger.getLogger(SVGIcon.class.getName());
+    /* A limit of 8192 pixels on each side means the resulting maximum image buffer would take 268
+    megabytes. It's also twice twice as long as the longest side of a 4K display. This is small
+    enough to avoid an OutOfMemoryError but large enough to cater for most SVG loading scenarios.
+    Photoshop had 10000 pixels as a maximum limit for many years. */
+    private static final int MAX_DIMENSION_PIXELS = 8192;
+    // XML document factories are expensive to initialize, so do it once per thread only.
+    private static final ThreadLocal<SAXSVGDocumentFactory> DOCUMENT_FACTORY =
+            new ThreadLocal<SAXSVGDocumentFactory>()
+    {
+        @Override
+        protected SAXSVGDocumentFactory initialValue() {
+            return new SAXSVGDocumentFactory(XMLResourceDescriptor.getXMLParserClassName());
+        }
+    };
+
+    private final URL url;
+    /**
+     * Cache of the parsed SVG document. Just painting the GraphicsNode is much faster than also
+     * re-parsing the underlying SVG file, yet we want to avoid keeping potentially complex object
+     * trees in memory for the lifetime of the Icon instance. Thus we allow the GraphicsNode to be
+     * garbage collected after the first paint. The rasterized bitmap will be cached separately by
+     * the superclass.
+     */
+    private WeakReference<GraphicsNode> graphicsNodeWeakRef;
+    /**
+     * A strong reference version of {@link #graphicsNodeWeakRef}, which can be set to ensure that
+     * the latter is not yet garbage collected. Used to ensure that the initially loaded
+     * GraphicsNode is cached at least until the first time the icon is painted. May be null.
+     */
+    private GraphicsNode graphicsNodeStrongRef;
+
+    private SVGIcon(URL url, GraphicsNode initialGraphicsNode, int width, int height) {
+        super(width, height);
+        Parameters.notNull("url", url);
+        Parameters.notNull("initialGraphicsNode", initialGraphicsNode);
+        this.url = url;
+        this.graphicsNodeStrongRef = initialGraphicsNode;
+        this.graphicsNodeWeakRef = new WeakReference<GraphicsNode>(initialGraphicsNode);
+    }
+
+    public static Icon load(URL url) throws IOException {
+        Parameters.notNull("url", url);
+        Dimension size = new Dimension();
+        GraphicsNode initialGraphicsNode = loadGraphicsNode(url, size);
+        return new SVGIcon(url, initialGraphicsNode, size.width, size.height);
+    }
+
+    /**
+     * Get the {@code GraphicsNode}, re-loading it from the original resource if a cached instance
+     * is no longer available. Once this method has been called at least once, garbage collection
+     * may cause the cache to be cleared.
+     */
+    private synchronized GraphicsNode getGraphicsNode() throws IOException {
+        GraphicsNode ret = graphicsNodeWeakRef.get();
+        if (ret != null) {
+            // Allow the GraphicsNode to be garbage collected after the initial paint.
+            graphicsNodeStrongRef = null;
+            return ret;
+        }
+        ret = loadGraphicsNode(url, null);
+        graphicsNodeWeakRef = new WeakReference<GraphicsNode>(ret);
+        return ret;
+    }
+
+    /**
+     * Load the original SVG resource.
+     *
+     * @param toSize if not null, will be set to the image's size
+     */
+    private static GraphicsNode loadGraphicsNode(URL url, Dimension toSize)
+            throws IOException
+    {
+        Parameters.notNull("url", url);
+        final GraphicsNode graphicsNode;
+        final Dimension2D documentSize;
+        final Document doc;
+        InputStream is = url.openStream();
+        try {
+            // See http://batik.2283329.n4.nabble.com/rendering-directly-to-java-awt-Graphics2D-td3716202.html
+            SAXSVGDocumentFactory factory = DOCUMENT_FACTORY.get();
+            /* Don't provide an URI here; we shouldn't commit to supporting relative links from
+            loaded SVG documents. */
+            doc = factory.createDocument(null, is);
+            UserAgent userAgent = new UserAgentAdapter();
+            DocumentLoader loader = new DocumentLoader(userAgent);
+            BridgeContext bctx = new BridgeContext(userAgent, loader);
+            try {
+                bctx.setDynamicState(BridgeContext.STATIC);
+                graphicsNode = new GVTBuilder().build(bctx, doc);
+                documentSize = bctx.getDocumentSize();
+            } finally {
+                bctx.dispose();
+            }
+        } catch (RuntimeException e) {
+            /* Rethrow the many different exceptions that can occur when parsing invalid SVG files;
+            DOMException, BridgeException etc. */
+            throw new IOException("Error parsing SVG file", e);
+        } finally {
+            is.close();
+        }
+        if (toSize != null) {
+            int width = (int) Math.ceil(documentSize.getWidth());
+            int height = (int) Math.ceil(documentSize.getHeight());
+            final int widthLimited = Math.min(MAX_DIMENSION_PIXELS, width);
+            final int heightLimited = Math.min(MAX_DIMENSION_PIXELS, height);
+            if (width != widthLimited || height != heightLimited) {
+                LOG.log(Level.WARNING,
+                        "SVG image {0} too large (dimensions were {1}x{2}, each side can be at most {3}px)",
+                        new Object[]{url, width, height, MAX_DIMENSION_PIXELS});
+            } else if (width <= 1 && height <= 1) {
+                LOG.log(Level.WARNING,
+                        "SVG image {0} did not specify a width/height, or is incorrectly sized", url);
+            }
+            toSize.width = widthLimited;
+            toSize.height = heightLimited;
+        }
+        return graphicsNode;
+    }
+
+    private static RenderingHints createHints() {
+        Map<RenderingHints.Key, Object> hints = new LinkedHashMap<RenderingHints.Key, Object>();
+        hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+        hints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+        /* Ensure that outlined strokes (strokes converted to solid shapes) appear the same as
+        regular strokes, as they do during editing in Adobe Illustrator. */
+        hints.put(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
+        return new RenderingHints(hints);
+    }
+
+    @Override
+    protected Image createAndPaintImage(
+            Component c, ColorModel colorModel, int deviceWidth, int deviceHeight, double scale)
+    {
+        BufferedImage img = createBufferedImage(colorModel, deviceWidth, deviceHeight);
+        /* Use Batik's createGraphics method to improve performance and avoid the
+        "Graphics2D from BufferedImage lacks BUFFERED_IMAGE hint" warning. */
+        final Graphics2D g = GraphicsUtil.createGraphics(img);
+        try {
+            g.scale(scale, scale);
+            try {
+                GraphicsNode graphicsNode = getGraphicsNode();
+                g.addRenderingHints(createHints());
+                graphicsNode.paint(g);
+            } catch (IOException e) {
+                LOG.log(Level.WARNING,
+                        "Unexpected exception while re-loading an SVG file that previously loaded successfully", e);
+            }
+        } finally {
+            g.dispose();
+        }
+        return img;
+    }
+}
diff --git a/platform/openide.util.ui.svg/src/org/openide/util/svg/SVGLoaderImpl.java b/platform/openide.util.ui.svg/src/org/openide/util/svg/SVGLoaderImpl.java
new file mode 100644
index 0000000..27c25ab
--- /dev/null
+++ b/platform/openide.util.ui.svg/src/org/openide/util/svg/SVGLoaderImpl.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.openide.util.svg;
+
+import java.io.IOException;
+import java.net.URL;
+import javax.swing.Icon;
+import org.openide.util.lookup.ServiceProvider;
+import org.openide.util.spi.SVGLoader;
+
+@ServiceProvider(service=SVGLoader.class)
+public class SVGLoaderImpl implements SVGLoader {
+  @Override
+  public Icon loadIcon(URL url) throws IOException {
+    return SVGIcon.load(url);
+  }
+}
diff --git a/platform/openide.util.ui/apichanges.xml b/platform/openide.util.ui/apichanges.xml
index 465346a..7505b6e 100644
--- a/platform/openide.util.ui/apichanges.xml
+++ b/platform/openide.util.ui/apichanges.xml
@@ -27,6 +27,33 @@
     <apidef name="actions">Actions API</apidef>
 </apidefs>
 <changes>
+    <change id="SVGLoader">
+      <api name="util"/>
+      <summary>Support loading of SVG icons for scalable rendering on HiDPI displays.</summary>
+      <version major="9" minor="15"/>
+      <date year="2019" month="11" day="24"/>
+      <author login="ebakke"/>
+      <compatibility addition="yes" binary="compatible" source="compatible" semantic="compatible"/>
+      <description>
+        <p>
+            As a part of the effort to make NetBeans look better on HiDPI displays, the
+            ImageUtilities class has now been completely updated to support scalable implementations
+            of the java.awt.Icon interface, and to support loading of icons and images from SVG
+            files. If an SVG file resource exists with the same base name as an existing bitmap
+            icon, the SVG file will be loaded instead (e.g. "icon.svg" will be loaded instead of
+            "icon.png"). SVG file resources can also be loaded explicitly.
+        </p>
+        <p>
+            To avoid bloating the core platform modules with large JAR libraries, the actual loading
+            and parsing of SVG files is implemented in a separate, optional module, which is lazily
+            loaded the first time that an SVG file is encountered for loading. A new interface
+            SVGLoader has been added to serve as an SPI for said module to implement. Furthermore,
+            the CachedHiDPIIcon helper class has been made public to assist in the implementation of
+            this and other scalable Icon implementations.
+        </p>
+      </description>
+      <issue number="NETBEANS-2604"/>
+    </change>
     <change id="VectorIcon">
       <api name="util"/>
       <summary>Added abstract class VectorIcon to support creation of custom-painted HiDPI icons.</summary>
diff --git a/platform/openide.util.ui/arch.xml b/platform/openide.util.ui/arch.xml
index 7203ae0..e23627c 100644
--- a/platform/openide.util.ui/arch.xml
+++ b/platform/openide.util.ui/arch.xml
@@ -51,7 +51,7 @@
  <answer id="arch-time">
   <p>
    The module has been around since 1997 and is still improved
-   from time to time.
+   from time to time. Support for HiDPI screens and SVG image loading was added in 2019.
   </p>
  </answer>
 
@@ -123,7 +123,10 @@
    a class that is looked up in <a href="@org-openide-util-lookup@/org/openide/util/Lookup.html#getDefault--">Lookup.getDefault()</a>
    and if registered can provide better UI elements for <a href="@JDK@/javax/swing/Action.html">Action</a>s.
    </api>
-   
+  </p>
+
+  <p>Support for SVG image loading can be enabled by including the optional
+     <a href="@org-openide-util-ui-svg@/overview-summary.html">SVG Loader</a> module.
   </p>
  </answer>
 
diff --git a/platform/openide.util.ui/nbproject/project.xml b/platform/openide.util.ui/nbproject/project.xml
index 1f9c6be..fa1cc44 100644
--- a/platform/openide.util.ui/nbproject/project.xml
+++ b/platform/openide.util.ui/nbproject/project.xml
@@ -69,6 +69,7 @@
             <public-packages>
                 <package>org.openide</package>
                 <package>org.openide.util</package>
+                <package>org.openide.util.spi</package>
                 <package>org.openide.util.actions</package>
                 <package>org.openide.util.datatransfer</package>
                 <package>org.openide.util.io</package>
diff --git a/platform/openide.util.ui/src/org/openide/util/CachedHiDPIIcon.java b/platform/openide.util.ui/src/org/openide/util/CachedHiDPIIcon.java
index b0bcffe..b9a0b9e 100644
--- a/platform/openide.util.ui/src/org/openide/util/CachedHiDPIIcon.java
+++ b/platform/openide.util.ui/src/org/openide/util/CachedHiDPIIcon.java
@@ -23,7 +23,10 @@ import java.awt.Graphics;
 import java.awt.Graphics2D;
 import java.awt.GraphicsConfiguration;
 import java.awt.Image;
+import java.awt.Transparency;
 import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.Map;
@@ -35,7 +38,7 @@ import javax.swing.Icon;
  * representations for HiDPI displays. Bitmaps for multiple HiDPI scaling factors can be cached at
  * the same time, e.g. for multi-monitor setups. Thread-safe.
  */
-abstract class CachedHiDPIIcon implements Icon {
+public abstract class CachedHiDPIIcon implements Icon {
     /**
      * The maximum size of the cache, as a multiple of the size of the icon at 100% scaling. For
      * example, storing three images at 100%, 150%, and 200% scaling, respectively, yields a total
@@ -56,7 +59,11 @@ abstract class CachedHiDPIIcon implements Icon {
     private double cacheSize = 0.0;
 
     /**
-     * Constructor to be used by subclasses.
+     * Constructor to be used by subclasses. For HiDPI screens, dimensions are specified in logical
+     * pixels rather than device pixels, as in the superclass.
+     *
+     * @param width the width of the icon
+     * @param height the height of the icon
      */
     protected CachedHiDPIIcon(int width, int height) {
         if (width < 0) {
@@ -78,7 +85,7 @@ abstract class CachedHiDPIIcon implements Icon {
         final int deviceWidth = (int) Math.ceil(getIconWidth() * scale);
         final int deviceHeight = (int) Math.ceil(getIconHeight() * scale);
         final Image img =
-                createImage(c, key.getGraphicsConfiguration(), deviceWidth, deviceHeight, scale);
+                createAndPaintImage(c, key.getColorModel(), deviceWidth, deviceHeight, scale);
         final double imgSize = key.getSize();
         if (imgSize <= MAX_CACHE_SIZE) {
             /* Evict least-recently-used images from the cache until we have space for the latest
@@ -133,7 +140,9 @@ abstract class CachedHiDPIIcon implements Icon {
     }
 
     /**
-     * Create a scaled image containing the graphics of this icon. The result may be cached.
+     * Create a scaled image containing the graphics of this icon. The result may be cached. The
+     * dimensions are specfied in device pixels rather than logical pixels, i.e. with HiDPI scaling
+     * applied.
      *
      * @param c the component that was passed to {@link Icon#paintIcon(Component,Graphics,int,int)}.
      *        The cache will <em>not</em> be invalidated if {@code c} or its state changes, so 
@@ -141,25 +150,51 @@ abstract class CachedHiDPIIcon implements Icon {
      *        ensure compatibility with existing Icon implementations that may be used as delegates.
      *        Future implementations might also elect to simply pass a dummy Component instance
      *        here.
-     * @param graphicsConfiguration the configuration of the surface on which the image will be
-     *        painted
-     * @param deviceWidth the required width of the image, with scaling already applied
-     * @param deviceHeight the required height of the image, with scaling already applied
+     * @param colorModel the {@link ColorModel} of the surface on which the image will be painted
+     *        (may be passed to {@link #createBufferedImage(ColorModel, int, int)} in the common
+     *        case)
+     * @param deviceWidth the required width of the image, in device pixels
+     * @param deviceHeight the required height of the image, in device pixels
      * @param scale the HiDPI scaling factor detected in {@code graphicsConfiguration}
      */
-    protected abstract Image createImage(Component c, GraphicsConfiguration graphicsConfiguration,
+    protected abstract Image createAndPaintImage(Component c, ColorModel colorModel,
             int deviceWidth, int deviceHeight, double scale);
 
+    /**
+     * Utility method to create a compatible {@link BufferedImage} from the parameters passed to
+     * {@link #createAndPaintImage(Component, ColorModel, int, int, double)}. May be called by
+     * implementors of the latter to create a surface to draw on and return.
+     *
+     * @param colorModel the required {@link ColorModel}
+     * @param deviceWidth the required width of the image, in device pixels
+     * @param deviceHeight the required height of the image, in device pixels
+     * @return an image compatible with the given parameters
+     */
+    protected static final BufferedImage createBufferedImage(
+            ColorModel colorModel, int deviceWidth, int deviceHeight)
+    {
+      return new BufferedImage(
+          colorModel,
+          colorModel.createCompatibleWritableRaster(deviceWidth, deviceHeight),
+          colorModel.isAlphaPremultiplied(), null);
+    }
+
+    /**
+     * Key for image cache map. Immutable.
+     */
     private static final class CachedImageKey {
-        private final GraphicsConfiguration gconf;
+        /* The ColorModel is the only field in GraphicsConfiguration that is needed to create a
+        compatible BufferedImage. So include only that one, plus the HiDPI scaling factor, in the
+        cache key. */
+        private final ColorModel colorModel;
         private final double scale;
 
-        public CachedImageKey(GraphicsConfiguration gconf, double scale) {
-            Parameters.notNull("gconf", gconf);
+        private CachedImageKey(ColorModel colorModel, double scale) {
+            Parameters.notNull("colorModel", colorModel);
             if (scale <= 0.0) {
                 throw new IllegalArgumentException();
             }
-            this.gconf = gconf;
+            this.colorModel = colorModel;
             this.scale = scale;
         }
 
@@ -174,7 +209,12 @@ abstract class CachedHiDPIIcon implements Icon {
             } else {
                 scale = 1.0;
             }
-            return new CachedImageKey(g.getDeviceConfiguration(), scale);
+            GraphicsConfiguration gconf = g.getDeviceConfiguration();
+            /* Always use the same transparency mode for the cached images, so we don't end up with
+            one set of cached images for each encountered mode. The TRANSLUCENT mode is the most
+            generic one; presumably it should paint OK onto less capable surfaces. */
+            ColorModel colorModel = gconf.getColorModel(Transparency.TRANSLUCENT);
+            return new CachedImageKey(colorModel, scale);
         }
 
         public double getScale() {
@@ -188,13 +228,13 @@ abstract class CachedHiDPIIcon implements Icon {
             return Math.pow(getScale(), 2.0);
         }
 
-        public GraphicsConfiguration getGraphicsConfiguration() {
-            return gconf;
+        public ColorModel getColorModel() {
+            return colorModel;
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(gconf, scale);
+            return Objects.hash(colorModel, scale);
         }
 
         @Override
@@ -203,8 +243,13 @@ abstract class CachedHiDPIIcon implements Icon {
                 return false;
             }
             final CachedImageKey other = (CachedImageKey) obj;
-            return this.gconf.equals(other.gconf) &&
+            return this.colorModel.equals(other.colorModel) &&
                    this.scale == other.scale;
         }
+
+        @Override
+        public String toString() {
+            return "CachedImageKey(" + colorModel + ", " + scale + ")";
+        }
     }
 }
diff --git a/platform/openide.util.ui/src/org/openide/util/FilteredIcon.java b/platform/openide.util.ui/src/org/openide/util/FilteredIcon.java
index 0496c3b..6e0c52c 100644
--- a/platform/openide.util.ui/src/org/openide/util/FilteredIcon.java
+++ b/platform/openide.util.ui/src/org/openide/util/FilteredIcon.java
@@ -21,12 +21,11 @@ package org.openide.util;
 import java.awt.Component;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
-import java.awt.GraphicsConfiguration;
 import java.awt.Image;
 import java.awt.Rectangle;
 import java.awt.Toolkit;
-import java.awt.Transparency;
 import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
 import java.awt.image.FilteredImageSource;
 import java.awt.image.RGBImageFilter;
 import javax.swing.Icon;
@@ -59,12 +58,10 @@ final class FilteredIcon extends CachedHiDPIIcon {
     }
 
     @Override
-    protected Image createImage(
-            Component c, GraphicsConfiguration graphicsConfiguration,
-            int deviceWidth, int deviceHeight, double scale)
+    protected Image createAndPaintImage(
+            Component c, ColorModel colorModel, int deviceWidth, int deviceHeight, double scale)
     {
-        final BufferedImage img = graphicsConfiguration.createCompatibleImage(
-                deviceWidth, deviceHeight, Transparency.TRANSLUCENT);
+        final BufferedImage img = createBufferedImage(colorModel, deviceWidth, deviceHeight);
         final Graphics2D imgG = img.createGraphics();
         try {
             imgG.clip(new Rectangle(0, 0, img.getWidth(), img.getHeight()));
diff --git a/platform/openide.util.ui/src/org/openide/util/ImageUtilities.java b/platform/openide.util.ui/src/org/openide/util/ImageUtilities.java
index 4af5cc8..e9d90b1 100644
--- a/platform/openide.util.ui/src/org/openide/util/ImageUtilities.java
+++ b/platform/openide.util.ui/src/org/openide/util/ImageUtilities.java
@@ -23,7 +23,6 @@ import java.awt.Component;
 import java.awt.EventQueue;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
-import java.awt.GraphicsConfiguration;
 import java.awt.HeadlessException;
 import java.awt.Image;
 import java.awt.MediaTracker;
@@ -45,7 +44,9 @@ import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import javax.imageio.ImageIO;
@@ -57,6 +58,7 @@ import javax.swing.ImageIcon;
 import javax.swing.JLabel;
 import javax.swing.SwingUtilities;
 import javax.swing.UIManager;
+import org.openide.util.spi.SVGLoader;
 
 /** 
  * Useful static methods for manipulation with images/icons, results are cached.
@@ -91,9 +93,10 @@ public final class ImageUtilities {
      * @see "#20072"
      */
     private static final Set<String> extraInitialSlashes = new HashSet<String>();
-    private static volatile Object currentLoader;
-    private static Lookup.Result<ClassLoader> loaderQuery = null;
-    private static boolean noLoaderWarned = false;
+    private static final CachedLookupLoader<ClassLoader> classLoaderLoader =
+            new CachedLookupLoader<ClassLoader>(ClassLoader.class);
+    private static final CachedLookupLoader<SVGLoader> svgLoaderLoader =
+            new CachedLookupLoader<SVGLoader>(SVGLoader.class);
     private static final Component component = new Component() {
     };
 
@@ -101,7 +104,6 @@ public final class ImageUtilities {
     private static int mediaTrackerID;
     
     private static ImageReader PNG_READER;
-//    private static ImageReader GIF_READER;
     
     private static final Logger ERR = Logger.getLogger(ImageUtilities.class.getName());
     
@@ -110,7 +112,7 @@ public final class ImageUtilities {
     /**
      * Dummy component to be passed to the first parameter  of
      * {@link Icon#paintIcon(Component, Graphics, int, int)} when converting an {@code Icon} to an
-     * {@code Image}. See comment in {@link #icon2ToolTipImage(Icon)}.
+     * {@code Image}. See comment in {@link #icon2ToolTipImage(Icon, URL)}.
      */
     private static volatile Component dummyIconComponent;
 
@@ -135,12 +137,25 @@ public final class ImageUtilities {
     static {
         ImageIO.setUseCache(false);
         PNG_READER = ImageIO.getImageReadersByMIMEType("image/png").next();
-//        GIF_READER = ImageIO.getImageReadersByMIMEType("image/gif").next();
     }
 
     /**
      * Loads an image from the specified resource ID. The image is loaded using the "system" classloader registered in
      * Lookup.
+     *
+     * <p>If the default lookup contains a service provider for the {@link SVGLoader} interface, and
+     * there exists an SVG version of the requested image (e.g. "icon.svg" exists when "icon.png"
+     * was requested), the SVG version will be loaded instead of the originally requested bitmap.
+     * SVG images can also be requested directly. The SVG document's root element must contain
+     * explicit width/height attributes. An SVG loader implementation can be installed via the
+     * optional {@code openide.util.ui.svg} module.
+     *
+     * <p>To paint SVG images at arbitrary resolutions, convert the returned {@link Image} to an
+     * {@link Icon} using {@link #image2Icon(Image)}, and set an appropriate transform on the
+     * {@link Graphics2D} instance passed to {@link Icon#paintIcon(Component, Graphics, int, int)}.
+     * When painting on HiDPI-capable {@code Graphics2D} instances provided by Swing, the
+     * appropriate transform will already be in place.
+     *
      * @param resourceID resource path of the icon (no initial slash)
      * @return icon's Image, or null, if the icon cannot be loaded.     
      */
@@ -191,7 +206,7 @@ public final class ImageUtilities {
             // only non _dark images need filtering
             RGBImageFilter imageFilter = getImageIconFilter();
             if (null != image && null != imageFilter) {
-                image = icon2ToolTipImage(FilteredIcon.create(imageFilter, image));
+                image = icon2ToolTipImage(FilteredIcon.create(imageFilter, image), image.url);
             }
         }
         return image;
@@ -315,15 +330,18 @@ public final class ImageUtilities {
             if (ret != null)
                 return ret;
         }
-        return icon2ToolTipImage(icon);
+        return icon2ToolTipImage(icon, null);
     }
 
-    private static ToolTipImage icon2ToolTipImage(Icon icon) {
+    /**
+     * @param url may be null
+     */
+    private static ToolTipImage icon2ToolTipImage(Icon icon, URL url) {
         Parameters.notNull("icon", icon);
         if (icon instanceof ToolTipImage) {
             return (ToolTipImage) icon;
         }
-        ToolTipImage image = new ToolTipImage(icon, "", BufferedImage.TYPE_INT_ARGB);
+        ToolTipImage image = new ToolTipImage(icon, "", url, BufferedImage.TYPE_INT_ARGB);
         Graphics g = image.getGraphics();
         /* Previously, we'd create a new JLabel here every time; this once led to a deadlock on
         startup when the nb.imageicon.filter setting was enabled. The underlying problem is that
@@ -428,47 +446,107 @@ public final class ImageUtilities {
     }
 
     /**
+     * Get an SVG icon loader, if the appropriate service provider module is installed. To ensure
+     * lazy loading of the SVG loader module, this method should only be called when there actually
+     * exists an SVG file to load. The result is cached.
+     *
+     * @return may be null
+     */
+    private static SVGLoader getSVGLoader() {
+        /* "Objects contained in the default lookup are instantiated lazily when first requested."
+        ( http://wiki.netbeans.org/DevFaqLookupDefault ) So the SVGLoader implementation module will
+        only be loaded the first time an SVG file is actually encountered for loading, rather than,
+        for instance, when the startup splash screen initializes ImageUtilities to load its PNG
+        image. This was confirmed by printing a debugging message from a static initializer in
+        SVGLoaderImpl in the implementation module; the message appears well after the splash
+        screen's PNG graphics first becomes visible. */
+        return svgLoaderLoader.getLoader();
+    }
+
+    /**
      * Get the class loader from lookup.
      * Since this is done very frequently, it is wasteful to query lookup each time.
      * Instead, remember the last result and just listen for changes.
      */
-    static ClassLoader getLoader() {
-        Object is = currentLoader;
-        if (is instanceof ClassLoader) {
-            return (ClassLoader)is;
-        }
-            
-        currentLoader = Thread.currentThread();
-            
-        if (loaderQuery == null) {
-            loaderQuery = Lookup.getDefault().lookup(new Lookup.Template<ClassLoader>(ClassLoader.class));
-            loaderQuery.addLookupListener(
-                new LookupListener() {
-                    public void resultChanged(LookupEvent ev) {
-                        ERR.fine("Loader cleared"); // NOI18N
-                        currentLoader = null;
-                    }
-                }
-            );
+    static ClassLoader getClassLoader() {
+        return classLoaderLoader.getLoader();
+    }
+
+    private static final class CachedLookupLoader<T> {
+        private final Class<T> clazz;
+        private final AtomicBoolean noLoaderWarned = new AtomicBoolean(false);
+        /**
+         * Cached result of {@link #getLoader()}. Null means the cache is cleared; absent means the
+         * result is cached but was null (no loader found). This field is marked volatile so that it
+         * can be retrieved without synchronization in the common case, like in prior versions.
+         */
+        private volatile Optional<T> currentLoader;
+        /**
+         * The thread which last started performing an uncached lookup, when said lookup is
+         * currently in progress. The result of an uncached lookup will only be cached if
+         * (1) LookupListener.resultChanged was _not_ called while the lookup was being performed
+         * and (2) no other uncached lookups were started more recently. This is slightly cleaned-up
+         * version of the fix for an old race condition bug (#62194 in BugZilla).
+         */
+        private Thread threadInProgress;
+        private Lookup.Result<T> loaderQuery;
+
+        public CachedLookupLoader(Class<T> clazz) {
+            Parameters.notNull("clazz", clazz);
+            this.clazz = clazz;
         }
 
-        Iterator it = loaderQuery.allInstances().iterator();
-        if (it.hasNext()) {
-            ClassLoader toReturn = (ClassLoader) it.next();
-            if (currentLoader == Thread.currentThread()) {
-                currentLoader = toReturn;
+        public T getLoader() {
+            Optional<T> toReturn = currentLoader;
+            if (toReturn != null) {
+                return toReturn.orElse(null);
             }
-            if (ERR.isLoggable(Level.FINE)) {
-                ERR.fine("Loader computed: " + currentLoader); // NOI18N
+            final Lookup.Result<T> useLoaderQuery;
+            synchronized (this) {
+                // Signal to other threads that their result is outdated.
+                threadInProgress = Thread.currentThread();
+                if (loaderQuery == null) {
+                    loaderQuery = Lookup.getDefault().lookupResult(clazz);
+                    loaderQuery.addLookupListener(
+                        new LookupListener() {
+                            @Override
+                            public void resultChanged(LookupEvent ev) {
+                                ERR.log(Level.FINE, "Loader for {0} cleared", clazz); // NOI18N
+                                /* Clear any existing cached result, and indicate to ongoing lookup
+                                operations in other threads that their results are outdated and
+                                should not be cahced. */
+                                synchronized (CachedLookupLoader.this) {
+                                    currentLoader = null;
+                                    threadInProgress = null;
+                                }
+                            }
+                        }
+                    );
+                }
+                useLoaderQuery = loaderQuery;
             }
-            return toReturn;
-        } else { if (!noLoaderWarned) {
-                noLoaderWarned = true;
-                ERR.warning(
-                    "No ClassLoader instance found in " + Lookup.getDefault() // NOI18N
-                );
+            Iterator it = useLoaderQuery.allInstances().iterator();
+            toReturn = Optional.ofNullable(it.hasNext() ? (T) it.next() : null);
+            if (!toReturn.isPresent()) {
+                if (!noLoaderWarned.getAndSet(true)) {
+                    ERR.log(Level.WARNING, "No {0} instance found in {1}", // NOI18N
+                            new Object[]{ clazz, Lookup.getDefault() });
+                }
+            } else if (ERR.isLoggable(Level.FINE)) {
+                // Log message must start with "Loader computed", per ImageUtilitiesGetLoaderTest.
+                ERR.log(Level.FINE, "Loader computed for {0}: {1}", // NOI18N
+                        new Object[]{ clazz, toReturn.orElse(null) });
             }
-            return null;
+            synchronized (this) {
+                if (threadInProgress == Thread.currentThread()) {
+                    /* We're the last thread to have started performing a lookup, and the result has
+                    not been invalidated since after we started the operation, so we can safely
+                    cache the result. */
+                    threadInProgress = null;
+                    currentLoader = toReturn;
+                }
+            }
+            return toReturn.orElse(null);
         }
     }
 
@@ -497,7 +575,7 @@ public final class ImageUtilities {
                 }
 
                 // find localized or base image
-                ClassLoader loader = getLoader();
+                ClassLoader loader = getClassLoader();
 
                 // we'll keep the String probably for long time, optimize it
                 resource = new String(resource).intern(); // NOPMD
@@ -538,7 +616,7 @@ public final class ImageUtilities {
                 return null;
             }
         } else {
-            return getIcon(resource, getLoader(), false);
+            return getIcon(resource, getClassLoader(), false);
         }
     }
 
@@ -600,15 +678,39 @@ public final class ImageUtilities {
                 n = name;
             }
 
-            // we have to load it
-            java.net.URL url = (loader != null) ? loader.getResource(n)
-                                                : ImageUtilities.class.getClassLoader().getResource(n);
+            // Load the icon.
+            SVGLoader svgLoader = null; // If not null, url should be loaded as an SVG file.
+            ClassLoader useClassLoader =
+                    (loader != null) ? loader : ImageUtilities.class.getClassLoader();
+            java.net.URL url = null;
+            if (n.endsWith(".png") || n.endsWith(".gif") || n.endsWith(".svg")) {
+                /* If an SVG version of the image is available, always load that one. Only attempt
+                to load the SVGLoader implementation module if an actual SVG file exists. */
+                URL svgURL = useClassLoader.getResource(n.substring(0, n.length() - 4) + ".svg");
+                if (svgURL != null) {
+                    svgLoader = getSVGLoader();
+                    if (svgLoader != null) {
+                        url = svgURL;
+                    } else {
+                        ERR.log(Level.INFO, "No SVG loader available for loading {0}", svgURL);
+                    }
+                }
+            }
+            if (url == null && !n.endsWith(".svg")) { // The SVG case was handled before.
+                url = useClassLoader.getResource(n);
+            }
 
 //            img = (url == null) ? null : Toolkit.getDefaultToolkit().createImage(url);
             Image result = null;
             try {
                 if (url != null) {
-                    if (name.endsWith(".png")) {
+                    if (svgLoader != null) {
+                        try {
+                            result = icon2ToolTipImage(svgLoader.loadIcon(url), url);
+                        } catch (IOException e) {
+                            ERR.log(Level.INFO, "Failed to load SVG image " + url, e);
+                        }
+                    } else if (name.endsWith(".png")) {
                         ImageInputStream stream = ImageIO.createImageInputStream(url.openStream());
                         ImageReadParam param = PNG_READER.getDefaultReadParam();
                         try {
@@ -620,20 +722,6 @@ public final class ImageUtilities {
                         }
                         stream.close();
                     } 
-                    /*
-                    else if (name.endsWith(".gif")) {
-                        ImageInputStream stream = ImageIO.createImageInputStream(url.openStream());
-                        ImageReadParam param = GIF_READER.getDefaultReadParam();
-                        try {
-                            GIF_READER.setInput(stream, true, true);
-                            result = GIF_READER.read(0, param);
-                        }
-                        catch (IOException ioe1) {
-                            ERR.log(Level.INFO, "Image "+name+" is not GIF", ioe1);
-                        }
-                        stream.close();
-                    }
-                     */
 
                     if (result == null) {
                         result = ImageIO.read(url);
@@ -657,7 +745,9 @@ public final class ImageUtilities {
                     ERR.log(Level.FINE, "loading icon {0} = {1}", new Object[] {n, result});
                 }
                 name = new String(name).intern(); // NOPMD
-                ToolTipImage toolTipImage = ToolTipImage.createNew("", result, url);
+                ToolTipImage toolTipImage = (result instanceof ToolTipImage)
+                        ? (ToolTipImage) result
+                        : ToolTipImage.createNew("", result, url);
                 cache.put(name, new ActiveRef<String>(toolTipImage, cache, name));
                 return toolTipImage;
             } else { // no icon found
@@ -669,10 +759,11 @@ public final class ImageUtilities {
         }
     }
 
+    // Note: No longer in use.
     /** The method creates a BufferedImage which represents the same Image as the
      * parameter but consumes less memory.
      */
-    static final Image toBufferedImage(Image img) {
+    private static final Image toBufferedImage(Image img) {
         // load the image
         new javax.swing.ImageIcon(img, "");
 
@@ -766,11 +857,10 @@ public final class ImageUtilities {
         }
 
         @Override
-        protected Image createImage(Component c, GraphicsConfiguration graphicsConfiguration,
-                int deviceWidth, int deviceHeight, double scale)
+        protected Image createAndPaintImage(
+                Component c, ColorModel colorModel, int deviceWidth, int deviceHeight, double scale)
         {
-            BufferedImage ret = graphicsConfiguration.createCompatibleImage(
-                    deviceWidth, deviceHeight, Transparency.TRANSLUCENT);
+            BufferedImage ret = createBufferedImage(colorModel, deviceWidth, deviceHeight);
             Graphics2D g = ret.createGraphics();
             try {
                 g.clip(new Rectangle(0, 0, deviceWidth, deviceHeight));
@@ -941,6 +1031,7 @@ public final class ImageUtilities {
         final String toolTipText;
         // May be null.
         final Icon delegateIcon;
+        // May be null.
         final URL url;
         // May be null.
         ImageIcon imageIconVersion;
@@ -987,13 +1078,16 @@ public final class ImageUtilities {
           return imageIconVersion;
         }
 
-        public ToolTipImage(Icon delegateIcon, String toolTipText, int imageType) {
+        /**
+         * @param url may be null
+         */
+        public ToolTipImage(Icon delegateIcon, String toolTipText, URL url, int imageType) {
             // BufferedImage must have width/height > 0.
             super(Math.max(1, delegateIcon.getIconWidth()),
                     Math.max(1, delegateIcon.getIconHeight()), imageType);
             this.delegateIcon = delegateIcon;
             this.toolTipText = toolTipText;
-            this.url = null;
+            this.url = url;
         }
 
         /**
diff --git a/platform/openide.util.ui/src/org/openide/util/spi/SVGLoader.java b/platform/openide.util.ui/src/org/openide/util/spi/SVGLoader.java
new file mode 100644
index 0000000..09608f0
--- /dev/null
+++ b/platform/openide.util.ui/src/org/openide/util/spi/SVGLoader.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.openide.util.spi;
+
+import java.io.IOException;
+import java.net.URL;
+import javax.swing.Icon;
+import org.openide.util.lookup.ServiceProvider;
+
+/**
+ * SVG image loader. This is an optional service provider. If implemented, a single instance should
+ * be placed in the default lookup (e.g. via the {@link ServiceProvider} annotation).
+ */
+public interface SVGLoader {
+    /**
+     * Load an SVG image as an {@link Icon}. The SVG document's root element must contain explicit
+     * width/height attributes.
+     *
+     * @param url may not be null
+     * @return may not be null
+     * @throws IOException in case of loading or parsing errors
+     */
+    public Icon loadIcon(URL url) throws IOException;
+}
diff --git a/platform/openide.util.ui/test/unit/src/org/openide/util/ImageUtilitiesGetLoaderTest.java b/platform/openide.util.ui/test/unit/src/org/openide/util/ImageUtilitiesGetLoaderTest.java
index 4353714..ae163a1 100644
--- a/platform/openide.util.ui/test/unit/src/org/openide/util/ImageUtilitiesGetLoaderTest.java
+++ b/platform/openide.util.ui/test/unit/src/org/openide/util/ImageUtilitiesGetLoaderTest.java
@@ -54,11 +54,11 @@ public class ImageUtilitiesGetLoaderTest extends TestCase {
     }
 
     public void testWrongImplOfGetLoaderIssue62194() throws Exception {
-        ClassLoader l = ImageUtilities.getLoader ();
+        ClassLoader l = ImageUtilities.getClassLoader ();
         assertTrue("Error manager race condition activated", ErrMgr.switchDone);
         assertEquals("c1 the original one", Lkp.c1, l);
         
-        ClassLoader n = ImageUtilities.getLoader ();
+        ClassLoader n = ImageUtilities.getClassLoader ();
         assertEquals("c2 the new one", Lkp.c2, n);
     }
     
diff --git a/webcommon/javascript.nodejs/src/org/netbeans/modules/javascript/nodejs/ui/resources/npm.svg b/webcommon/javascript.nodejs/src/org/netbeans/modules/javascript/nodejs/ui/resources/npm.svg
index b350d68..310d12e 100644
--- a/webcommon/javascript.nodejs/src/org/netbeans/modules/javascript/nodejs/ui/resources/npm.svg
+++ b/webcommon/javascript.nodejs/src/org/netbeans/modules/javascript/nodejs/ui/resources/npm.svg
@@ -28,4 +28,4 @@
 - the file was opened, color was modified to #CC3534 and saved with NetBeans
 - color was taken from here: https://www.schemecolor.com/npm-logo-colors.php
 -->
-<svg role="img" viewBox="0 0 24 24" fill="#CC3534" xmlns="http://www.w3.org/2000/svg"><title>NPM icon</title><path d="M0 7.334v8h6.666v1.332H12v-1.332h12v-8H0zm6.666 6.664H5.334v-4H3.999v4H1.335V8.667h5.331v5.331zm4 0v1.336H8.001V8.667h5.334v5.332h-2.669v-.001zm12.001 0h-1.33v-4h-1.336v4h-1.335v-4h-1.33v4h-2.671V8.667h8.002v5.331zM10.665 10H12v2.667h-1.335V10z"/></svg>
\ No newline at end of file
+<svg role="img" viewBox="0 0 24 24" width="24" height="24" fill="#CC3534" xmlns="http://www.w3.org/2000/svg"><title>NPM icon</title><path d="M0 7.334v8h6.666v1.332H12v-1.332h12v-8H0zm6.666 6.664H5.334v-4H3.999v4H1.335V8.667h5.331v5.331zm4 0v1.336H8.001V8.667h5.334v5.332h-2.669v-.001zm12.001 0h-1.33v-4h-1.336v4h-1.335v-4h-1.33v4h-2.671V8.667h8.002v5.331zM10.665 10H12v2.667h-1.335V10z"/></svg>


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists