public <T> void removeAttribute(AttributeKey<T> key) {
   if (hasAttribute(key)) {
     T oldValue = key.get(this);
     attributes.remove(key);
     fireAttributeChanged(key, oldValue, key.getDefaultValue());
   }
 }
  protected void writeAttributes(DOMOutput out) throws IOException {
    Figure prototype = (Figure) out.getPrototype();

    boolean isElementOpen = false;
    for (Map.Entry<AttributeKey, Object> entry : attributes.entrySet()) {
      AttributeKey key = entry.getKey();
      if (forbiddenAttributes == null || !forbiddenAttributes.contains(key)) {
        Object prototypeValue = key.get(prototype);
        Object attributeValue = key.get(this);
        if (prototypeValue != attributeValue
            || (prototypeValue != null
                && attributeValue != null
                && !prototypeValue.equals(attributeValue))) {
          if (!isElementOpen) {
            out.openElement("a");
            isElementOpen = true;
          }
          out.openElement(key.getKey());
          out.writeObject(entry.getValue());
          out.closeElement();
        }
      }
    }
    if (isElementOpen) {
      out.closeElement();
    }
  }
 @SuppressWarnings("unchecked")
 protected void readAttributes(DOMInput in) throws IOException {
   if (in.getElementCount("a") > 0) {
     in.openElement("a");
     for (int i = in.getElementCount() - 1; i >= 0; i--) {
       in.openElement(i);
       String name = in.getTagName();
       Object value = in.readObject();
       AttributeKey key = getAttributeKey(name);
       if (key != null && key.isAssignable(value)) {
         if (forbiddenAttributes == null || !forbiddenAttributes.contains(key)) {
           setAttribute(key, value);
         }
       }
       in.closeElement();
     }
     in.closeElement();
   }
 }
 /** Gets an attribute from the figure. */
 public <T> T getAttribute(AttributeKey<T> key) {
   return hasAttribute(key) ? key.get(attributes) : key.getDefaultValue();
 }
 /**
  * Sets an attribute of the figure. AttributeKey name and semantics are defined by the class
  * implementing the figure interface.
  */
 public <T> void setAttribute(AttributeKey<T> key, T newValue) {
   if (forbiddenAttributes == null || !forbiddenAttributes.contains(key)) {
     T oldValue = (T) key.put(attributes, newValue);
     fireAttributeChanged(key, oldValue, newValue);
   }
 }