protected static boolean compareUpdateAttributes(String left, String right) {
        //the numbers below come from the CPE Matching standard
        //Table 6-2: Enumeration of Attribute Comparison Set Relations
        //https://nvlpubs.nist.gov/nistpubs/Legacy/IR/nistir7696.pdf

        if (left.equalsIgnoreCase(right)) {
            //1 6 9 - equals
            return true;
        } else if (LogicalValue.ANY.getAbbreviation().equals(left)) {
            //2 3 4 - superset (4 is undefined - treating as true)
            return true;
        } else if (LogicalValue.NA.getAbbreviation().equals(left)
                && LogicalValue.ANY.getAbbreviation().equals(right)) {
            //5 - subset
            return true;
        } else if (LogicalValue.NA.getAbbreviation().equals(left)) {
            //7 8 - disjoint, undefined
            return false;
        } else if (LogicalValue.NA.getAbbreviation().equals(right)) {
            //12 16 - disjoint
            return false;
        } else if (LogicalValue.ANY.getAbbreviation().equals(right)) {
            //13 15 - subset
            return true;
        }
        final String leftValue = left.replace("-", "").replace("_", "");
        final String rightValue = right.replace("-", "").replace("_", "");
        if (leftValue.equalsIgnoreCase(rightValue)) {
            //1 6 9 - equals
            return true;
        }

        boolean results = false;
        //10 11 14 17
        if (containsSpecialCharacter(left)) {
            final Pattern p = Convert.wellFormedToPattern(left.toLowerCase());
            final Matcher m = p.matcher(right.toLowerCase());
            results = m.matches();
        }
        if (!results && rightValue.matches("^[abu]\\d.*") && leftValue.matches("^(update|alpha|beta).*")) {
            switch (right.charAt(0)) {
                case 'u':
                    results = compareUpdateAttributes(leftValue, "update" + rightValue.substring(1));
                    break;
                case 'a':
                    results = compareUpdateAttributes(leftValue, "alpha" + rightValue.substring(1));
                    break;
                case 'b':
                    results = compareUpdateAttributes(leftValue, "beta" + rightValue.substring(1));
                    break;
                default:
                    break;
            }
        }
        if (!results && leftValue.matches("^[abu]\\d.*") && rightValue.matches("^(update|alpha|beta).*")) {
            switch (left.charAt(0)) {
                case 'u':
                    results = compareUpdateAttributes("update" + leftValue.substring(1), rightValue);
                    break;
                case 'a':
                    results = compareUpdateAttributes("alpha" + leftValue.substring(1), rightValue);
                    break;
                case 'b':
                    results = compareUpdateAttributes("beta" + leftValue.substring(1), rightValue);
                    break;
                default:
                    break;
            }
        }
        return results;
    }
@Test
    public void testcompareUpdateAttributes() throws CpeValidationException {

        assertTrue(VulnerableSoftware.compareUpdateAttributes("update1", "u1"));
        assertTrue(VulnerableSoftware.compareUpdateAttributes("u1", "update1"));
        assertTrue(VulnerableSoftware.compareUpdateAttributes("u1", "update-1"));
        assertTrue(VulnerableSoftware.compareUpdateAttributes("a1", "alpha1"));
        assertTrue(VulnerableSoftware.compareUpdateAttributes("alpha-1", "alpha1"));
        assertTrue(VulnerableSoftware.compareUpdateAttributes("b-1", "beta1"));
        assertFalse(VulnerableSoftware.compareUpdateAttributes("a1", "beta1"));

    }