/*
 * JBoss, Home of Professional Open Source
 * Copyright 2008, Red Hat, Inc. and/or its affiliates, and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * 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 org.jboss.weld.util.collections;

import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * A {@link java.util.Map} that can contain multiple values, where the keys
 * and values are stored in {@link ArraySet} instances.
 *
 * @author David Allen
 */
public class ArraySetMultimap<K, V> extends AbstractMap<K, List<V>> {
    private ArraySet<Map.Entry<K, List<V>>> entrySet = new ArraySet<Map.Entry<K, List<V>>>();

    public ArraySetMultimap() {

    }

    public ArraySetMultimap(Map<K, List<V>> map) {
        // Add entries from the given map to this one
    }

    @Override
    public List<V> get(Object key) {
        List<V> result = super.get(key);
        if (result == null) {
            result = Collections.emptyList();
        }
        return result;
    }

    // Workaround bug in Helios
    public List<V> putSingleElement(K key, V value) {
        List<V> result = super.get(key);
        if (result == null) {
            result = new ArrayList<V>();
            SimpleEntry<K, List<V>> entry = new SimpleEntry<K, List<V>>(key, result);
            entrySet.add(entry);
        }
        result.add(value);
        return result;
    }

    public void trimToSize() {
        for (Map.Entry<K, List<V>> entry : this.entrySet()) {
            ((ArrayList<V>) entry.getValue()).trimToSize();
        }
    }

    @Override
    public Set<java.util.Map.Entry<K, List<V>>> entrySet() {
        return entrySet;
    }
}

@@ -1891,22 +1891,19 @@
         
-Simple
+Map
 Entry%3CK,
@@ -1928,14 +1928,11 @@
 new 
-Simple
+Map
 Entr
@@ -2335,10 +2335,1145 @@
 ;%0A    %7D%0A
-%7D
 %0A
+    static class MapEntry%3CK, V%3E implements Map.Entry%3CK, V%3E %7B%0A        private K key;%0A        private V value;%0A%0A        MapEntry(K key, V value) %7B%0A            this.key = key;%0A            this.value = value;%0A        %7D%0A%0A        public K getKey() %7B%0A            return key;%0A        %7D%0A%0A        public V getValue() %7B%0A            return value;%0A        %7D%0A%0A        public V setValue(V value) %7B%0A            V previous = this.value;%0A            this.value = value;%0A            return previous;%0A        %7D%0A%0A        @Override%0A        public int hashCode() %7B%0A            return (key == null ? 0 : key.hashCode()) %5E (value == null ? 0 : value.hashCode());%0A        %7D%0A%0A        @Override%0A        public boolean equals(Object o) %7B%0A            if (o instanceof Map.Entry == false) %7B%0A                return false;%0A            %7D%0A%0A            Map.Entry e = (Map.Entry) o;%0A%0A            return (key == null ? e.getKey() == null : key.equals(e.getKey())) &&%0A                   (value == null ? e.getValue() == null : value.equals(e.getValue()));%0A        %7D%0A%0A        @Override%0A        public String toString() %7B%0A            return key + %22=%22 + value;%0A        %7D%0A    %7D%0A%7D

Use custom Map.Entry impl.