class MatchingAttributeName {

    private final TemplateMode templateMode;
    private final AttributeName matchingAttributeName;
    private final String matchingAllAttributesWithPrefix;
    private final boolean matchingAllAttributes;



    public static MatchingAttributeName forAttributeName(final TemplateMode templateMode, final AttributeName matchingAttributeName) {
        Validate.notNull(templateMode, "Template mode cannot be null");
        Validate.notNull(matchingAttributeName, "Matching attribute name cannot be null");
        if (templateMode == TemplateMode.HTML && !(matchingAttributeName instanceof HTMLAttributeName)) {
            throw new IllegalArgumentException("Attribute names for HTML template mode must be of class " + HTMLAttributeName.class.getName());
        } else if (templateMode == TemplateMode.XML && !(matchingAttributeName instanceof XMLAttributeName)) {
            throw new IllegalArgumentException("Attribute names for XML template mode must be of class " + XMLAttributeName.class.getName());
        } else if (templateMode.isText() && !(matchingAttributeName instanceof TextAttributeName)) {
            throw new IllegalArgumentException("Attribute names for any text template modes must be of class " + TextAttributeName.class.getName());
        }
        return new MatchingAttributeName(templateMode, matchingAttributeName, null, false);
    }


    public static MatchingAttributeName forAllAttributesWithPrefix(final TemplateMode templateMode, final String matchingAllAttributesWithPrefix) {<FILL_FUNCTION_BODY>}


    public static MatchingAttributeName forAllAttributes(final TemplateMode templateMode) {
        Validate.notNull(templateMode, "Template mode cannot be null");
        return new MatchingAttributeName(templateMode, null, null, true);
    }



    private MatchingAttributeName(
            final TemplateMode templateMode, final AttributeName matchingAttributeName,
            final String matchingAllAttributesWithPrefix, final boolean matchingAllAttributes) {
        super();
        this.templateMode = templateMode;
        this.matchingAttributeName = matchingAttributeName;
        this.matchingAllAttributesWithPrefix = matchingAllAttributesWithPrefix;
        this.matchingAllAttributes = matchingAllAttributes;
    }




    public TemplateMode getTemplateMode() {
        return this.templateMode;
    }


    public AttributeName getMatchingAttributeName() {
        return this.matchingAttributeName;
    }


    public String getMatchingAllAttributesWithPrefix() {
        return this.matchingAllAttributesWithPrefix;
    }


    public boolean isMatchingAllAttributes() {
        return this.matchingAllAttributes;
    }




    public boolean matches(final AttributeName attributeName) {

        Validate.notNull(attributeName, "Attributes name cannot be null");

        if (this.matchingAttributeName == null) {

            if (this.templateMode == TemplateMode.HTML && !(attributeName instanceof HTMLAttributeName)) {
                return false;
            } else if (this.templateMode == TemplateMode.XML && !(attributeName instanceof XMLAttributeName)) {
                return false;
            } else if (this.templateMode.isText() && !(attributeName instanceof TextAttributeName)) {
                return false;
            }

            if (this.matchingAllAttributes) {
                return true;
            }

            if (this.matchingAllAttributesWithPrefix == null) {
                return attributeName.getPrefix() == null;
            }

            final String attributeNamePrefix = attributeName.getPrefix();
            if (attributeNamePrefix == null) {
                return false; // we already checked we are not matching nulls
            }

            return TextUtils.equals(this.templateMode.isCaseSensitive(), this.matchingAllAttributesWithPrefix, attributeNamePrefix);

        }

        return this.matchingAttributeName.equals(attributeName);

    }



    @Override
    public String toString() {
        if (this.matchingAttributeName == null) {
            if (this.matchingAllAttributes) {
                return "*";
            }
            if (this.matchingAllAttributesWithPrefix == null) {
                return "[^:]*";
            }
            return this.matchingAllAttributesWithPrefix + ":*";
        }
        return matchingAttributeName.toString();
    }


}

        Validate.notNull(templateMode, "Template mode cannot be null");
        // Prefix can actually be null -> match all attributes with no prefix
        return new MatchingAttributeName(templateMode, null, matchingAllAttributesWithPrefix, false);
    
<no_super_class>