package nl.hsac.fitnesse.fixture.util;

import fit.exception.FitFailureException;

import javax.xml.namespace.NamespaceContext;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Implementation of namespace registry for XPath expressions.
 */
public class NamespaceContextImpl implements NamespaceContext {
    private final Map<String, String> namespaces = new HashMap<String, String>();

    /**
     * Adds registration for prefix.
     * @param prefix prefix to register.
     * @param uri namespace the prefix should map to.
     * @throws FitFailureException if another uri is already registered for this prefix.
     */
    public void add(String prefix, String uri) {
        if (uri == null) {
            namespaces.remove(prefix);
        } else {
            if (namespaces.containsKey(prefix)) {
                String currentUri = namespaces.get(prefix);
                if (!currentUri.equals(uri)) {
                    throw new FitFailureException(
                                String.format("The prefix %s is already mapped to %s",
                                                prefix, currentUri));
                }
            } else {
                namespaces.put(prefix, uri);
            }
        }
    }

    @Override
    public String getNamespaceURI(String aPrefix) {
        return namespaces.get(aPrefix);
    }

    @Override
    public String getPrefix(String anUri) {
        String result = null;
        for (String key : namespaces.keySet()) {
            String uri = namespaces.get(key);
            if (uri.equals(anUri)) {
                result = key;
                break;
            }
        }
        return result;
    }

    @Override
    public Iterator<String> getPrefixes(String anUri) {
        List<String> result = new ArrayList<String>();
        for (String key : namespaces.keySet()) {
            String uri = namespaces.get(key);
            if (uri.equals(anUri)) {
                result.add(key);
            }
        }
        return result.iterator();
    }
}

@@ -2108,11 +2108,376 @@
 );%0A    %7D
+%0A%0A    @Override%0A    public boolean equals(Object o) %7B%0A        if (this == o) return true;%0A        if (o == null %7C%7C getClass() != o.getClass()) return false;%0A%0A        NamespaceContextImpl that = (NamespaceContextImpl) o;%0A%0A        return namespaces.equals(that.namespaces);%0A%0A    %7D%0A%0A    @Override%0A    public int hashCode() %7B%0A        return namespaces.hashCode();%0A    %7D
 %0A%7D%0A

Allow equals (and hashcode) to be used on our namespace impl