gt: 		if (key == null || key.isEmpty()) {
context: /**
   * Copyright (C) 2001-2015 by RapidMiner and the contributors
   *
   * Complete list of developers available at our web site:
   *
   *      http://rapidminer.com
   *
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU Affero 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 Affero General Public License for more details.
   *
   * You should have received a copy of the GNU Affero General Public License
   * along with this program.  If not, see http://www.gnu.org/licenses/.
   */
  package com.rapidminer.gui.properties;
  
  import java.io.IOException;
  import java.net.URISyntaxException;
  import java.util.Collection;
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.LinkedHashMap;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.Map;
  import java.util.Map.Entry;
  import java.util.logging.Level;
  
  import javax.xml.parsers.ParserConfigurationException;
  
  import org.xml.sax.SAXException;
  
  import com.rapidminer.gui.properties.SettingsItem.Type;
  import com.rapidminer.tools.LogService;
  import com.rapidminer.tools.ParameterService;
  import com.rapidminer.tools.Tools;
  
  
  /**
   * This singleton instance handles {SettingItem}s. It contains a map, which maps settings keys to
   * {@link SettingsItem}s. Additionally to some default map methods and helper methods are provided.
   *
   * @author Adrian Wilke
   */
  public enum SettingsItems {
  
  	INSTANCE;
  
  	/** Maps keys to SettingsItem objects */
  	private Map<String, SettingsItem> itemMap = new LinkedHashMap<>();
  
  	/** Was XML of RapidMiner Studio parsed successfully? */
  	private boolean studioXmlParsed = false;
  
  	/** Singleton: Empty private constructor */
  	private SettingsItems() {}
  
  	/** Removes empty subgroups and groups */
  	public void clean() {
  		List<SettingsItem> mapItems = getItems(Type.SUB_GROUP);
  		Iterator<SettingsItem> mapIterator = mapItems.iterator();
  		while (mapIterator.hasNext()) {
  			SettingsItem item = mapIterator.next();
  			if (item.getChildren().isEmpty()) {
  				try {
  					remove(item.getKey());
  				} catch (RuntimeException runtimeException) {
  					// This would be a failure in the settings structure and should not happen.
  					// The log is to notice an improbable occurrence.
  					LogService.getRoot().log(Level.WARNING, "com.rapidminer.gui.properties.SettingsItems.remove_item_error",
  							runtimeException);
  				}
  			}
  		}
  		mapItems = getItems(Type.GROUP);
  		mapIterator = mapItems.iterator();
  		while (mapIterator.hasNext()) {
  			SettingsItem item = mapIterator.next();
  			if (item.getChildren().isEmpty()) {
  				try {
  					remove(item.getKey());
  				} catch (RuntimeException runtimeException) {
  					// This would be a failure in the settings structure and should not happen.
  					// The log is to notice an improbable occurrence.
  					LogService.getRoot().log(Level.WARNING, "com.rapidminer.gui.properties.SettingsItems.remove_item_error",
  							runtimeException);
  				}
  			}
  		}
  	};
  
  	/** Checks if a key is known. */
  	public boolean containsKey(String key) {
  		return itemMap.containsKey(key);
  	}
  
  	/** Returns item or <code>null</code>, if key is unknown. */
  	public SettingsItem get(String key) {
  		return itemMap.get(key);
  	}
  
  	/** Returns all items of the specified type. */
  	public List<SettingsItem> getItems(Type type) {
  		List<SettingsItem> settingsItems = new LinkedList<>();
  		for (SettingsItem settingsItem : itemMap.values()) {
  			if (settingsItem.getType().equals(type)) {
  				settingsItems.add(settingsItem);
  			}
  		}
  		return settingsItems;
  	}
  
  	/** Returns all known keys. */
  	public Collection<String> getKeys() {
  		return new HashSet<String>(itemMap.keySet());
  	}
  
  	/**
  	 * Parses XML file of RapidMiner Studio with settings structure.
  	 *
  	 * Sets {@link SettingsItems#studioXmlParsed} to the return value.
  	 *
  	 * @return <code>true</code>, if the XML was parsed successfully. <code>false</code>, if not.
  	 */
  	public boolean parseStudioXml() {
  		try {
  			itemMap = new SettingsXmlHandler().parse(Tools.getResource(SettingsXmlHandler.SETTINGS_XML_FILE).toURI());
  			studioXmlParsed = true;
  			return true;
  		} catch (ParserConfigurationException | SAXException | IOException | URISyntaxException e) {
  			String[] params = new String[2];
  			params[0] = SettingsXmlHandler.SETTINGS_XML_FILE;
  			params[1] = e.getMessage();
  			LogService.getRoot().log(Level.WARNING, "com.rapidminer.gui.properties.SettingsItems.parse_xml_error", params);
  			studioXmlParsed = false;
  			return false;
  			// Must not throw an exception, as the settings work without the structure inside XML.
  		}
  	}
  
  	/**
  	 * Adds an item to the map of used SettingsItem objects. Checks for <code>null</code> and empty
  	 * values of the parameters.
  	 */
  	public void put(String key, SettingsItem item) {
  		if (key == null || key.isEmpty()) {
  			throw new IllegalArgumentException("Key not set");
  		}
  		if (item == null) {
  			throw new IllegalArgumentException("No item for key " + key);
  		}
  		itemMap.put(key, item);
  	}
  
  	/**
  	 * Removes item from {@link SettingsItems} and the {@link SettingsItem} internal hierarchy.
  	 *
  	 * @param key
  	 *            Key of item
  	 * @throws IllegalStateException
  	 *             If key is not known or related item has children
  	 */
  	public void remove(String key) throws IllegalStateException {
  		remove(key, true, true);
  	}
  
  	/**
  	 * Removes item from {@link SettingsItems} and/or the {@link SettingsItem} internal hierarchy.
  	 * The execution of the remove operation can be set for each of the both data structures.
  	 *
  	 * @param key
  	 *            Key of item
  	 * @param removeFromSettingsItems
  	 *            Remove from {@link SettingsItems} data structure
  	 * @param removeFromHierarchy
  	 *            Removes from {@link SettingsItem} internal hierarchy
  	 *
  	 * @throws IllegalStateException
  	 *             If key is not known or related item has children
  	 */
  	public void remove(String key, boolean removeFromSettingsItems, boolean removeFromHierarchy)
  			throws IllegalStateException {
  
  		if (!itemMap.containsKey(key)) {
  			throw new IllegalStateException("Could not remove settings item " + key + " as it is not known");
  		}
  
  		if (removeFromHierarchy) {
  			SettingsItem item = itemMap.get(key);
  			if (item.getChildren().isEmpty()) {
  				if (item.getParent() != null) {
  					item.getParent().getChildren().remove(item);
  				}
  			} else {
  				throw new IllegalStateException("Could not remove settings item " + key + " as it has children");
  			}
  		}
  
  		if (removeFromSettingsItems) {
  			itemMap.remove(key);
  		}
  	}
  
  	/** Removes all elements of type parameter, whose keys are not contained in keepKeys */
  	public void removeParameterInverse(Collection<String> keepKeys) {
  		Iterator<Entry<String, SettingsItem>> itemMapIterator = itemMap.entrySet().iterator();
  		while (itemMapIterator.hasNext()) {
  			Entry<String, SettingsItem> itemMapEntry = itemMapIterator.next();
  			String key = itemMapEntry.getKey();
  			if (!keepKeys.contains(key)) {
  				SettingsItem item = itemMapEntry.getValue();
  				if (item.getType().equals(Type.PARAMETER)) {
  					try {
  						remove(key, false, true);
  						itemMapIterator.remove();
  					} catch (IllegalStateException e) {
  						LogService.getRoot().log(Level.WARNING,
  								"com.rapidminer.gui.properties.SettingsItems.remove_item_error", e);
  					}
  				}
  			}
  		}
  	}
  
  	/** Returns true if the XML file was parsed successfully. Returns false if not. */
  	public boolean isStudioXmlParsedSuccessfully() {
  		return studioXmlParsed;
  	}
  
  	/**
  	 * Creates a SettingsItem and adds it to the item map. Parent items of the type GROUP are also
  	 * generated.
  	 *
  	 * @param key
  	 *            The key of the item
  	 * @param type
  	 *            The type of the item
  	 *
  	 * @return The created SettingsItem
  	 */
  	public static SettingsItem createAndAddItem(String key, Type type) {
  