Index: trunk/src/org/openstreetmap/josm/gui/ExtendedDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/ExtendedDialog.java	(revision 6220)
+++ trunk/src/org/openstreetmap/josm/gui/ExtendedDialog.java	(revision 6221)
@@ -37,4 +37,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Utils;
 import org.openstreetmap.josm.tools.WindowGeometry;
 
@@ -132,16 +133,18 @@
     /**
      * Same as above but lets you define if the dialog should be modal.
-     */
-    public ExtendedDialog(Component parent, String title, String[] buttonTexts,
-            boolean modal) {
+     * @param parent The parent element that will be used for position and maximum size
+     * @param title The text that will be shown in the window titlebar
+     * @param buttonTexts String Array of the text that will appear on the buttons. The first button is the default one.
+     * @param modal Set it to {@code true} if you want the dialog to be modal
+     */
+    public ExtendedDialog(Component parent, String title, String[] buttonTexts, boolean modal) {
         this(parent, title, buttonTexts, modal, true);
     }
 
-    public ExtendedDialog(Component parent, String title, String[] buttonTexts,
-            boolean modal, boolean disposeOnClose) {
+    public ExtendedDialog(Component parent, String title, String[] buttonTexts, boolean modal, boolean disposeOnClose) {
         super(JOptionPane.getFrameForComponent(parent), title, modal ? ModalityType.DOCUMENT_MODAL : ModalityType.MODELESS);
         this.parent = parent;
         this.modal = modal;
-        bTexts = buttonTexts;
+        bTexts = Utils.copyArray(buttonTexts);
         if (disposeOnClose) {
             setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
@@ -152,8 +155,9 @@
     /**
      * Allows decorating the buttons with icons.
-     * @param buttonIcons
+     * @param buttonIcons The button icons
+     * @return {@code this}
      */
     public ExtendedDialog setButtonIcons(Icon[] buttonIcons) {
-        this.bIcons = buttonIcons;
+        this.bIcons = Utils.copyArray(buttonIcons);
         return this;
     }
@@ -161,4 +165,6 @@
     /**
      * Convenience method to provide image names instead of images.
+     * @param buttonIcons The button icon names
+     * @return {@code this}
      */
     public ExtendedDialog setButtonIcons(String[] buttonIcons) {
@@ -175,7 +181,8 @@
      *
      * @param toolTipTexts the tool tip texts. Ignored, if null.
+     * @return {@code this}
      */
     public ExtendedDialog setToolTipTexts(String[] toolTipTexts) {
-        this.bToolTipTexts = toolTipTexts;
+        this.bToolTipTexts = Utils.copyArray(toolTipTexts);
         return this;
     }
@@ -188,4 +195,5 @@
      *
      * @param content Any element that can be displayed in the message dialog
+     * @return {@code this}
      */
     public ExtendedDialog setContent(Component content) {
@@ -201,5 +209,5 @@
      * @param content Any element that can be displayed in the message dialog
      * @param placeContentInScrollPane if  true, places  the content in a JScrollPane
-     *
+     * @return {@code this}
      */
     public ExtendedDialog setContent(Component content, boolean placeContentInScrollPane) {
@@ -217,4 +225,5 @@
      *
      * @param message The text that should be shown to the user
+     * @return {@code this}
      */
     public ExtendedDialog setContent(String message) {
@@ -225,4 +234,6 @@
      * Decorate the dialog with an icon that is shown on the left part of
      * the window area. (Similar to how it is done in {@link JOptionPane})
+     * @param icon The icon to display
+     * @return {@code this}
      */
     public ExtendedDialog setIcon(Icon icon) {
@@ -233,4 +244,6 @@
     /**
      * Convenience method to allow values that would be accepted by {@link JOptionPane} as messageType.
+     * @param messageType The {@link JOptionPane} messageType
+     * @return {@code this}
      */
     public ExtendedDialog setIcon(int messageType) {
@@ -254,4 +267,5 @@
      * Show the dialog to the user. Call this after you have set all options
      * for the dialog. You can retrieve the result using {@link #getValue()}.
+     * @return {@code this}
      */
     public ExtendedDialog showDialog() {
@@ -493,5 +507,5 @@
      *              existing preference is found (only takes effect if
      *              <code>pref</code> is not null or empty
-     *
+     * @return {@code this}
      */
     public ExtendedDialog setRememberWindowGeometry(String pref, WindowGeometry wg) {
@@ -507,4 +521,5 @@
      * Currently, this is not supported for non-modal dialogs.
      * @param togglePref  The preference to save the checkbox state to
+     * @return {@code this}
      */
     public ExtendedDialog toggleEnable(String togglePref) {
@@ -520,4 +535,5 @@
      * Call this if you "accidentally" called toggleEnable. This doesn't need
      * to be called for every dialog, as it's the default anyway.
+     * @return {@code this}
      */
     public ExtendedDialog toggleDisable() {
@@ -530,5 +546,6 @@
      * if you want to give more information. Only has an effect if
      * <code>toggleEnable</code> is set.
-     * @param text
+     * @param text The toggle checkbox text
+     * @return {@code this}
      */
     public ExtendedDialog setToggleCheckboxText(String text) {
@@ -539,4 +556,6 @@
     /**
      * Sets the button that will react to ENTER.
+     * @param defaultButtonIdx The button index (starts to )
+     * @return {@code this}
      */
     public ExtendedDialog setDefaultButton(int defaultButtonIdx) {
@@ -549,4 +568,5 @@
      * If the user presses 'cancel' the toggle settings are ignored and not saved to the pref
      * @param cancelButtonIdx index of the button that stands for cancel, accepts multiple values
+     * @return {@code this}
      */
     public ExtendedDialog setCancelButton(Integer... cancelButtonIdx) {
@@ -623,4 +643,5 @@
      * @param helpTopic the help topic
      * @param showHelpButton true, if the dialog displays a help button
+     * @return {@code this}
      */
     public ExtendedDialog configureContextsensitiveHelp(String helpTopic, boolean showHelpButton) {
Index: trunk/src/org/openstreetmap/josm/gui/FileDrop.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/FileDrop.java	(revision 6220)
+++ trunk/src/org/openstreetmap/josm/gui/FileDrop.java	(revision 6221)
@@ -24,5 +24,4 @@
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.EventObject;
 import java.util.List;
 import java.util.TooManyListenersException;
@@ -474,47 +473,4 @@
 
     /**
-     * This is the event that is passed to the
-     * {@link FileDrop.Listener#filesDropped filesDropped(...)} method in
-     * your {@link FileDrop.Listener} when files are dropped onto
-     * a registered drop target.
-     *
-     * <p>I'm releasing this code into the Public Domain. Enjoy.</p>
-     *
-     * @author  Robert Harder
-     * @author  rob@iharder.net
-     * @version 1.2
-     */
-    public static class Event extends EventObject {
-
-        private File[] files;
-
-        /**
-         * Constructs an {@link Event} with the array
-         * of files that were dropped and the
-         * {@link FileDrop} that initiated the event.
-         *
-         * @param files The array of files that were dropped
-         * @param source The event source
-         */
-        public Event( File[] files, Object source ) {
-            super( source );
-            this.files = files;
-        }   // end constructor
-
-        /**
-         * Returns an array of files that were dropped on a
-         * registered drop target.
-         *
-         * @return array of files that were dropped
-         */
-        public File[] getFiles() {
-            return files;
-        }   // end getFiles
-
-    }   // end inner class Event
-
-    /* ********  I N N E R   C L A S S  ******** */
-
-    /**
      * At last an easy way to encapsulate your custom objects for dragging and dropping
      * in your Java programs!
Index: trunk/src/org/openstreetmap/josm/gui/MainApplication.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MainApplication.java	(revision 6220)
+++ trunk/src/org/openstreetmap/josm/gui/MainApplication.java	(revision 6221)
@@ -4,4 +4,6 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 import static org.openstreetmap.josm.tools.I18n.trn;
+import gnu.getopt.Getopt;
+import gnu.getopt.LongOpt;
 
 import java.awt.Image;
@@ -28,7 +30,4 @@
 import javax.swing.RepaintManager;
 import javax.swing.SwingUtilities;
-
-import gnu.getopt.Getopt;
-import gnu.getopt.LongOpt;
 
 import org.jdesktop.swinghelper.debug.CheckThreadViolationRepaintManager;
@@ -301,5 +300,5 @@
         Main.platform.preStartupHook();
 
-        Main.commandLineArgs = argArray;
+        Main.commandLineArgs = Utils.copyArray(argArray);
         
         if (args.containsKey(Option.VERSION)) {
Index: trunk/src/org/openstreetmap/josm/gui/QuadStateCheckBox.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/QuadStateCheckBox.java	(revision 6220)
+++ 	(revision )
@@ -1,188 +1,0 @@
-// License: GPL. Copyright 2008 by Frederik Ramm and others
-package org.openstreetmap.josm.gui;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.ItemListener;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-
-import javax.swing.AbstractAction;
-import javax.swing.ActionMap;
-import javax.swing.ButtonGroup;
-import javax.swing.ButtonModel;
-import javax.swing.Icon;
-import javax.swing.JCheckBox;
-import javax.swing.SwingUtilities;
-import javax.swing.event.ChangeListener;
-import javax.swing.plaf.ActionMapUIResource;
-
-public class QuadStateCheckBox extends JCheckBox {
-
-    public enum State { NOT_SELECTED, SELECTED, UNSET, PARTIAL }
-
-    private final QuadStateDecorator model;
-    private State[] allowed;
-
-    public QuadStateCheckBox(String text, Icon icon, State initial, State[] allowed) {
-        super(text, icon);
-        this.allowed = allowed;
-        // Add a listener for when the mouse is pressed
-        super.addMouseListener(new MouseAdapter() {
-            @Override public void mousePressed(MouseEvent e) {
-                grabFocus();
-                model.nextState();
-            }
-        });
-        // Reset the keyboard action map
-        ActionMap map = new ActionMapUIResource();
-        map.put("pressed", new AbstractAction() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                grabFocus();
-                model.nextState();
-            }
-        });
-        map.put("released", null);
-        SwingUtilities.replaceUIActionMap(this, map);
-        // set the model to the adapted model
-        model = new QuadStateDecorator(getModel());
-        setModel(model);
-        setState(initial);
-    }
-    public QuadStateCheckBox(String text, State initial, State[] allowed) {
-        this(text, null, initial, allowed);
-    }
-
-    /** Do not let anyone add mouse listeners */
-    @Override public void addMouseListener(MouseListener l) { }
-    /**
-     * Set the new state.
-     */
-    public void setState(State state) { model.setState(state); }
-    /** Return the current state, which is determined by the
-     * selection status of the model. */
-    public State getState() { return model.getState(); }
-    @Override public void setSelected(boolean b) {
-        if (b) {
-            setState(State.SELECTED);
-        } else {
-            setState(State.NOT_SELECTED);
-        }
-    }
-
-    private class QuadStateDecorator implements ButtonModel {
-        private final ButtonModel other;
-        private QuadStateDecorator(ButtonModel other) {
-            this.other = other;
-        }
-        private void setState(State state) {
-            if (state == State.NOT_SELECTED) {
-                other.setArmed(false);
-                other.setPressed(false);
-                other.setSelected(false);
-                setToolTipText(tr("false: the property is explicitly switched off"));
-            } else if (state == State.SELECTED) {
-                other.setArmed(false);
-                other.setPressed(false);
-                other.setSelected(true);
-                setToolTipText(tr("true: the property is explicitly switched on"));
-            } else if (state == State.PARTIAL) {
-                other.setArmed(true);
-                other.setPressed(true);
-                other.setSelected(true);
-                setToolTipText(tr("partial: different selected objects have different values, do not change"));
-            } else {
-                other.setArmed(true);
-                other.setPressed(true);
-                other.setSelected(false);
-                setToolTipText(tr("unset: do not set this property on the selected objects"));
-            }
-        }
-        /**
-         * The current state is embedded in the selection / armed
-         * state of the model.
-         *
-         * We return the SELECTED state when the checkbox is selected
-         * but not armed, PARTIAL state when the checkbox is
-         * selected and armed (grey) and NOT_SELECTED when the
-         * checkbox is deselected.
-         */
-        private State getState() {
-            if (isSelected() && !isArmed()) {
-                // normal black tick
-                return State.SELECTED;
-            } else if (isSelected() && isArmed()) {
-                // don't care grey tick
-                return State.PARTIAL;
-            } else if (!isSelected() && !isArmed()) {
-                return State.NOT_SELECTED;
-            } else {
-                return State.UNSET;
-            }
-        }
-        /** Rotate to the next allowed state.*/
-        private void nextState() {
-            State current = getState();
-            for (int i = 0; i < allowed.length; i++) {
-                if (allowed[i] == current) {
-                    setState((i == allowed.length-1) ? allowed[0] : allowed[i+1]);
-                    break;
-                }
-            }
-        }
-        /** Filter: No one may change the armed/selected/pressed status except us. */
-        @Override public void setArmed(boolean b) { }
-        @Override public void setSelected(boolean b) { }
-        @Override public void setPressed(boolean b) { }
-        /** We disable focusing on the component when it is not
-         * enabled. */
-        @Override public void setEnabled(boolean b) {
-            setFocusable(b);
-            other.setEnabled(b);
-        }
-        /** All these methods simply delegate to the "other" model
-         * that is being decorated. */
-        @Override public boolean isArmed() { return other.isArmed(); }
-        @Override public boolean isSelected() { return other.isSelected(); }
-        @Override public boolean isEnabled() { return other.isEnabled(); }
-        @Override public boolean isPressed() { return other.isPressed(); }
-        @Override public boolean isRollover() { return other.isRollover(); }
-        @Override public void setRollover(boolean b) { other.setRollover(b); }
-        @Override public void setMnemonic(int key) { other.setMnemonic(key); }
-        @Override public int getMnemonic() { return other.getMnemonic(); }
-        @Override public void setActionCommand(String s) {
-            other.setActionCommand(s);
-        }
-        @Override public String getActionCommand() {
-            return other.getActionCommand();
-        }
-        @Override public void setGroup(ButtonGroup group) {
-            other.setGroup(group);
-        }
-        @Override public void addActionListener(ActionListener l) {
-            other.addActionListener(l);
-        }
-        @Override public void removeActionListener(ActionListener l) {
-            other.removeActionListener(l);
-        }
-        @Override public void addItemListener(ItemListener l) {
-            other.addItemListener(l);
-        }
-        @Override public void removeItemListener(ItemListener l) {
-            other.removeItemListener(l);
-        }
-        @Override public void addChangeListener(ChangeListener l) {
-            other.addChangeListener(l);
-        }
-        @Override public void removeChangeListener(ChangeListener l) {
-            other.removeChangeListener(l);
-        }
-        @Override public Object[] getSelectedObjects() {
-            return other.getSelectedObjects();
-        }
-    }
-}
Index: trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPresetItems.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPresetItems.java	(revision 6220)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPresetItems.java	(revision 6221)
@@ -48,5 +48,4 @@
 import org.openstreetmap.josm.data.osm.Tag;
 import org.openstreetmap.josm.data.preferences.BooleanProperty;
-import org.openstreetmap.josm.gui.QuadStateCheckBox;
 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletingTextField;
 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionItemPritority;
@@ -54,4 +53,5 @@
 import org.openstreetmap.josm.gui.widgets.JosmComboBox;
 import org.openstreetmap.josm.gui.widgets.JosmTextField;
+import org.openstreetmap.josm.gui.widgets.QuadStateCheckBox;
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
Index: trunk/src/org/openstreetmap/josm/gui/widgets/QuadStateCheckBox.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/widgets/QuadStateCheckBox.java	(revision 6221)
+++ trunk/src/org/openstreetmap/josm/gui/widgets/QuadStateCheckBox.java	(revision 6221)
@@ -0,0 +1,233 @@
+// License: GPL. Copyright 2008 by Frederik Ramm and others
+package org.openstreetmap.josm.gui.widgets;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+
+import javax.swing.AbstractAction;
+import javax.swing.ActionMap;
+import javax.swing.ButtonGroup;
+import javax.swing.ButtonModel;
+import javax.swing.Icon;
+import javax.swing.JCheckBox;
+import javax.swing.SwingUtilities;
+import javax.swing.event.ChangeListener;
+import javax.swing.plaf.ActionMapUIResource;
+
+import org.openstreetmap.josm.tools.Utils;
+
+/**
+ * A four-state checkbox. The states are enumerated in {@link State}.
+ * @since 591
+ */
+public class QuadStateCheckBox extends JCheckBox {
+
+    /**
+     * The 4 possible states of this checkbox.
+     */
+    public enum State {
+        /** Not selected: the property is explicitly switched off */
+        NOT_SELECTED,
+        /** Selected: the property is explicitly switched on */
+        SELECTED,
+        /** Unset: do not set this property on the selected objects */
+        UNSET,
+        /** Partial: different selected objects have different values, do not change */
+        PARTIAL
+    }
+
+    private final QuadStateDecorator model;
+    private State[] allowed;
+
+    /**
+     * Constructs a new {@code QuadStateCheckBox}.
+     * @param text the text of the check box
+     * @param icon the Icon image to display
+     * @param initial The initial state
+     * @param allowed The allowed states
+     */
+    public QuadStateCheckBox(String text, Icon icon, State initial, State[] allowed) {
+        super(text, icon);
+        this.allowed = Utils.copyArray(allowed);
+        // Add a listener for when the mouse is pressed
+        super.addMouseListener(new MouseAdapter() {
+            @Override public void mousePressed(MouseEvent e) {
+                grabFocus();
+                model.nextState();
+            }
+        });
+        // Reset the keyboard action map
+        ActionMap map = new ActionMapUIResource();
+        map.put("pressed", new AbstractAction() {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                grabFocus();
+                model.nextState();
+            }
+        });
+        map.put("released", null);
+        SwingUtilities.replaceUIActionMap(this, map);
+        // set the model to the adapted model
+        model = new QuadStateDecorator(getModel());
+        setModel(model);
+        setState(initial);
+    }
+    
+    /**
+     * Constructs a new {@code QuadStateCheckBox}.
+     * @param text the text of the check box
+     * @param initial The initial state
+     * @param allowed The allowed states
+     */
+    public QuadStateCheckBox(String text, State initial, State[] allowed) {
+        this(text, null, initial, allowed);
+    }
+
+    /** Do not let anyone add mouse listeners */
+    @Override public void addMouseListener(MouseListener l) { }
+    
+    /**
+     * Set the new state.
+     * @param state The new state
+     */
+    public void setState(State state) {
+        model.setState(state);
+    }
+    
+    /** 
+     * Return the current state, which is determined by the selection status of the model. 
+     * @return The current state 
+     */
+    public State getState() {
+        return model.getState();
+    }
+    
+    @Override
+    public void setSelected(boolean b) {
+        if (b) {
+            setState(State.SELECTED);
+        } else {
+            setState(State.NOT_SELECTED);
+        }
+    }
+
+    private class QuadStateDecorator implements ButtonModel {
+        private final ButtonModel other;
+        
+        private QuadStateDecorator(ButtonModel other) {
+            this.other = other;
+        }
+        
+        private void setState(State state) {
+            if (state == State.NOT_SELECTED) {
+                other.setArmed(false);
+                other.setPressed(false);
+                other.setSelected(false);
+                setToolTipText(tr("false: the property is explicitly switched off"));
+            } else if (state == State.SELECTED) {
+                other.setArmed(false);
+                other.setPressed(false);
+                other.setSelected(true);
+                setToolTipText(tr("true: the property is explicitly switched on"));
+            } else if (state == State.PARTIAL) {
+                other.setArmed(true);
+                other.setPressed(true);
+                other.setSelected(true);
+                setToolTipText(tr("partial: different selected objects have different values, do not change"));
+            } else {
+                other.setArmed(true);
+                other.setPressed(true);
+                other.setSelected(false);
+                setToolTipText(tr("unset: do not set this property on the selected objects"));
+            }
+        }
+        
+        /**
+         * The current state is embedded in the selection / armed
+         * state of the model.
+         *
+         * We return the SELECTED state when the checkbox is selected
+         * but not armed, PARTIAL state when the checkbox is
+         * selected and armed (grey) and NOT_SELECTED when the
+         * checkbox is deselected.
+         */
+        private State getState() {
+            if (isSelected() && !isArmed()) {
+                // normal black tick
+                return State.SELECTED;
+            } else if (isSelected() && isArmed()) {
+                // don't care grey tick
+                return State.PARTIAL;
+            } else if (!isSelected() && !isArmed()) {
+                return State.NOT_SELECTED;
+            } else {
+                return State.UNSET;
+            }
+        }
+        /** Rotate to the next allowed state.*/
+        private void nextState() {
+            State current = getState();
+            for (int i = 0; i < allowed.length; i++) {
+                if (allowed[i] == current) {
+                    setState((i == allowed.length-1) ? allowed[0] : allowed[i+1]);
+                    break;
+                }
+            }
+        }
+        /** Filter: No one may change the armed/selected/pressed status except us. */
+        @Override public void setArmed(boolean b) { }
+        @Override public void setSelected(boolean b) { }
+        @Override public void setPressed(boolean b) { }
+        /** We disable focusing on the component when it is not enabled. */
+        @Override public void setEnabled(boolean b) {
+            setFocusable(b);
+            other.setEnabled(b);
+        }
+        /** All these methods simply delegate to the "other" model
+         * that is being decorated. */
+        @Override public boolean isArmed() { return other.isArmed(); }
+        @Override public boolean isSelected() { return other.isSelected(); }
+        @Override public boolean isEnabled() { return other.isEnabled(); }
+        @Override public boolean isPressed() { return other.isPressed(); }
+        @Override public boolean isRollover() { return other.isRollover(); }
+        @Override public void setRollover(boolean b) { other.setRollover(b); }
+        @Override public void setMnemonic(int key) { other.setMnemonic(key); }
+        @Override public int getMnemonic() { return other.getMnemonic(); }
+        @Override public void setActionCommand(String s) {
+            other.setActionCommand(s);
+        }
+        @Override public String getActionCommand() {
+            return other.getActionCommand();
+        }
+        @Override public void setGroup(ButtonGroup group) {
+            other.setGroup(group);
+        }
+        @Override public void addActionListener(ActionListener l) {
+            other.addActionListener(l);
+        }
+        @Override public void removeActionListener(ActionListener l) {
+            other.removeActionListener(l);
+        }
+        @Override public void addItemListener(ItemListener l) {
+            other.addItemListener(l);
+        }
+        @Override public void removeItemListener(ItemListener l) {
+            other.removeItemListener(l);
+        }
+        @Override public void addChangeListener(ChangeListener l) {
+            other.addChangeListener(l);
+        }
+        @Override public void removeChangeListener(ChangeListener l) {
+            other.removeChangeListener(l);
+        }
+        @Override public Object[] getSelectedObjects() {
+            return other.getSelectedObjects();
+        }
+    }
+}
Index: trunk/src/org/openstreetmap/josm/tools/Utils.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/Utils.java	(revision 6220)
+++ trunk/src/org/openstreetmap/josm/tools/Utils.java	(revision 6221)
@@ -30,4 +30,5 @@
 import java.util.AbstractList;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
@@ -241,4 +242,17 @@
     }
 
+    /**
+     * Copies the given array. Unlike {@link Arrays#copyOf}, this method is null-safe.
+     * @param array The array to copy
+     * @return A copy of the original array, or {@code null} if {@code array} is null
+     * @since 6221
+     */
+    public static <T> T[] copyArray(T[] array) {
+        if (array != null) {
+            return Arrays.copyOf(array, array.length);
+        }
+        return null;
+    }
+    
     /**
      * Simple file copy function that will overwrite the target file.<br/>
