package org.zanata.rest.dto.resource;

import java.util.HashSet;

import javax.xml.bind.annotation.XmlRootElement;

import org.zanata.rest.dto.DTOUtil;
import org.zanata.rest.dto.ExtensionValue;


@XmlRootElement(name = "extension-set")
public class ExtensionSet<T extends ExtensionValue> extends HashSet<T>
{

   private static final long serialVersionUID = 1L;

   public <E extends T> E findByType(Class<E> clz)
   {
      for (T e : this)
      {
         if (clz.isInstance(e))
            return (E) clz.cast(e);
      }
      return null;
   }

   @Override
   public String toString()
   {
      return DTOUtil.toXML(this);
   }

   public <E extends T> E findOrAddByType(Class<E> clz)
   {
      E ext = findByType(clz);
      if (ext == null)
      {
         try
         {
            ext = clz.newInstance();
            add(ext);
         }
         catch (Throwable e)
         {
            throw new RuntimeException("unable to create instance", e);
         }
      }
      return ext;
   }

}

@@ -53,496 +53,989 @@
 til.
-HashSet;%0A%0Aimport javax.xml.bind.annotation.XmlRootElement;%0A%0Aimport org.zanata.rest.dto.DTOUtil;%0Aimport org.zanata.rest.dto.ExtensionValue;%0A%0A%0A@XmlRootElement(name = %22extension-set%22)%0Apublic class ExtensionSet%3CT extends ExtensionValue%3E extends HashSet%3CT%3E%0A%7B%0A%0A   private static final long serialVersionUID = 1L;%0A%0A   public %3CE extends T%3E E findByType(Class%3CE%3E clz)%0A   %7B%0A      for (T e : this)%0A      %7B
+AbstractCollection;%0Aimport java.util.Iterator;%0Aimport java.util.LinkedHashMap;%0Aimport java.util.Map;%0A%0Aimport javax.xml.bind.annotation.XmlRootElement;%0A%0Aimport org.apache.commons.lang.builder.EqualsBuilder;%0Aimport org.apache.commons.lang.builder.HashCodeBuilder;%0Aimport org.zanata.rest.dto.DTOUtil;%0Aimport org.zanata.rest.dto.ExtensionValue;%0A%0A%0A@XmlRootElement(name = %22extension-set%22)%0Apublic class ExtensionSet%3CT extends ExtensionValue%3E extends AbstractCollection%3CT%3E%0A%7B%0A%0A   private Map%3CClass%3C?%3E, T%3E extensions = new LinkedHashMap%3CClass%3C?%3E, T%3E();%0A   %0A   @Override%0A   public Iterator%3CT%3E iterator()%0A   %7B%0A      return extensions.values().iterator();%0A   %7D%0A   %0A   @Override%0A   public int size()%0A   %7B%0A      return extensions.size();%0A   %7D%0A   %0A   @Override%0A   public boolean add(T e) 
 %0A   
+%7B%0A
       
-if (clz.isInstance(e))
+this.extensions.put(e.getClass(), e);
 %0A      
-      return (E) clz.cast(e);%0A      %7D%0A      return null
+return true;%0A   %7D;%0A   %0A   @SuppressWarnings(%22unchecked%22)%0A   public %3CE extends T%3E E findByType(Class%3CE%3E clz)%0A   %7B%0A      return (E)this.extensions.get(clz)
 ;%0A  
@@ -1494,12 +1494,705 @@
 xt;%0A   %7D
+%0A   %0A   @Override%0A   public boolean equals(Object obj)%0A   %7B%0A      if( obj == null )%0A      %7B%0A         return false;%0A      %7D%0A      else if( !(obj instanceof ExtensionSet) )%0A      %7B%0A         return false;%0A      %7D%0A      else%0A      %7B%0A         @SuppressWarnings(%22rawtypes%22)%0A         ExtensionSet other = (ExtensionSet)obj;%0A         %0A         return new EqualsBuilder()%0A                    .append(this.extensions, other.extensions)%0A                    .isEquals();%0A      %7D%0A   %7D%0A   %0A   @Override%0A   public int hashCode()%0A   %7B%0A      HashCodeBuilder hcBuilder = new HashCodeBuilder(15, 67);%0A      for( T t : this )%0A      %7B%0A         hcBuilder.append(t);%0A      %7D%0A      return hcBuilder.toHashCode();%0A   %7D
 %0A%0A%7D%0A

Change ExtensionSet implementation.