/*
 * Copyright 2005 The Apache Software Foundation or its licensors, as
 * applicable.
 * 
 * Licensed 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 java.beans;

import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * Common base class for Descriptors.
 * 
 * @author Maxim V. Berkultsev
 */
public class FeatureDescriptor {

    private Map<String, Object> values;

    boolean preferred, hidden, expert;

    String shortDescription;

    String name;

    String displayName;

    /**
     * <p>
     * Constructs an instance.
     * </p>
     */
    public FeatureDescriptor() {
        this.values = new HashMap<String, Object>();
    }

    /**
     * <p>
     * Sets the value for the named attribute.
     * </p>
     * 
     * @param attributeName The name of the attribute to set a value with.
     * @param value The value to set.
     */
    public void setValue(String attributeName, Object value) {
        if (attributeName == null || value == null)
            throw new NullPointerException();
        values.put(attributeName, value);
    }

    /**
     * <p>
     * Gets the value associated with the named attribute.
     * </p>
     * 
     * @param attributeName The name of the attribute to get a value for.
     * @return The attribute's value.
     */
    public Object getValue(String attributeName) {
        Object result = null;
        if (attributeName != null) {
            result = values.get(attributeName);
        }
        return result;
    }

    /**
     * <p>
     * Enumerates the attribute names.
     * </p>
     * 
     * @return An instance of {@link Enumeration}.
     */
    public Enumeration<String> attributeNames() {
        return Collections.enumeration(values.keySet());
    }

    /**
     * <p>
     * Sets the short description.
     * </p>
     * 
     * @param text The description to set.
     */
    public void setShortDescription(String text) {
        this.shortDescription = text;
    }

    /**
     * <p>
     * Sets the name.
     * </p>
     * 
     * @param name The name to set.
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * <p>
     * Sets the display name.
     * </p>
     * 
     * @param displayName The display name to set.
     */
    public void setDisplayName(String displayName) {
        this.displayName = displayName;
    }

    /**
     * <p>
     * Gets the short description or {@link #getDisplayName()} if not set.
     * </p>
     * 
     * @return The description.
     */
    public String getShortDescription() {
        return shortDescription == null ? getDisplayName() : shortDescription;
    }

    /**
     * <p>
     * Gets the name.
     * </p>
     * 
     * @return The name.
     */
    public String getName() {
        return name;
    }

    /**
     * <p>
     * Gets the display name or {@link #getName()} if not set.
     * </p>
     * 
     * @return The display name.
     */
    public String getDisplayName() {
        return displayName == null ? getName() : displayName;
    }

    /**
     * <p>
     * Sets the preferred indicator.
     * </p>
     * 
     * @param preferred <code>true</code> if preferred, <code>false</code>
     *        otherwise.
     */
    public void setPreferred(boolean preferred) {
        this.preferred = preferred;
    }

    /**
     * <p>
     * Sets the hidden indicator.
     * </p>
     * 
     * @param hidden <code>true</code> if hidden, <code>false</code>
     *        otherwise.
     */
    public void setHidden(boolean hidden) {
        this.hidden = hidden;
    }

    /**
     * <p>
     * Sets the expert indicator.
     * </p>
     * 
     * @param expert <code>true</code> if expert, <code>false</code>
     *        otherwise.
     */
    public void setExpert(boolean expert) {
        this.expert = expert;
    }

    /**
     * <p>
     * Indicates if this feature is preferred.
     * </p>
     * 
     * @return <code>true</code> if preferred, <code>false</code> otherwise.
     */
    public boolean isPreferred() {
        return preferred;
    }

    /**
     * <p>
     * Indicates if this feature is hidden.
     * </p>
     * 
     * @return <code>true</code> if hidden, <code>false</code> otherwise.
     */
    public boolean isHidden() {
        return hidden;
    }

    /**
     * <p>
     * Indicates if this feature is an expert feature.
     * </p>
     * 
     * @return <code>true</code> if hidden, <code>false</code> otherwise.
     */
    public boolean isExpert() {
        return expert;
    }
}

@@ -749,16 +749,45 @@
 ashMap;%0A
+import java.util.LinkedList;%0A
 import j
@@ -2257,24 +2257,87 @@
 teNames() %7B%0A
+        //Create a new list, so that the references are copied%0A
         retu
@@ -2363,16 +2363,39 @@
 eration(
+new LinkedList%3CString%3E(
 values.k
@@ -2402,16 +2402,17 @@
 eySet())
+)
 ;%0A    %7D%0A

Make a copy of the keys for enumeration.