package com.dottydingo.service.endpoint.context;

import java.util.*;

/**
 */
public class MultiMap
{
    private Map<String,List<String>> map = new TreeMap<String,List<String>>(new CaseInsensitiveComparator());

    public List<String> get(String key)
    {
        if(key == null)
            throw new IllegalArgumentException("Null keys not allowed.");

        return map.get(key);
    }

    public String getFirst(String key)
    {
        if(key == null)
            throw new IllegalArgumentException("Null keys not allowed.");

        List<String> vals = map.get(key);
        if(vals == null || vals.size() == 0)
            return null;

        return vals.get(0);
    }

    public void add(String key, String value)
    {
        if(key == null)
            throw new IllegalArgumentException("Null keys not allowed.");

        if(value == null)
            throw new IllegalArgumentException("Null values not allowed.");

        List<String> vals = map.get(key);
        if(vals == null)
        {
            vals = new ArrayList<String>();
            map.put(key,vals);
        }

        vals.add(value);
    }

    public Set<String> getKeys()
    {
        return map.keySet();
    }

    private class CaseInsensitiveComparator implements Comparator<String>
    {
        @Override
        public int compare(String o1, String o2)
        {
            return o1.toLowerCase().compareTo(o2.toLowerCase());
        }
    }
}

@@ -203,24 +203,294 @@
 arator());%0A%0A
+    public MultiMap()%0A    %7B%0A    %7D%0A%0A    private MultiMap(Map%3CString, List%3CString%3E%3E map)%0A    %7B%0A        this.map = map;%0A    %7D%0A%0A    /**%0A     * Return the values associated with the key.%0A     * @param key The key%0A     * @return The values, or null if there are none.%0A     */%0A
     public L
@@ -650,32 +650,194 @@
 et(key);%0A    %7D%0A%0A
+    /**%0A     * Return the first value associated with the key.%0A     * @param key The key.%0A     * @return The first value, or null if there are no values.%0A     */%0A
     public Strin
@@ -1104,32 +1104,248 @@
 .get(0);%0A    %7D%0A%0A
+    /**%0A     * Add a value to the key. If other values are already associated with the key then this value will be added%0A     * to the existing values.%0A     * @param key The key%0A     * @param value The value%0A     */%0A
     public void 
@@ -1773,24 +1773,645 @@
 ue);%0A    %7D%0A%0A
+    /**%0A     * Return a copy of this MultiMap containing only the supplied keys%0A     * @param keys The keys to include in the copy%0A     * @return The filtered copy%0A     */%0A    public MultiMap filter(Collection%3CString%3E keys)%0A    %7B%0A        // no reason for a treemap here since we are copying by known keys%0A        Map%3CString,List%3CString%3E%3E copy = new HashMap%3CString, List%3CString%3E%3E();%0A        for (String key : keys)%0A        %7B%0A            List%3CString%3E value = map.get(key);%0A            if(value != null)%0A                copy.put(key,Collections.unmodifiableList(value));%0A        %7D%0A%0A        return new MultiMap(copy);%0A    %7D%0A%0A
     public S

Allow for filtered copies of multimaps