class VersioningUtils {

    public static final List<String> matchExpression(List<String> listVersion, String appName)
            throws VersioningException {

        if (listVersion.size() == 0) {
            return Collections.EMPTY_LIST;
        }
        String expressionVersion = getExpression(appName);

        // if using an untagged version
        if (expressionVersion == null) {
            // return the matched version if exist
            if (listVersion.contains(appName)) {
                return listVersion.subList(listVersion.indexOf(appName),
                        listVersion.indexOf(appName) + 1);
            } else {
                throw new VersioningException(
                        LOCALSTRINGS.getLocalString("versioning.deployment.version.notreg",
                        "version {0} not registered",
                        appName));
            }
        }

        // if using an identifier
        if (expressionVersion.indexOf(EXPRESSION_WILDCARD) == -1) {
            // return the matched version if exist
            if (listVersion.contains(appName)) {
                return listVersion.subList(listVersion.indexOf(appName),
                        listVersion.indexOf(appName) + 1);
            } else {
                throw new VersioningException(
                        LOCALSTRINGS.getLocalString("versioning.deployment.version.notreg",
                        "Version {0} not registered",
                        appName));
            }
        }

        StringTokenizer st = new StringTokenizer(expressionVersion,
                EXPRESSION_WILDCARD);
        String lastToken = null;
        List<String> matchedVersions = new ArrayList<String>(listVersion);

        while (st.hasMoreTokens()) {
            String token = st.nextToken();
            Iterator it = listVersion.iterator();

            while (it.hasNext()) {
                String app = (String) it.next();
                String identifier = getExpression(app);

                // get the position of the last token in the current identifier
                int lastTokenIndex = -1;
                if (lastToken != null) {
                    lastTokenIndex = identifier.indexOf(lastToken);
                }
                // matching expression on the current identifier
                if (identifier != null) {
                    if ( expressionVersion.startsWith(token)
                            && ! identifier.startsWith(token) ) {
                        matchedVersions.remove(app);
                    } else if ( expressionVersion.endsWith(token)
                            && !identifier.endsWith(token) ) {
                        matchedVersions.remove(app);
                    } else if ( !identifier.contains(token.subSequence(0, token.length() - 1))
                            || identifier.indexOf(token) <= lastTokenIndex ) {
                        matchedVersions.remove(app);
                    }
                } else {
                    matchedVersions.remove(app);
                }

            }
            lastToken = token;
        }
        // returns matched version(s)
        return matchedVersions;
    }

}