package jacz.util.maps;

import jacz.util.lists.tuple.Duple;
import jacz.util.lists.tuple.Triple;

import java.io.Serializable;
import java.util.*;

/**
 * A map implementation with two keys. Values can be retrieved with either key.
 */
public class DoubleKeyMap<K, S, V> implements Serializable {

    private final Map<K, Triple<K, S, V>> mainMap;

    private final Map<S, Triple<K, S, V>> secondaryMap;

    public DoubleKeyMap() {
        mainMap = new HashMap<>();
        secondaryMap = new HashMap<>();
    }

    public void put(K key, S secondaryKey, V value) {
        Triple<K, S, V> tripleValue = new Triple<>(key, secondaryKey, value);
        mainMap.put(key, tripleValue);
        secondaryMap.put(secondaryKey, tripleValue);
    }

    public V get(K key) {
        return mainMap.get(key).element3;
    }

    public S getSecondaryKey(K key) {
        return mainMap.get(key).element2;
    }

    public V getSecondary(S key) {
        return secondaryMap.get(key).element3;
    }

    public K getMainKey(S key) {
        return secondaryMap.get(key).element1;
    }

    public boolean containsKey(K key) {
        return mainMap.containsKey(key);
    }

    public boolean containsSecondaryKey(S secondaryKey) {
        return secondaryMap.containsKey(secondaryKey);
    }

    public Duple<S, V> remove(K key) {
        Triple<K, S, V> tripleValue = mainMap.remove(key);
        if (tripleValue != null) {
            secondaryMap.remove(tripleValue.element2);
            return new Duple<>(tripleValue.element2, tripleValue.element3);
        } else {
            return null;
        }
    }

    public Duple<K, V> removeSecondary(S secondaryKey) {
        Triple<K, S, V> tripleValue = secondaryMap.remove(secondaryKey);
        if (tripleValue != null) {
            mainMap.remove(tripleValue.element1);
            return new Duple<>(tripleValue.element1, tripleValue.element3);
        } else {
            return null;
        }
    }

    public boolean isEmpty() {
        return size() == 0;
    }

    public int size() {
        return mainMap.size();
    }

    public Set<K> keySet() {
        return mainMap.keySet();
    }

    public Set<S> secondaryKeySet() {
        return secondaryMap.keySet();
    }

    public Collection<V> values() {
        Collection<V> values = new ArrayList<>();
        for (Triple<K, S, V> tripleValue : mainMap.values()) {
            values.add(tripleValue.element3);
        }
        return values;
    }

    public Collection<Triple<K, S, V>> entrySet() {
        return mainMap.values();
    }

}

@@ -2019,32 +2019,120 @@
 () == 0;%0A    %7D%0A%0A
+    public void clear() %7B%0A        mainMap.clear();%0A        secondaryMap.clear();%0A    %7D%0A%0A
     public int s

Add clear method to DoubleKeyMap