private boolean refuse(int[] first, int[] second, int i, Node left, Node right) {
        if (left == null && right == null) return false;
        if (i == 3) return right != null;
        int u = first[i], v = second[i];
        if (left == right) {
            Node wildcard = left.children.get(-1);
            if (wildcard != null)
                return u != v || refuse(first, second, i + 1, wildcard, wildcard);

            if ( ! left.children.tailMap(u, false).headMap(v, false).isEmpty())
                return true;

            return refuse(first, second, i + 1, left.children.get(u), left.children.get(v));
        }
        if (left != null && (left.children.containsKey(-1) || ! left.children.tailMap(u, false).isEmpty()))
            return true;

        if (right != null && (right.children.containsKey(-1) || ! right.children.headMap(v, false).isEmpty()))
            return true;

        return refuse(first, second, i + 1, left == null ? null : left.children.get(u), right == null ? null : right.children.get(v));
    }
Logic for what platform and compile versions are incompatible.

This class is instantiated with a list of versions which are only compatible with other versions
that are not older than themselves. Each entry in this list is represented by a string, and any
major, minor or micro with the value @{code *} means all versions are such boundaries.
Versions A, B are incompatible iff. there exists an incompatibility boundary X such that
(A &ge; X) &ne; (B &ge; X).

@author jonmv
component/src/main/java/com/yahoo/component/VersionCompatibility.java