ArgExtractor::ArgExtractor(const NumberFormat& nf, const Formattable& obj, UErrorCode& status)
    : ncnf((NumberFormat*) &nf), num(&obj), setCurr(FALSE) {

    const UObject* o = obj.getObject(); // most commonly o==NULL
    const CurrencyAmount* amt;
    if (o != NULL && (amt = dynamic_cast<const CurrencyAmount*>(o)) != NULL) {
        // getISOCurrency() returns a pointer to internal storage, so we
        // copy it to retain it across the call to setCurrency().
        const UChar* curr = amt->getISOCurrency();
        u_strcpy(save, nf.getCurrency());
        setCurr = (u_strcmp(curr, save) != 0);
        if (setCurr) {
            ncnf->setCurrency(curr, status);
        }
        num = &amt->getNumber();
    }
}
std::string GlobalizationNDK::getCurrencyPattern(const std::string& args)
{
    if (args.empty()) {
        slog2f(0, ID_G11N, SLOG2_ERROR, "GlobalizationNDK::getCurrencyPattern: no arguments provided!");
        return errorInJson(UNKNOWN_ERROR, "No arguments provided!");
    }

    Json::Reader reader;
    Json::Value root;
    bool parse = reader.parse(args, root);

    if (!parse) {
        slog2f(0, ID_G11N, SLOG2_ERROR, "GlobalizationNDK::getCurrencyPattern: invalid json data: %s",
                args.c_str());
        return errorInJson(PARSING_ERROR, "Invalid json data!");
    }

    Json::Value ccv = root["currencyCode"];
    if (ccv.isNull()) {
        slog2f(0, ID_G11N, SLOG2_ERROR, "GlobalizationNDK::getCurrencyPattern: no currencyCode provided!");
        return errorInJson(FORMATTING_ERROR, "No currencyCode provided!");
    }

    if (!ccv.isString()) {
        slog2f(0, ID_G11N, SLOG2_ERROR, "GlobalizationNDK::getCurrencyPattern: invalid currencyCode type: %d!",
                ccv.type());
        return errorInJson(FORMATTING_ERROR, "Invalid currencyCode type!");
    }

    std::string cc = ccv.asString();
    if (cc.empty()) {
        slog2f(0, ID_G11N, SLOG2_ERROR, "GlobalizationNDK::getCurrencyPattern: empty currencyCode!");
        return errorInJson(FORMATTING_ERROR, "Empty currencyCode!");
    }

    UnicodeString ucc = UnicodeString::fromUTF8(cc);
    DecimalFormat* df = 0;
    int count = 0;
    const Locale* locs = Locale::getAvailableLocales(count);
    for (int i = 0; i < count; ++i) {
        UErrorCode status = U_ZERO_ERROR;
        NumberFormat* nf = NumberFormat::createCurrencyInstance(*(locs + i), status);
        if (!nf) {
            slog2f(0, ID_G11N, SLOG2_ERROR, "GlobalizationNDK::getCurrencyPattern: locale %d: unable to get NumberFormat instance!",
                    i);
            continue;
        }
        std::auto_ptr<NumberFormat> ndeleter(nf);

        const UChar* currency = nf->getCurrency();
        if (!currency) {
            slog2f(0, ID_G11N, SLOG2_ERROR, "GlobalizationNDK::getCurrencyPattern: locale %d: failed to getCurrency!",
                    i);
            continue;
        }

        if (!ucc.compare(currency, -1)) {
            df = (DecimalFormat*) ndeleter.release();
            break;
        }
    }

    if (!df)
        return errorInJson(UNKNOWN_ERROR, "Currency not supported!");

    std::auto_ptr<DecimalFormat> deleter(df);

    const DecimalFormatSymbols* dfs = df->getDecimalFormatSymbols();
    if (!dfs) {
        slog2f(0, ID_G11N, SLOG2_ERROR, "GlobalizationNDK::getCurrencyPattern: unable to get DecimalFormatSymbols!");
        return errorInJson(UNKNOWN_ERROR, "Failed to get DecimalFormatSymbols!");
    }

    UnicodeString ucs;

    std::string pattern;
    df->toPattern(ucs);
    ucs.toUTF8String(pattern);
    ucs.remove();

    int fraction = df->getMaximumFractionDigits();
    double rounding = df->getRoundingIncrement();

    std::string decimal;
    ucs = dfs->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
    ucs.toUTF8String(decimal);
    ucs.remove();

    std::string grouping;
    ucs = dfs->getSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol);
    ucs.toUTF8String(grouping);
    ucs.remove();

    return resultInJson(pattern, cc, fraction, rounding, decimal, grouping);
}