gt:         if (testValue == null) {
context: /*
   * Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de)
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License as published by the Free
   * Software Foundation; either version 3 of the License, or (at your option)
   * any later version.
   * This program is distributed in the hope that it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
   * more details.
   *
   * You should have received a copy of the GNU General Public License along
   * with this program; if not, see http://www.gnu.org/licenses/
   */
  package org.esa.snap.framework.ui.command;
  
  import com.bc.ceres.core.CoreException;
  import com.bc.ceres.core.runtime.ConfigurableExtension;
  import com.bc.ceres.core.runtime.ConfigurationElement;
  import org.esa.snap.framework.ui.UIUtils;
  import org.esa.snap.util.Debug;
  import org.esa.snap.util.Guardian;
  import org.esa.snap.util.StringUtils;
  
  import javax.swing.AbstractButton;
  import javax.swing.Action;
  import javax.swing.Icon;
  import javax.swing.JMenuItem;
  import javax.swing.KeyStroke;
  import javax.swing.event.EventListenerList;
  import java.util.EventListener;
  import java.util.List;
  import java.util.MissingResourceException;
  import java.util.ResourceBundle;
  
  /**
   * The <code>Command</code> is the base class for all BEAM GUI commands.
   *
   * @author Norman Fomferra
   * @author Sabine Embacher
   */
  public abstract class Command implements ConfigurableExtension {
  
      private String commandID;
      private final Action action;
      private EventListenerList eventListenerList;
      private static CommandUIFactory commandUIFactory = new DefaultCommandUIFactory();
  
      /**
       * The key used for storing a large icon for the action, used for toolbar buttons.
       * <p>Note: Actually this key belongs in the javax.swing.Action interface, but Sun hasn't done this so far (why?).
       */
      public static final String ACTION_KEY_LARGE_ICON = "_largeIcon";
      public static final String ACTION_KEY_SEPARATOR_BEFORE = "_separatorBefore";
      public static final String ACTION_KEY_SEPARATOR_AFTER = "_separatorAfter";
      public static final String ACTION_KEY_PLACE_FIRST = "_placeFirst";
      public static final String ACTION_KEY_PLACE_LAST = "_placeLast";
      public static final String ACTION_KEY_PLACE_BEFORE = "_placeBefore";
      public static final String ACTION_KEY_PLACE_AFTER = "_placeAfter";
      public static final String ACTION_KEY_PLACE_CONTEXT_TOP = "_placeAtContextTop";
      public static final String ACTION_KEY_PARENT = "_parent";
      public static final String ACTION_KEY_LOCATION = "_location";
      public static final String ACTION_KEY_CONTEXT = "_context";
      public static final String ACTION_KEY_POPUP_TEXT = "popupText";
      public static final String ACTION_KEY_SORT_CHILDREN = "_sortChildren";
      public static final String HELP_ID_KEY = "_helpId";
  
      protected Command() {
          action = createAction();
          setCommandID(getClass().getName());
      }
  
      protected Command(String commandID) {
          this();
          Guardian.assertNotNull(commandID, "commandID");
          setCommandID(commandID);
      }
  
      public String getCommandID() {
          return commandID;
      }
  
      public void setCommandID(String commandId) {
          commandID = commandId;
          action.putValue(Action.ACTION_COMMAND_KEY, commandId);
      }
  
      public Action getAction() {
          return action;
      }
  
      public boolean isEnabled() {
          return getAction().isEnabled();
      }
  
      public void setEnabled(boolean enabled) {
          getAction().setEnabled(enabled);
      }
  
      public String getParent() {
          return (String) getProperty(ACTION_KEY_PARENT);
      }
  
      public void setParent(String value) {
          setProperty(ACTION_KEY_PARENT, value);
      }
  
      public String[] getLocations() {
          return (String[]) getProperty(ACTION_KEY_LOCATION);
      }
  
      public void setLocations(String[] locations) {
          setProperty(ACTION_KEY_LOCATION, locations);
      }
  
      public boolean containsLocation(String location) {
          return containsProperty(ACTION_KEY_LOCATION, location);
      }
  
      public String[] getContexts() {
          return (String[]) getProperty(ACTION_KEY_CONTEXT);
      }
  
      public void setContexts(String[] contexts) {
          setProperty(ACTION_KEY_CONTEXT, contexts);
      }
  
      public boolean containsContext(String context) {
          return containsProperty(ACTION_KEY_CONTEXT, context);
      }
  
      public String getText() {
          return (String) getProperty(Action.NAME);
      }
  
      public void setText(String value) {
          setProperty(Action.NAME, value);
      }
  
      public String getPopupText() {
          return (String) getProperty(ACTION_KEY_POPUP_TEXT);
      }
  
      public void setPopupText(String value) {
          setProperty(ACTION_KEY_POPUP_TEXT, value);
      }
  
      public boolean getSortChildren() {
          return getProperty(ACTION_KEY_SORT_CHILDREN, false);
      }
  
      /**
       * Returns the integer value of command's mnemonic character.
       *
       * @return the integer value of command's mnemonic character or <code>-1</code> if mnemonic property is
       *         <code>null</code>
       */
      public int getMnemonic() {
          final Object property = getProperty(Action.MNEMONIC_KEY);
          if (property != null) {
              return ((Number) property).intValue();
          }
          return -1;
      }
  
      public void setMnemonic(int mnemonic) {
          setProperty(Action.MNEMONIC_KEY, mnemonic);
      }
  
      public KeyStroke getAccelerator() {
          return (KeyStroke) getProperty(Action.ACCELERATOR_KEY);
      }
  
      public void setAccelerator(KeyStroke accelerator) {
          setProperty(Action.ACCELERATOR_KEY, accelerator);
      }
  
      public String getShortDescription() {
          return (String) getProperty(Action.SHORT_DESCRIPTION);
      }
  
      public void setShortDescription(String text) {
          setProperty(Action.SHORT_DESCRIPTION, text);
      }
  
      public String getLongDescription() {
          return (String) getProperty(Action.LONG_DESCRIPTION);
      }
  
      public void setLongDescription(String text) {
          setProperty(Action.LONG_DESCRIPTION, text);
      }
  
      public String getHelpId() {
          return getProperty(HELP_ID_KEY, "");
      }
  
      public void setHelpId(String id) {
          setProperty(HELP_ID_KEY, id);
      }
  
      public Icon getSmallIcon() {
          return (Icon) getProperty(Action.SMALL_ICON);
      }
  
      public void setSmallIcon(Icon icon) {
          setProperty(Action.SMALL_ICON, icon);
      }
  
      public Icon getLargeIcon() {
          return (Icon) getProperty(ACTION_KEY_LARGE_ICON);
      }
  
      public void setLargeIcon(Icon icon) {
          setProperty(ACTION_KEY_LARGE_ICON, icon);
      }
  
      public boolean isSeparatorBefore() {
          return getProperty(ACTION_KEY_SEPARATOR_BEFORE, false);
      }
  
      public void setSeparatorBefore(boolean separatorBefore) {
          setProperty(ACTION_KEY_SEPARATOR_BEFORE, separatorBefore);
      }
  
      public boolean isSeparatorAfter() {
          return getProperty(ACTION_KEY_SEPARATOR_AFTER, false);
      }
  
      public void setSeparatorAfter(boolean separatorAfter) {
          setProperty(ACTION_KEY_SEPARATOR_AFTER, separatorAfter);
      }
  
      public boolean getPlaceFirst() {
          return getProperty(ACTION_KEY_PLACE_FIRST, false);
      }
  
      public void setPlaceFirst(boolean value) {
          setProperty(ACTION_KEY_PLACE_FIRST, value);
      }
  
      public boolean getPlaceLast() {
          return getProperty(ACTION_KEY_PLACE_LAST, false);
      }
  
      public void setPlaceLast(boolean value) {
          setProperty(ACTION_KEY_PLACE_LAST, value);
      }
  
      public String getPlaceAfter() {
          return (String) getProperty(ACTION_KEY_PLACE_AFTER);
      }
  
      public void setPlaceAfter(String placeAfter) {
          setProperty(ACTION_KEY_PLACE_AFTER, placeAfter);
      }
  
      public String getPlaceBefore() {
          return (String) getProperty(ACTION_KEY_PLACE_BEFORE);
      }
  
      public void setPlaceBefore(String placeBefore) {
          setProperty(ACTION_KEY_PLACE_BEFORE, placeBefore);
      }
  
      public boolean isPlaceAtContextTop() {
          return getProperty(ACTION_KEY_PLACE_CONTEXT_TOP, false);
      }
  
      public void setPlaceAtContextTop(boolean placeAtContextTop) {
          setProperty(ACTION_KEY_PLACE_CONTEXT_TOP, placeAtContextTop);
      }
  
      /**
       * Configures this command with the properties (if any) found in the given recource bundle. The resource keys for
       * the corresponding properties are: <p> <ul> <li><code>command.</code><i>command-ID</i><code>.text = <i>display text</i></code></li>
       * <li><code>command.</code><i>command-ID</i><code>.popuptext = <i>display text for popup menu</i></code></li>
       * <li><code>command.</code><i>command-ID</i><code>.mnemonic = <i>mnemonic key character</i></code></li>
       * <li><code>command.</code><i>command-ID</i><code>.accelerator = <i>accelerator</i></code></li>
       * <li><code>command.</code><i>command-ID</i><code>.shortdescr = <i>text</i></code></li>
       * <li><code>command.</code><i>command-ID</i><code>.longdescr = <i>text</i></code></li>
       * <li><code>command.</code><i>command-ID</i><code>.smallicon = <i>image-path</i></code></li>
       * <li><code>command.</code><i>command-ID</i><code>.largeicon = <i>image-path</i></code></li>
       * <li><code>command.</code><i>command-ID</i><code>.parent = <i>command-COMMAND_ID or main-menu-name</i></code></li>
       * <li><code>command.</code><i>command-ID</i><code>.location = <i>location-1</i>, <i>location-2</i>, ...</code></li>
       * <li><code>command.</code><i>command-ID</i><code>.context = <i>context-1</i>, <i>context-2</i>, ...</code></li>
       * <li><code>command.</code><i>command-COMMAND_ID</i><code>.placeBefore = <i>command-ID</i></code></li>
       * <li><code>command.</code><i>command-ID</i><code>.placeAfter = <i>command-COMMAND_ID</i></code></li>
       * <li><code>command.</code><i>command-ID</i><code>.separatorBefore = true <i>or</i> false</code></li>
       * <li><code>command.</code><i>command-ID</i><code>.separatorAfter = true <i>or</i> false</code></li> </ul>
       *
       * @param resourceBundle the resource bundle from which the properties are received
       *
       * @throws IllegalArgumentException if the resource bundle is null
       */
      public void configure(ResourceBundle resourceBundle) {
          Guardian.assertNotNull("resourceBundle", resourceBundle);
  
          String resString;
          String[] resStrings;
          Icon resIcon;
          Boolean resBoolean;
  
          resString = getResourceString(resourceBundle, "text");
          if (resString != null && resString.length() > 0) {
              setText(resString);
          }
  
          resString = getResourceString(resourceBundle, "popuptext");
          if (resString != null && resString.length() > 0) {
              setPopupText(resString);
          }
  
          resString = getResourceString(resourceBundle, "mnemonic");
          if (resString != null && resString.length() > 0) {
              setMnemonic((int) resString.charAt(0));
          }
  
          resString = getResourceString(resourceBundle, "accelerator");
          if (resString != null && resString.length() > 0) {
              setAccelerator(KeyStroke.getKeyStroke(resString));
          }
  
          resString = getResourceString(resourceBundle, "shortDescr");
          if (resString != null) {
              setShortDescription(resString);
          }
  
          resString = getResourceString(resourceBundle, "longDescr");
          if (resString != null) {
              setLongDescription(resString);
          }
  
          resIcon = getResourceIcon(resourceBundle, "smallIcon");
          if (resIcon != null) {
              setSmallIcon(resIcon);
          }
  
          resIcon = getResourceIcon(resourceBundle, "largeIcon");
          if (resIcon != null) {
              setLargeIcon(resIcon);
          }
  
          resBoolean = getResourceBoolean(resourceBundle, "separatorBefore");
          if (resBoolean != null) {
              setSeparatorBefore(resBoolean);
          }
  
          resBoolean = getResourceBoolean(resourceBundle, "separatorAfter");
          if (resBoolean != null) {
              setSeparatorAfter(resBoolean);
          }
  
          resString = getResourceString(resourceBundle, "placeBefore");
          if (resString != null) {
              setProperty(ACTION_KEY_PLACE_BEFORE, resString);
          }
  
          resString = getResourceString(resourceBundle, "placeAfter");
          if (resString != null) {
              setProperty(ACTION_KEY_PLACE_AFTER, resString);
          }
  
          resBoolean = getResourceBoolean(resourceBundle, "placeAtContextTop");
          if (resBoolean != null) {
              setPlaceAtContextTop(resBoolean);
          }
  
          resString = getResourceString(resourceBundle, "parent");
          if (resString != null) {
              setProperty(ACTION_KEY_PARENT, resString);
          }
  
          resStrings = getResourceStrings(resourceBundle, "location");
          if (resStrings != null) {
              setProperty(ACTION_KEY_LOCATION, resStrings);
          }
  
          resStrings = getResourceStrings(resourceBundle, "context");
          if (resStrings != null) {
              setProperty(ACTION_KEY_CONTEXT, resStrings);
          }
  
          resBoolean = getResourceBoolean(resourceBundle, "sortChildren");
          if (resString != null) {
              setProperty(ACTION_KEY_SORT_CHILDREN, resBoolean);
          }
  
          resString = getResourceString(resourceBundle, "helpId");
          if (resString != null) {
              setProperty(HELP_ID_KEY, resString);
          }
      }
  
      /**
       * Causes this command to fire the 'check status' event to all of its listeners.
       */
      public void updateState() {
          updateState(new CommandEvent(this, null, null, null));
          fireUpdateState();
      }
  
      /**
       * Creates an appropriate menu item for this command.
       */
      public abstract JMenuItem createMenuItem();
  
      /**
       * Creates an appropriate tool bar button for this command.
       */
      public abstract AbstractButton createToolBarButton();
  
      /**
       * Creates an appropriate action instance for this command.
       */
      protected abstract Action createAction();
  
      protected Object getProperty(String key) {
          return getAction().getValue(key);
      }
  
      protected void setProperty(String key, Object value) {
          getAction().putValue(key, value);
      }
  
      protected boolean containsProperty(String key, Object testValue) {
  