class CurrencyConverter implements PropertyConverter<Currency> {

    @Override
    public Currency convert(String value, ConversionContext ctx) {
        ctx.addSupportedFormats(getClass(), "<currencyCode>, using Locale.ENGLISH", "<numericValue>",
                "<locale>");
        if(value==null){
            return null;
        }
        String trimmed = value.trim();
        try {
            return Currency.getInstance(trimmed.toUpperCase(Locale.ENGLISH));
        } catch (Exception e) {
            LOG.log(Level.FINEST, "Not a valid textual currency code: " + trimmed + ", checking for numeric...", e);
        }
        try {
            // Check for numeric code
            Integer numCode = Integer.parseInt(trimmed);
            for (Currency currency : Currency.getAvailableCurrencies()) {
                if (currency.getNumericCode() == numCode) {
                    return currency;
                }
            }
        } catch (Exception e) {
            LOG.log(Level.FINEST, "Not a valid numeric currency code: " + trimmed + ", checking for locale...", e);
        }
        try {
            // Check for numeric code
            String[] parts = trimmed.split("\\_");
            Locale locale;
            switch (parts.length) {
                case 1:
                    locale = new Locale("", parts[0]);
                    break;
                case 2:
                    locale = new Locale(parts[0], parts[1]);
                    break;
                case 3:
                    locale = new Locale(parts[0], parts[1], parts[2]);
                    break;
                default:
                    locale = null;
            }
            if (locale != null) {
                return Currency.getInstance(locale);
            }
            LOG.finest("Not a valid currency: " + trimmed + ", giving up...");
        } catch (Exception e) {
            LOG.log(Level.FINEST, "Not a valid country locale for currency: " + trimmed + ", giving up...", e);
        }
        return null;
    }

}