int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
		unsigned long addr, pgprot_t newprot, int prot_numa)
{
	struct mm_struct *mm = vma->vm_mm;
	spinlock_t *ptl;
	pmd_t entry;
	bool preserve_write;
	int ret;

	ptl = __pmd_trans_huge_lock(pmd, vma);
	if (!ptl)
		return 0;

	preserve_write = prot_numa && pmd_write(*pmd);
	ret = 1;

#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
	if (is_swap_pmd(*pmd)) {
		swp_entry_t entry = pmd_to_swp_entry(*pmd);

		VM_BUG_ON(!is_pmd_migration_entry(*pmd));
		if (is_write_migration_entry(entry)) {
			pmd_t newpmd;
			/*
			 * A protection check is difficult so
			 * just be safe and disable write
			 */
			make_migration_entry_read(&entry);
			newpmd = swp_entry_to_pmd(entry);
			if (pmd_swp_soft_dirty(*pmd))
				newpmd = pmd_swp_mksoft_dirty(newpmd);
			set_pmd_at(mm, addr, pmd, newpmd);
		}
		goto unlock;
	}
#endif

	/*
	 * Avoid trapping faults against the zero page. The read-only
	 * data is likely to be read-cached on the local CPU and
	 * local/remote hits to the zero page are not interesting.
	 */
	if (prot_numa && is_huge_zero_pmd(*pmd))
		goto unlock;

	if (prot_numa && pmd_protnone(*pmd))
		goto unlock;

	/*
	 * In case prot_numa, we are under down_read(mmap_sem). It's critical
	 * to not clear pmd intermittently to avoid race with MADV_DONTNEED
	 * which is also under down_read(mmap_sem):
	 *
	 *	CPU0:				CPU1:
	 *				change_huge_pmd(prot_numa=1)
	 *				 pmdp_huge_get_and_clear_notify()
	 * madvise_dontneed()
	 *  zap_pmd_range()
	 *   pmd_trans_huge(*pmd) == 0 (without ptl)
	 *   // skip the pmd
	 *				 set_pmd_at();
	 *				 // pmd is re-established
	 *
	 * The race makes MADV_DONTNEED miss the huge pmd and don't clear it
	 * which may break userspace.
	 *
	 * pmdp_invalidate() is required to make sure we don't miss
	 * dirty/young flags set by hardware.
	 */
	entry = pmdp_invalidate(vma, addr, pmd);

	entry = pmd_modify(entry, newprot);
	if (preserve_write)
		entry = pmd_mk_savedwrite(entry);
	ret = HPAGE_PMD_NR;
	set_pmd_at(mm, addr, pmd, entry);
	BUG_ON(vma_is_anonymous(vma) && !preserve_write && pmd_write(entry));
unlock:
	spin_unlock(ptl);
	return ret;
}


static void take_rmap_locks(struct vm_area_struct *vma)
{
	if (vma->vm_file)
		i_mmap_lock_write(vma->vm_file->f_mapping);
	if (vma->anon_vma)
		anon_vma_lock_write(vma->anon_vma);
}


snmpCreateOidFromStr(const char *str, oid **name, int *nl)
{
    char const *delim = ".";

    *name = NULL;
    *nl = 0;
    const char *s = str;

    /* Parse the OID string into oid bits */
    while (size_t len = strcspn(s, delim)) {
        *name = (oid*)xrealloc(*name, sizeof(oid) * ((*nl) + 1));
        (*name)[*nl] = atoi(s); // stops at the '.' delimiter
        ++(*nl);
        // exit with true when the last octet has been parsed
        if (s[len] == '\0')
            return true;
        s += len+1;
    }

    // if we aborted before the lst octet was found, return false.
    safe_free(name);
    return false;
}


ACLSNMPCommunityStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &)
{
    return data->match (checklist->snmp_community);
}


    Image::AutoPtr ImageFactory::open(BasicIo::AutoPtr io)
    {
        if (io->open() != 0) {
            throw Error(kerDataSourceOpenFailed, io->path(), strError());
        }
        for (unsigned int i = 0; registry[i].imageType_ != ImageType::none; ++i) {
            if (registry[i].isThisType_(*io, false)) {
                return registry[i].newInstance_(io, false);
            }
        }
        return Image::AutoPtr();
    } // ImageFactory::open


int ras_encode(jas_image_t *image, jas_stream_t *out, const char *optstr)
{
	int_fast32_t width;
	int_fast32_t height;
	int_fast32_t depth;
	int cmptno;
	int i;
	ras_hdr_t hdr;
	int rowsize;
	ras_enc_t encbuf;
	ras_enc_t *enc = &encbuf;

	JAS_DBGLOG(10, ("ras_encode(%p, %p, \"%s\"\n", image, out,
	  optstr ? optstr : ""));

	if (optstr) {
		jas_eprintf("warning: ignoring RAS encoder options\n");
	}

	switch (jas_clrspc_fam(jas_image_clrspc(image))) {
	case JAS_CLRSPC_FAM_RGB:
		if (jas_image_clrspc(image) != JAS_CLRSPC_SRGB)
			jas_eprintf("warning: inaccurate color\n");
		enc->numcmpts = 3;
		if ((enc->cmpts[0] = jas_image_getcmptbytype(image,
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R))) < 0 ||
		  (enc->cmpts[1] = jas_image_getcmptbytype(image,
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G))) < 0 ||
		  (enc->cmpts[2] = jas_image_getcmptbytype(image,
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B))) < 0) {
			jas_eprintf("error: missing color component\n");
			return -1;
		}
		break;
	case JAS_CLRSPC_FAM_GRAY:
		if (jas_image_clrspc(image) != JAS_CLRSPC_SGRAY)
			jas_eprintf("warning: inaccurate color\n");
		enc->numcmpts = 1;
		if ((enc->cmpts[0] = jas_image_getcmptbytype(image,
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y))) < 0) {
			jas_eprintf("error: missing color component\n");
			return -1;
		}
		break;
	default:
		jas_eprintf("error: unsupported color space\n");
		return -1;
		break;
	}

	width = jas_image_cmptwidth(image, enc->cmpts[0]);
	height = jas_image_cmptheight(image, enc->cmpts[0]);
	depth = jas_image_cmptprec(image, enc->cmpts[0]);

	for (cmptno = 0; cmptno < enc->numcmpts; ++cmptno) {
		if (jas_image_cmptwidth(image, enc->cmpts[cmptno]) != width ||
		  jas_image_cmptheight(image, enc->cmpts[cmptno]) != height ||
		  jas_image_cmptprec(image, enc->cmpts[cmptno]) != depth ||
		  jas_image_cmptsgnd(image, enc->cmpts[cmptno]) != false ||
		  jas_image_cmpttlx(image, enc->cmpts[cmptno]) != 0 ||
		  jas_image_cmpttly(image, enc->cmpts[cmptno]) != 0) {
			jas_eprintf("The RAS format cannot be used to represent an image with this geometry.\n");
			return -1;
		}
	}

	/* Ensure that the image can be encoded in the desired format. */
	if (enc->numcmpts == 3) {

		/* All three components must have the same subsampling
		  factor and have a precision of eight bits. */
		if (enc->numcmpts > 1) {
			for (i = 0; i < enc->numcmpts; ++i) {
				if (jas_image_cmptprec(image, enc->cmpts[i]) != 8) {
					return -1;
				}
			}
		}
	} else if (enc->numcmpts == 1) {
		/* NOP */
	} else {
		return -1;
	}

	hdr.magic = RAS_MAGIC;
	hdr.width = width;
	hdr.height = height;
	hdr.depth = (enc->numcmpts == 3) ? 24 : depth;

	rowsize = RAS_ROWSIZE(&hdr);
	hdr.length = rowsize * hdr.height;
	hdr.type = RAS_TYPE_STD;

	hdr.maptype = RAS_MT_NONE;
	hdr.maplength = 0;

	if (ras_puthdr(out, &hdr)) {
		return -1;
	}

	if (ras_putdata(out, &hdr, image, enc->numcmpts, enc->cmpts)) {
		return -1;
	}

	return 0;
}


static int ras_putdatastd(jas_stream_t *out, ras_hdr_t *hdr, jas_image_t *image,  int numcmpts, int *cmpts)
{
	int rowsize;
	int pad;
	unsigned int z;
	int nz;
	int c;
	int x;
	int y;
	int v;
	jas_matrix_t *data[3];
	int i;

	assert(numcmpts <= 3);

	if (RAS_ISRGB(hdr) && numcmpts < 3) {
		/* need 3 components for RGB */
		return -1;
	}

	for (i = 0; i < 3; ++i) {
		data[i] = 0;
	}

	for (i = 0; i < numcmpts; ++i) {
		if (!(data[i] = jas_matrix_create(jas_image_height(image),
		  jas_image_width(image)))) {
			goto error;
		}
	}

	rowsize = RAS_ROWSIZE(hdr);
	pad = rowsize - (hdr->width * hdr->depth + 7) / 8;

	hdr->length = hdr->height * rowsize;

	for (y = 0; y < hdr->height; y++) {
		for (i = 0; i < numcmpts; ++i) {
			if (jas_image_readcmpt(image, cmpts[i], 0, y,
					jas_image_width(image), 1, data[i])) {
				goto error;
			}
		}
		z = 0;
		nz = 0;
		for (x = 0; x < hdr->width; x++) {
			z <<= hdr->depth;
			if (RAS_ISRGB(hdr)) {
				v = RAS_RED((jas_matrix_getv(data[0], x))) |
				  RAS_GREEN((jas_matrix_getv(data[1], x))) |
				  RAS_BLUE((jas_matrix_getv(data[2], x)));
			} else {
				v = (jas_matrix_getv(data[0], x));
			}
			z |= v & RAS_ONES(hdr->depth);
			nz += hdr->depth;
			while (nz >= 8) {
				c = (z >> (nz - 8)) & 0xff;
				if (jas_stream_putc(out, c) == EOF) {
					goto error;
				}
				nz -= 8;
				z &= RAS_ONES(nz);
			}
		}
		if (nz > 0) {
			c = (z >> (8 - nz)) & RAS_ONES(nz);
			if (jas_stream_putc(out, c) == EOF) {
				goto error;
			}
		}
		if (pad % 2) {
			if (jas_stream_putc(out, 0) == EOF) {
				goto error;
			}
		}
	}

	for (i = 0; i < numcmpts; ++i) {
		jas_matrix_destroy(data[i]);
		data[i] = 0;
	}

	return 0;

error:
	for (i = 0; i < numcmpts; ++i) {
		if (data[i]) {
			jas_matrix_destroy(data[i]);
		}
	}
	return -1;
}


Formattable::operator=(const Formattable& source)
{
    if (this != &source)
    {
        // Disposes the current formattable value/setting.
        dispose();

        // Sets the correct data type for this value.
        fType = source.fType;
        switch (fType)
        {
        case kArray:
            // Sets each element in the array one by one and records the array count.
            fValue.fArrayAndCount.fCount = source.fValue.fArrayAndCount.fCount;
            fValue.fArrayAndCount.fArray = createArrayCopy(source.fValue.fArrayAndCount.fArray,
                                                           source.fValue.fArrayAndCount.fCount);
            break;
        case kString:
            // Sets the string value.
            fValue.fString = new UnicodeString(*source.fValue.fString);
            break;
        case kDouble:
            // Sets the double value.
            fValue.fDouble = source.fValue.fDouble;
            break;
        case kLong:
        case kInt64:
            // Sets the long value.
            fValue.fInt64 = source.fValue.fInt64;
            break;
        case kDate:
            // Sets the Date value.
            fValue.fDate = source.fValue.fDate;
            break;
        case kObject:
            fValue.fObject = objectClone(source.fValue.fObject);
            break;
        }

        UErrorCode status = U_ZERO_ERROR;
        if (source.fDecimalQuantity != NULL) {
          fDecimalQuantity = new DecimalQuantity(*source.fDecimalQuantity);
        }
        if (source.fDecimalStr != NULL) {
            fDecimalStr = new CharString(*source.fDecimalStr, status);
            if (U_FAILURE(status)) {
                delete fDecimalStr;
                fDecimalStr = NULL;
            }
        }
    }
    return *this;
}


Formattable::Formattable() {
    init();
}


virtual Format* clone() const {return NULL;}


inline int32_t safeSubtract(int32_t a, int32_t b) {
    // Note: In C++, signed integer subtraction is undefined behavior.
    int32_t diff = static_cast<int32_t>(static_cast<uint32_t>(a) - static_cast<uint32_t>(b));
    if (b < 0 && diff < a) { return INT32_MAX; }
    if (b > 0 && diff > a) { return INT32_MIN; }
    return diff;
}


void NumberFormatTest::expectPad(DecimalFormat& fmt, const UnicodeString& pat,
                                 int32_t pos) {
    expectPad(fmt, pat, pos, 0, (UnicodeString)"");
}


uint64_t DecimalQuantity::toFractionLong(bool includeTrailingZeros) const {
    uint64_t result = 0L;
    int32_t magnitude = -1;
    int32_t lowerMagnitude = std::max(scale, rOptPos);
    if (includeTrailingZeros) {
        lowerMagnitude = std::min(lowerMagnitude, rReqPos);
    }
    for (; magnitude >= lowerMagnitude && result <= 1e18L; magnitude--) {
        result = result * 10 + getDigitPos(magnitude - scale);
    }
    // Remove trailing zeros; this can happen during integer overflow cases.
    if (!includeTrailingZeros) {
        while (result > 0 && (result % 10) == 0) {
            result /= 10;
        }
    }
    return result;
}


void NumberFormatTest::expectPosition(FieldPosition& pos, int32_t id, int32_t start, int32_t limit,
                                       const UnicodeString& str)  {
  logln(str);
  assertTrue((UnicodeString)"id " + id + " == " + pos.getField(), id == pos.getField());
  assertTrue((UnicodeString)"begin " + start + " == " + pos.getBeginIndex(), start == pos.getBeginIndex());
  assertTrue((UnicodeString)"end " + limit + " == " + pos.getEndIndex(), limit == pos.getEndIndex());
}


void NumberFormatTest::TestPatterns2(void) {
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormatSymbols US(Locale::getUS(), status);
    CHECK(status, "DecimalFormatSymbols constructor");

    DecimalFormat fmt("#", US, status);
    CHECK(status, "DecimalFormat constructor");

    UChar hat = 0x005E; /*^*/

    expectPad(fmt, "*^#", DecimalFormat::kPadBeforePrefix, 1, hat);
    expectPad(fmt, "$*^#", DecimalFormat::kPadAfterPrefix, 2, hat);
    expectPad(fmt, "#*^", DecimalFormat::kPadBeforeSuffix, 1, hat);
    expectPad(fmt, "#$*^", DecimalFormat::kPadAfterSuffix, 2, hat);
    expectPad(fmt, "$*^$#", ILLEGAL);
    expectPad(fmt, "#$*^$", ILLEGAL);
    expectPad(fmt, "'pre'#,##0*x'post'", DecimalFormat::kPadBeforeSuffix,
              12, (UChar)0x0078 /*x*/);
    expectPad(fmt, "''#0*x", DecimalFormat::kPadBeforeSuffix,
              3, (UChar)0x0078 /*x*/);
    expectPad(fmt, "'I''ll'*a###.##", DecimalFormat::kPadAfterPrefix,
              10, (UChar)0x0061 /*a*/);

    fmt.applyPattern("AA#,##0.00ZZ", status);
    CHECK(status, "applyPattern");
    fmt.setPadCharacter(hat);

    fmt.setFormatWidth(10);

    fmt.setPadPosition(DecimalFormat::kPadBeforePrefix);
    expectPat(fmt, "*^AA#,##0.00ZZ");

    fmt.setPadPosition(DecimalFormat::kPadBeforeSuffix);
    expectPat(fmt, "AA#,##0.00*^ZZ");

    fmt.setPadPosition(DecimalFormat::kPadAfterSuffix);
    expectPat(fmt, "AA#,##0.00ZZ*^");

    //            12  3456789012
    UnicodeString exp("AA*^#,##0.00ZZ", "");
    fmt.setFormatWidth(12);
    fmt.setPadPosition(DecimalFormat::kPadAfterPrefix);
    expectPat(fmt, exp);

    fmt.setFormatWidth(13);
    //              12  34567890123
    expectPat(fmt, "AA*^##,##0.00ZZ");

    fmt.setFormatWidth(14);
    //              12  345678901234
    expectPat(fmt, "AA*^###,##0.00ZZ");

    fmt.setFormatWidth(15);
    //              12  3456789012345
    expectPat(fmt, "AA*^####,##0.00ZZ"); // This is the interesting case

    fmt.setFormatWidth(16);
    //              12  34567890123456
    expectPat(fmt, "AA*^#####,##0.00ZZ");
}


void DecimalQuantity::multiplyBy(const DecNum& multiplicand, UErrorCode& status) {
    if (isInfinite() || isZero() || isNaN()) {
        return;
    }
    // Convert to DecNum, multiply, and convert back.
    DecNum decnum;
    toDecNum(decnum, status);
    if (U_FAILURE(status)) { return; }
    decnum.multiplyBy(multiplicand, status);
    if (U_FAILURE(status)) { return; }
    setToDecNum(decnum, status);
}


void NumberFormatTest::Test20073_StrictPercentParseErrorIndex() {
    IcuTestErrorCode status(*this, "Test20073_StrictPercentParseErrorIndex");
    ParsePosition parsePosition(0);
    DecimalFormat df(u"0%", {"en-us", status}, status);
    if (U_FAILURE(status)) {
        dataerrln("Unable to create DecimalFormat instance.");
        return;
    }
    df.setLenient(FALSE);
    Formattable result;
    df.parse(u"%2%", result, parsePosition);
    assertEquals("", 0, parsePosition.getIndex());
    assertEquals("", 0, parsePosition.getErrorIndex());
}


ufmt_getDecNumChars(UFormattable *fmt, int32_t *len, UErrorCode *status) {
  if(U_FAILURE(*status)) {
    return "";
  }
  Formattable *obj = Formattable::fromUFormattable(fmt);
  CharString *charString = obj->internalGetCharString(*status);
  if(U_FAILURE(*status)) {
    return "";
  }
  if(charString == NULL) {
    *status = U_MEMORY_ALLOCATION_ERROR;
    return "";
  } else {
    if(len!=NULL) {
      *len = charString->length();
    }
    return charString->data();
  }
}


void NumberFormatTest::expect2(NumberFormat* fmt, const Formattable& n,
                               const UnicodeString& exp,
                               UErrorCode status) {
    if (fmt == NULL || U_FAILURE(status)) {
        dataerrln("FAIL: NumberFormat constructor");
    } else {
        expect2(*fmt, n, exp);
    }
    delete fmt;
}


void NumberFormatTest::Test11035_FormatCurrencyAmount() {
    UErrorCode status = U_ZERO_ERROR;
    double amount = 12345.67;
    const char16_t* expected = u"12,345$67 ";

    // Test two ways to set a currency via API

    Locale loc1 = Locale("pt_PT");
    LocalPointer<NumberFormat> fmt1(NumberFormat::createCurrencyInstance("loc1", status),
                                    status);
    if (U_FAILURE(status)) {
      dataerrln("%s %d NumberFormat instance fmt1 is null",  __FILE__, __LINE__);
      return;
    }
    fmt1->setCurrency(u"PTE", status);
    assertSuccess("Setting currency on fmt1", status);
    UnicodeString actualSetCurrency;
    fmt1->format(amount, actualSetCurrency);

    Locale loc2 = Locale("pt_PT@currency=PTE");
    LocalPointer<NumberFormat> fmt2(NumberFormat::createCurrencyInstance(loc2, status));
    assertSuccess("Creating fmt2", status);
    UnicodeString actualLocaleString;
    fmt2->format(amount, actualLocaleString);

    // TODO: The following test will fail until DecimalFormat wraps NumberFormatter.
    if (!logKnownIssue("13574")) {
        assertEquals("Custom Currency Pattern, Set Currency", expected, actualSetCurrency);
    }
}


void NumberFormatTest::Test11645_ApplyPatternEquality() {
    IcuTestErrorCode status(*this, "Test11645_ApplyPatternEquality");
    const char16_t* pattern = u"#,##0.0#";
    LocalPointer<DecimalFormat> fmt((DecimalFormat*) NumberFormat::createInstance(status), status);
    if (!assertSuccess("", status, true, __FILE__, __LINE__)) { return; }
    fmt->applyPattern(pattern, status);
    LocalPointer<DecimalFormat> fmtCopy;

    static const int32_t newMultiplier = 37;
    fmtCopy.adoptInstead(new DecimalFormat(*fmt));
    assertFalse("Value before setter", fmtCopy->getMultiplier() == newMultiplier);
    fmtCopy->setMultiplier(newMultiplier);
    assertEquals("Value after setter", fmtCopy->getMultiplier(), newMultiplier);
    fmtCopy->applyPattern(pattern, status);
    assertEquals("Value after applyPattern", fmtCopy->getMultiplier(), newMultiplier);
    assertFalse("multiplier", *fmt == *fmtCopy);

    static const NumberFormat::ERoundingMode newRoundingMode = NumberFormat::ERoundingMode::kRoundCeiling;
    fmtCopy.adoptInstead(new DecimalFormat(*fmt));
    assertFalse("Value before setter", fmtCopy->getRoundingMode() == newRoundingMode);
    fmtCopy->setRoundingMode(newRoundingMode);
    assertEquals("Value after setter", fmtCopy->getRoundingMode(), newRoundingMode);
    fmtCopy->applyPattern(pattern, status);
    assertEquals("Value after applyPattern", fmtCopy->getRoundingMode(), newRoundingMode);
    assertFalse("roundingMode", *fmt == *fmtCopy);

    static const char16_t *const newCurrency = u"EAT";
    fmtCopy.adoptInstead(new DecimalFormat(*fmt));
    assertFalse("Value before setter", fmtCopy->getCurrency() == newCurrency);
    fmtCopy->setCurrency(newCurrency);
    assertEquals("Value after setter", fmtCopy->getCurrency(), newCurrency);
    fmtCopy->applyPattern(pattern, status);
    assertEquals("Value after applyPattern", fmtCopy->getCurrency(), newCurrency);
    assertFalse("currency", *fmt == *fmtCopy);

    static const UCurrencyUsage newCurrencyUsage = UCurrencyUsage::UCURR_USAGE_CASH;
    fmtCopy.adoptInstead(new DecimalFormat(*fmt));
    assertFalse("Value before setter", fmtCopy->getCurrencyUsage() == newCurrencyUsage);
    fmtCopy->setCurrencyUsage(newCurrencyUsage, status);
    assertEquals("Value after setter", fmtCopy->getCurrencyUsage(), newCurrencyUsage);
    fmtCopy->applyPattern(pattern, status);
    assertEquals("Value after applyPattern", fmtCopy->getCurrencyUsage(), newCurrencyUsage);
    assertFalse("currencyUsage", *fmt == *fmtCopy);
}


void NumberFormatTest::expect(NumberFormat* fmt, const Formattable& n,
                              const UnicodeString& exp, UBool rt,
                              UErrorCode status) {
    if (fmt == NULL || U_FAILURE(status)) {
        dataerrln("FAIL: NumberFormat constructor");
    } else {
        expect(*fmt, n, exp, rt);
    }
    delete fmt;
}


Formattable::adoptDecimalQuantity(DecimalQuantity *dq) {
    if (fDecimalQuantity != NULL) {
        delete fDecimalQuantity;
    }
    fDecimalQuantity = dq;
    if (dq == NULL) { // allow adoptDigitList(NULL) to clear
        return;
    }

    // Set the value into the Union of simple type values.
    // Cannot use the set() functions because they would delete the fDecimalNum value.
    if (fDecimalQuantity->fitsInLong()) {
        fValue.fInt64 = fDecimalQuantity->toLong();
        if (fValue.fInt64 <= INT32_MAX && fValue.fInt64 >= INT32_MIN) {
            fType = kLong;
        } else {
            fType = kInt64;
        }
    } else {
        fType = kDouble;
        fValue.fDouble = fDecimalQuantity->toDouble();
    }
}


void NumberFormatTest::Test11735_ExceptionIssue() {
    IcuTestErrorCode status(*this, "Test11735_ExceptionIssue");
    Locale enLocale("en");
    DecimalFormatSymbols symbols(enLocale, status);
    if (status.isSuccess()) {
        DecimalFormat fmt("0", symbols, status);
        assertSuccess("Fail: Construct DecimalFormat formatter", status, true, __FILE__, __LINE__);
        ParsePosition ppos(0);
        fmt.parseCurrency("53.45", ppos);  // NPE thrown here in ICU4J.
        assertEquals("Issue11735 ppos", 0, ppos.getIndex());
    }
}


Formattable::Formattable(const UnicodeString& stringToCopy)
{
    init();
    fType = kString;
    fValue.fString = new UnicodeString(stringToCopy);
}


Formattable::Formattable(UObject* objectToAdopt)
{
    init();
    fType = kObject;
    fValue.fObject = objectToAdopt;
}


void NumberFormatTest::Test13327_numberingSystemBufferOverflow() {
    UErrorCode status = U_ZERO_ERROR;
    for (int runId = 0; runId < 2; runId++) {
        // Construct a locale string with a very long "numbers" value.
        // The first time, make the value length exactly equal to ULOC_KEYWORDS_CAPACITY.
        // The second time, make it exceed ULOC_KEYWORDS_CAPACITY.
        int extraLength = (runId == 0) ? 0 : 5;

        CharString localeId("en@numbers=", status);
        for (int i = 0; i < ULOC_KEYWORDS_CAPACITY + extraLength; i++) {
            localeId.append('x', status);
        }
        assertSuccess("Constructing locale string", status);
        Locale locale(localeId.data());

        LocalPointer<NumberingSystem> ns(NumberingSystem::createInstance(locale, status));
        assertFalse("Should not be null", ns.getAlias() == nullptr);
        assertSuccess("Should create with no error", status);
    }
}


void NumberFormatTest::TestUFormattable(void) {
  {
    // test that a default formattable is equal to Formattable()
    UErrorCode status = U_ZERO_ERROR;
    LocalUFormattablePointer defaultUFormattable(ufmt_open(&status));
    assertSuccess("calling umt_open", status);
    Formattable defaultFormattable;
    assertTrue((UnicodeString)"comparing ufmt_open() with Formattable()",
               (defaultFormattable
                == *(Formattable::fromUFormattable(defaultUFormattable.getAlias()))));
    assertTrue((UnicodeString)"comparing ufmt_open() with Formattable()",
               (defaultFormattable
                == *(Formattable::fromUFormattable(defaultUFormattable.getAlias()))));
    assertTrue((UnicodeString)"comparing Formattable() round tripped through UFormattable",
               (defaultFormattable
                == *(Formattable::fromUFormattable(defaultFormattable.toUFormattable()))));
    assertTrue((UnicodeString)"comparing &Formattable() round tripped through UFormattable",
               ((&defaultFormattable)
                == Formattable::fromUFormattable(defaultFormattable.toUFormattable())));
    assertFalse((UnicodeString)"comparing &Formattable() with ufmt_open()",
               ((&defaultFormattable)
                == Formattable::fromUFormattable(defaultUFormattable.getAlias())));
    testFormattableAsUFormattable(__FILE__, __LINE__, defaultFormattable);
  }
  // test some random Formattables
  {
    Formattable f(ucal_getNow(), Formattable::kIsDate);
    testFormattableAsUFormattable(__FILE__, __LINE__,  f);
  }
  {
    Formattable f((double)1.61803398874989484820); // golden ratio
    testFormattableAsUFormattable(__FILE__, __LINE__,  f);
  }
  {
    Formattable f((int64_t)80994231587905127LL); // weight of the moon, in kilotons http://solarsystem.nasa.gov/planets/profile.cfm?Display=Facts&Object=Moon
    testFormattableAsUFormattable(__FILE__, __LINE__,  f);
  }
  {
    Formattable f((int32_t)4); // random number, source: http://www.xkcd.com/221/
    testFormattableAsUFormattable(__FILE__, __LINE__,  f);
  }
  {
    Formattable f("Hello world."); // should be invariant?
    testFormattableAsUFormattable(__FILE__, __LINE__,  f);
  }
  {
    UErrorCode status2 = U_ZERO_ERROR;
    Formattable f(StringPiece("73476730924573500000000.0"), status2); // weight of the moon, kg
    assertSuccess("Constructing a StringPiece", status2);
    testFormattableAsUFormattable(__FILE__, __LINE__,  f);
  }
  {
    UErrorCode status2 = U_ZERO_ERROR;
    UObject *obj = new Locale();
    Formattable f(obj);
    assertSuccess("Constructing a Formattable from a default constructed Locale()", status2);
    testFormattableAsUFormattable(__FILE__, __LINE__,  f);
  }
  {
    const Formattable array[] = {
      Formattable(ucal_getNow(), Formattable::kIsDate),
      Formattable((int32_t)4),
      Formattable((double)1.234),
    };

    Formattable fa(array, 3);
    testFormattableAsUFormattable(__FILE__, __LINE__, fa);
  }
}


void NumberFormatTest::Test10727_RoundingZero() {
    IcuTestErrorCode status(*this, "Test10727_RoundingZero");
    DecimalQuantity dq;
    dq.setToDouble(-0.0);
    assertTrue("", dq.isNegative());
    dq.roundToMagnitude(0, UNUM_ROUND_HALFEVEN, status);
    assertTrue("", dq.isNegative());
}


static inline UBool instanceOfMeasure(const UObject* a) {
    return dynamic_cast<const Measure*>(a) != NULL;
}


void NumberFormatTest::TestToPatternScientific11648() {
    UErrorCode status = U_ZERO_ERROR;
    Locale en("en");
    DecimalFormatSymbols sym(en, status);
    DecimalFormat fmt("0.00", sym, status);
    if (U_FAILURE(status)) {
        dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
        return;
    }
    fmt.setScientificNotation(TRUE);
    UnicodeString pattern;
    assertEquals("", "0.00E0", fmt.toPattern(pattern));
    DecimalFormat fmt2(pattern, sym, status);
    assertSuccess("", status);
}


void NumberFormatTest::TestFastFormatInt32() {
    IcuTestErrorCode status(*this, "TestFastFormatInt32");

    // The two simplest formatters, old API and new API.
    // Old API should use the fastpath for ints.
    LocalizedNumberFormatter lnf = NumberFormatter::withLocale("en");
    LocalPointer<NumberFormat> df(NumberFormat::createInstance("en", status), status);
    if (!assertSuccess("", status, true, __FILE__, __LINE__)) {return;}

    double nums[] = {
            0.0,
            -0.0,
            NAN,
            INFINITY,
            0.1,
            1.0,
            1.1,
            2.0,
            3.0,
            9.0,
            10.0,
            99.0,
            100.0,
            999.0,
            1000.0,
            9999.0,
            10000.0,
            99999.0,
            100000.0,
            999999.0,
            1000000.0,
            static_cast<double>(INT32_MAX) - 1,
            static_cast<double>(INT32_MAX),
            static_cast<double>(INT32_MAX) + 1,
            static_cast<double>(INT32_MIN) - 1,
            static_cast<double>(INT32_MIN),
            static_cast<double>(INT32_MIN) + 1};

    for (auto num : nums) {
        UnicodeString expected = lnf.formatDouble(num, status).toString();
        UnicodeString actual;
        df->format(num, actual);
        assertEquals(UnicodeString("d = ") + num, expected, actual);
    }
}


Formattable::getLong(UErrorCode& status) const
{
    if (U_FAILURE(status)) {
        return 0;
    }

    switch (fType) {
    case Formattable::kLong:
        return (int32_t)fValue.fInt64;
    case Formattable::kInt64:
        if (fValue.fInt64 > INT32_MAX) {
            status = U_INVALID_FORMAT_ERROR;
            return INT32_MAX;
        } else if (fValue.fInt64 < INT32_MIN) {
            status = U_INVALID_FORMAT_ERROR;
            return INT32_MIN;
        } else {
            return (int32_t)fValue.fInt64;
        }
    case Formattable::kDouble:
        if (fValue.fDouble > INT32_MAX) {
            status = U_INVALID_FORMAT_ERROR;
            return INT32_MAX;
        } else if (fValue.fDouble < INT32_MIN) {
            status = U_INVALID_FORMAT_ERROR;
            return INT32_MIN;
        } else {
            return (int32_t)fValue.fDouble; // loses fraction
        }
    case Formattable::kObject:
        if (fValue.fObject == NULL) {
            status = U_MEMORY_ALLOCATION_ERROR;
            return 0;
        }
        // TODO Later replace this with instanceof call
        if (instanceOfMeasure(fValue.fObject)) {
            return ((const Measure*) fValue.fObject)->
                getNumber().getLong(status);
        }
        U_FALLTHROUGH;
    default:
        status = U_INVALID_FORMAT_ERROR;
        return 0;
    }
}


void NumberFormatTest::Test11025_CurrencyPadding() {
    UErrorCode status = U_ZERO_ERROR;
    UnicodeString pattern(u"¤¤ **####0.00");
    DecimalFormatSymbols sym(Locale::getFrance(), status);
    if (!assertSuccess("", status)) return;
    DecimalFormat fmt(pattern, sym, status);
    if (!assertSuccess("", status)) return;
    UnicodeString result;
    fmt.format(433.0, result);
    assertEquals("Number should be padded to 11 characters", "EUR *433,00", result);
}


void NumberFormatTest::TestCurrencyUnit(void){
    UErrorCode ec = U_ZERO_ERROR;
    static const UChar USD[]  = u"USD";
    static const char USD8[]  =  "USD";
    static const UChar BAD[]  = u"???";
    static const UChar BAD2[] = u"??A";
    static const UChar XXX[]  = u"XXX";
    static const char XXX8[]  =  "XXX";
    CurrencyUnit cu(USD, ec);
    assertSuccess("CurrencyUnit", ec);

    assertEquals("getISOCurrency()", USD, cu.getISOCurrency());
    assertEquals("getSubtype()", USD8, cu.getSubtype());

    CurrencyUnit cu2(cu);
    if (!(cu2 == cu)){
        errln("CurrencyUnit copy constructed object should be same");
    }

    CurrencyUnit * cu3 = (CurrencyUnit *)cu.clone();
    if (!(*cu3 == cu)){
        errln("CurrencyUnit cloned object should be same");
    }
    CurrencyUnit bad(BAD, ec);
    assertSuccess("CurrencyUnit", ec);
    if (cu.getIndex() == bad.getIndex()) {
        errln("Indexes of different currencies should differ.");
    }
    CurrencyUnit bad2(BAD2, ec);
    assertSuccess("CurrencyUnit", ec);
    if (bad2.getIndex() != bad.getIndex()) {
        errln("Indexes of unrecognized currencies should be the same.");
    }
    if (bad == bad2) {
        errln("Different unrecognized currencies should not be equal.");
    }
    bad = bad2;
    if (bad != bad2) {
        errln("Currency unit assignment should be the same.");
    }
    delete cu3;

    // Test default constructor
    CurrencyUnit def;
    assertEquals("Default currency", XXX, def.getISOCurrency());
    assertEquals("Default currency as subtype", XXX8, def.getSubtype());

    // Test slicing
    MeasureUnit sliced1 = cu;
    MeasureUnit sliced2 = cu;
    assertEquals("Subtype after slicing 1", USD8, sliced1.getSubtype());
    assertEquals("Subtype after slicing 2", USD8, sliced2.getSubtype());
    CurrencyUnit restored1(sliced1, ec);
    CurrencyUnit restored2(sliced2, ec);
    assertSuccess("Restoring from MeasureUnit", ec);
    assertEquals("Subtype after restoring 1", USD8, restored1.getSubtype());
    assertEquals("Subtype after restoring 2", USD8, restored2.getSubtype());
    assertEquals("ISO Code after restoring 1", USD, restored1.getISOCurrency());
    assertEquals("ISO Code after restoring 2", USD, restored2.getISOCurrency());

    // Test copy constructor failure
    LocalPointer<MeasureUnit> meter(MeasureUnit::createMeter(ec));
    assertSuccess("Creating meter", ec);
    CurrencyUnit failure(*meter, ec);
    assertEquals("Copying from meter should fail", ec, U_ILLEGAL_ARGUMENT_ERROR);
    assertEquals("Copying should not give uninitialized ISO code", u"", failure.getISOCurrency());
}


void NumberFormatTest::TestCases() {
    UErrorCode ec = U_ZERO_ERROR;
    TextFile reader("NumberFormatTestCases.txt", "UTF8", ec);
    if (U_FAILURE(ec)) {
        dataerrln("Couldn't open NumberFormatTestCases.txt");
        return;
    }
    TokenIterator tokens(&reader);

    Locale loc("en", "US", "");
    DecimalFormat *ref = 0, *fmt = 0;
    MeasureFormat *mfmt = 0;
    UnicodeString pat, tok, mloc, str, out, where, currAmt;
    Formattable n;

    for (;;) {
        ec = U_ZERO_ERROR;
        if (!tokens.next(tok, ec)) {
            break;
        }
        where = UnicodeString("(") + tokens.getLineNumber() + ") ";
        int32_t cmd = keywordIndex(tok);
        switch (cmd) {
        case 0:
            // ref= <reference pattern>
            if (!tokens.next(tok, ec)) goto error;
            delete ref;
            ref = new DecimalFormat(tok,
                      new DecimalFormatSymbols(Locale::getUS(), ec), ec);
            if (U_FAILURE(ec)) {
                dataerrln("Error constructing DecimalFormat");
                goto error;
            }
            break;
        case 1:
            // loc= <locale>
            if (!tokens.next(tok, ec)) goto error;
            loc = Locale::createFromName(CharString().appendInvariantChars(tok, ec).data());
            break;
        case 2: // f:
        case 3: // fp:
        case 4: // rt:
        case 5: // p:
            if (!tokens.next(tok, ec)) goto error;
            if (tok != "-") {
                pat = tok;
                delete fmt;
                fmt = new DecimalFormat(pat, new DecimalFormatSymbols(loc, ec), ec);
                if (U_FAILURE(ec)) {
                    errln("FAIL: " + where + "Pattern \"" + pat + "\": " + u_errorName(ec));
                    ec = U_ZERO_ERROR;
                    if (!tokens.next(tok, ec)) goto error;
                    if (!tokens.next(tok, ec)) goto error;
                    if (cmd == 3) {
                        if (!tokens.next(tok, ec)) goto error;
                    }
                    continue;
                }
            }
            if (cmd == 2 || cmd == 3 || cmd == 4) {
                // f: <pattern or '-'> <number> <exp. string>
                // fp: <pattern or '-'> <number> <exp. string> <exp. number>
                // rt: <pattern or '-'> <number> <string>
                UnicodeString num;
                if (!tokens.next(num, ec)) goto error;
                if (!tokens.next(str, ec)) goto error;
                ref->parse(num, n, ec);
                assertSuccess("parse", ec);
                assertEquals(where + "\"" + pat + "\".format(" + num + ")",
                             str, fmt->format(n, out.remove(), ec));
                assertSuccess("format", ec);
                if (cmd == 3) { // fp:
                    if (!tokens.next(num, ec)) goto error;
                    ref->parse(num, n, ec);
                    assertSuccess("parse", ec);
                }
                if (cmd != 2) { // != f:
                    Formattable m;
                    fmt->parse(str, m, ec);
                    assertSuccess("parse", ec);
                    assertEquals(where + "\"" + pat + "\".parse(\"" + str + "\")",
                                 n, m);
                }
            }
            // p: <pattern or '-'> <string to parse> <exp. number>
            else {
                UnicodeString expstr;
                if (!tokens.next(str, ec)) goto error;
                if (!tokens.next(expstr, ec)) goto error;
                Formattable exp, n;
                ref->parse(expstr, exp, ec);
                assertSuccess("parse", ec);
                fmt->parse(str, n, ec);
                assertSuccess("parse", ec);
                assertEquals(where + "\"" + pat + "\".parse(\"" + str + "\")",
                             exp, n);
            }
            break;
        case 8: // fpc:
            if (!tokens.next(tok, ec)) goto error;
            if (tok != "-") {
                mloc = tok;
                delete mfmt;
                mfmt = MeasureFormat::createCurrencyFormat(
                    Locale::createFromName(
                        CharString().appendInvariantChars(mloc, ec).data()), ec);
                if (U_FAILURE(ec)) {
                    errln("FAIL: " + where + "Loc \"" + mloc + "\": " + u_errorName(ec));
                    ec = U_ZERO_ERROR;
                    if (!tokens.next(tok, ec)) goto error;
                    if (!tokens.next(tok, ec)) goto error;
                    if (!tokens.next(tok, ec)) goto error;
                    continue;
                }
            } else if (mfmt == NULL) {
                errln("FAIL: " + where + "Loc \"" + mloc + "\": skip case using previous locale, no valid MeasureFormat");
                if (!tokens.next(tok, ec)) goto error;
                if (!tokens.next(tok, ec)) goto error;
                if (!tokens.next(tok, ec)) goto error;
                continue;
            }
            // fpc: <loc or '-'> <curr.amt> <exp. string> <exp. curr.amt>
            if (!tokens.next(currAmt, ec)) goto error;
            if (!tokens.next(str, ec)) goto error;
            parseCurrencyAmount(currAmt, *ref, (UChar)0x2F/*'/'*/, n, ec);
            if (assertSuccess("parseCurrencyAmount", ec)) {
                assertEquals(where + "getCurrencyFormat(" + mloc + ").format(" + currAmt + ")",
                             str, mfmt->format(n, out.remove(), ec));
                assertSuccess("format", ec);
            }
            if (!tokens.next(currAmt, ec)) goto error;
            parseCurrencyAmount(currAmt, *ref, (UChar)0x2F/*'/'*/, n, ec);
            if (assertSuccess("parseCurrencyAmount", ec)) {
                Formattable m;

                mfmt->parseObject(str, m, ec);
                if (assertSuccess("parseCurrency", ec)) {
                    assertEquals(where + "getCurrencyFormat(" + mloc + ").parse(\"" + str + "\")",
                                 n, m);
                } else {
                    errln("FAIL: source " + str);
                }
            }
            break;
        case 6:
            // perr: <pattern or '-'> <invalid string>
            errln("FAIL: Under construction");
            goto done;
        case 7: {
            // pat: <pattern> <exp. toPattern, or '-' or 'err'>
            UnicodeString testpat;
            UnicodeString exppat;
            if (!tokens.next(testpat, ec)) goto error;
            if (!tokens.next(exppat, ec)) goto error;
            UBool err = exppat == "err";
            UBool existingPat = FALSE;
            if (testpat == "-") {
                if (err) {
                    errln("FAIL: " + where + "Invalid command \"pat: - err\"");
                    continue;
                }
                existingPat = TRUE;
                testpat = pat;
            }
            if (exppat == "-") exppat = testpat;
            DecimalFormat* f = 0;
            UErrorCode ec2 = U_ZERO_ERROR;
            if (existingPat) {
                f = fmt;
            } else {
                f = new DecimalFormat(testpat, ec2);
            }
            if (U_SUCCESS(ec2)) {
                if (err) {
                    errln("FAIL: " + where + "Invalid pattern \"" + testpat +
                          "\" was accepted");
                } else {
                    UnicodeString pat2;
                    assertEquals(where + "\"" + testpat + "\".toPattern()",
                                 exppat, f->toPattern(pat2));
                }
            } else {
                if (err) {
                    logln("Ok: " + where + "Invalid pattern \"" + testpat +
                          "\" failed: " + u_errorName(ec2));
                } else {
                    errln("FAIL: " + where + "Valid pattern \"" + testpat +
                          "\" failed: " + u_errorName(ec2));
                }
            }
            if (!existingPat) delete f;
            } break;
        case -1:
            errln("FAIL: " + where + "Unknown command \"" + tok + "\"");
            goto done;
        }
    }
    goto done;

 error:
    if (U_SUCCESS(ec)) {
        errln("FAIL: Unexpected EOF");
    } else {
        errcheckln(ec, "FAIL: " + where + "Unexpected " + u_errorName(ec));
    }

 done:
    delete mfmt;
    delete fmt;
    delete ref;
}


    virtual void parse( const UnicodeString& ,
                        Formattable& ,
                        UErrorCode& ) const {}


void DecimalQuantity::readDecNumberToBcd(const DecNum& decnum) {
    const decNumber* dn = decnum.getRawDecNumber();
    if (dn->digits > 16) {
        ensureCapacity(dn->digits);
        for (int32_t i = 0; i < dn->digits; i++) {
            fBCD.bcdBytes.ptr[i] = dn->lsu[i];
        }
    } else {
        uint64_t result = 0L;
        for (int32_t i = 0; i < dn->digits; i++) {
            result |= static_cast<uint64_t>(dn->lsu[i]) << (4 * i);
        }
        fBCD.bcdLong = result;
    }
    scale = dn->exponent;
    precision = dn->digits;
}


void DecimalQuantity::_setToLong(int64_t n) {
    if (n == INT64_MIN) {
        DecNum decnum;
        UErrorCode localStatus = U_ZERO_ERROR;
        decnum.setTo("9.223372036854775808E+18", localStatus);
        if (U_FAILURE(localStatus)) { return; } // unexpected
        flags |= NEGATIVE_FLAG;
        readDecNumberToBcd(decnum);
    } else if (n <= INT32_MAX) {
        readIntToBcd(static_cast<int32_t>(n));
    } else {
        readLongToBcd(n);
    }
}


void NumberFormatTest::verifyRounding(
        DecimalFormat& format,
        const double *values,
        const char * const *expected,
        const DecimalFormat::ERoundingMode *roundingModes,
        const char * const *descriptions,
        int32_t valueSize,
        int32_t roundingModeSize) {
    for (int32_t i = 0; i < roundingModeSize; ++i) {
        format.setRoundingMode(roundingModes[i]);
        for (int32_t j = 0; j < valueSize; j++) {
            UnicodeString currentExpected(expected[i * valueSize + j]);
            currentExpected = currentExpected.unescape();
            UnicodeString actual;
            format.format(values[j], actual);
            if (currentExpected != actual) {
                dataerrln("For %s value %f, expected '%s', got '%s'",
                          descriptions[i], values[j], CStr(currentExpected)(), CStr(actual)());
            }
        }
    }
}


bool DecimalQuantity::isInfinite() const {
    return (flags & INFINITY_FLAG) != 0;
}


NumberFormatTest::escape(UnicodeString& s)
{
    UnicodeString buf;
    for (int32_t i=0; i<s.length(); ++i)
    {
        UChar c = s[(int32_t)i];
        if (c <= (UChar)0x7F) buf += c;
        else {
            buf += (UChar)0x5c; buf += (UChar)0x55;
            buf += toHexString((c & 0xF000) >> 12);
            buf += toHexString((c & 0x0F00) >> 8);
            buf += toHexString((c & 0x00F0) >> 4);
            buf += toHexString(c & 0x000F);
        }
    }
    return (s = buf);
}


void NumberFormatTest::TestLocalizedPatternSymbolCoverage() {
    IcuTestErrorCode errorCode(*this, "TestLocalizedPatternSymbolCoverage");
    // Ticket #12961: DecimalFormat::toLocalizedPattern() is not working as designed.
    DecimalFormatSymbols dfs(errorCode);
    dfs.setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol, u'⁖');
    dfs.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, u'⁘');
    dfs.setSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol, u'⁙');
    dfs.setSymbol(DecimalFormatSymbols::kDigitSymbol, u'▰');
    dfs.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol, u'໐');
    dfs.setSymbol(DecimalFormatSymbols::kSignificantDigitSymbol, u'⁕');
    dfs.setSymbol(DecimalFormatSymbols::kPlusSignSymbol, u'†');
    dfs.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, u'‡');
    dfs.setSymbol(DecimalFormatSymbols::kPercentSymbol, u'⁜');
    dfs.setSymbol(DecimalFormatSymbols::kPerMillSymbol, u'‱');
    dfs.setSymbol(DecimalFormatSymbols::kExponentialSymbol, u"⁑⁑"); // tests multi-char sequence
    dfs.setSymbol(DecimalFormatSymbols::kPadEscapeSymbol, u'⁂');

    {
        UnicodeString standardPattern(u"#,##0.05+%;#,##0.05-%");
        UnicodeString localizedPattern(u"▰⁖▰▰໐⁘໐໕†⁜⁙▰⁖▰▰໐⁘໐໕‡⁜");

        DecimalFormat df1("#", new DecimalFormatSymbols(dfs), errorCode);
        df1.applyPattern(standardPattern, errorCode);
        DecimalFormat df2("#", new DecimalFormatSymbols(dfs), errorCode);
        df2.applyLocalizedPattern(localizedPattern, errorCode);
        assertTrue("DecimalFormat instances should be equal", df1 == df2);
        UnicodeString p2;
        assertEquals("toPattern should match on localizedPattern instance",
                standardPattern, df2.toPattern(p2));
        UnicodeString lp1;
        assertEquals("toLocalizedPattern should match on standardPattern instance",
                localizedPattern, df1.toLocalizedPattern(lp1));
    }

    {
        UnicodeString standardPattern(u"* @@@E0‰");
        UnicodeString localizedPattern(u"⁂ ⁕⁕⁕⁑⁑໐‱");

        DecimalFormat df1("#", new DecimalFormatSymbols(dfs), errorCode);
        df1.applyPattern(standardPattern, errorCode);
        DecimalFormat df2("#", new DecimalFormatSymbols(dfs), errorCode);
        df2.applyLocalizedPattern(localizedPattern, errorCode);
        assertTrue("DecimalFormat instances should be equal", df1 == df2);
        UnicodeString p2;
        assertEquals("toPattern should match on localizedPattern instance",
                standardPattern, df2.toPattern(p2));
        UnicodeString lp1;
        assertEquals("toLocalizedPattern should match on standardPattern instance",
                localizedPattern, df1.toLocalizedPattern(lp1));
    }
}


static auth_result auth_url_deleteuser (auth_t *auth, const char *username)
{
    return AUTH_FAILED;
}


static size_t handle_returned_header (void *ptr, size_t size, size_t nmemb, void *stream)
{
    auth_client *auth_user = stream;
    size_t len = size * nmemb;
    client_t *client = auth_user->client;

    if (client) {
        auth_t *auth = client->auth;
        auth_url *url = auth->state;

        if (url->auth_header && len >= url->auth_header_len && strncasecmp(ptr, url->auth_header, url->auth_header_len) == 0)
            client->authenticated = 1;

        if (url->timelimit_header && len > url->timelimit_header_len && strncasecmp(ptr, url->timelimit_header, url->timelimit_header_len) == 0) {
            const char *input = ptr;
            unsigned int limit = 0;

            if (len >= 2 && input[len - 2] == '\r' && input[len - 1] == '\n') {
                input += url->timelimit_header_len;

                if (sscanf(input, "%u\r\n", &limit) == 1) {
                    client->con->discon_time = time(NULL) + limit;
                } else {
                    ICECAST_LOG_ERROR("Auth backend returned invalid timeline header: Can not parse limit");
                }
            } else {
                ICECAST_LOG_ERROR("Auth backend returned invalid timelimit header.");
            }
        }

        if (len > 24 && strncasecmp(ptr, "icecast-auth-message: ", 22) == 0) {
            const char *input = ptr;
            size_t copy_len = len - 24 + 1; /* length of string plus \0-termination */

            if (copy_len > sizeof(url->errormsg)) {
                copy_len = sizeof(url->errormsg);
            }

            if (len >= 2 && input[len - 2] == '\r' && input[len - 1] == '\n') {
                input += 22;
                memcpy(url->errormsg, input, copy_len);
                url->errormsg[copy_len-1] = 0;
            } else {
                ICECAST_LOG_ERROR("Auth backend returned invalid message header.");
            }
        }
    }

    return len;
}


Perl_croak_nocontext(const char *pat, ...)
{
    dTHX;
    va_list args;
    va_start(args, pat);
    vcroak(pat, &args);
    NOT_REACHED; /* NOTREACHED */
    va_end(args);
}


Perl_die_nocontext(const char* pat, ...)
{
    dTHX;
    va_list args;
    va_start(args, pat);
    vcroak(pat, &args);
    NOT_REACHED; /* NOTREACHED */
    va_end(args);
    NORETURN_FUNCTION_END;
}


Perl_my_pclose(pTHX_ PerlIO *ptr)
{
    int status;
    SV **svp;
    Pid_t pid;
    Pid_t pid2 = 0;
    bool close_failed;
    dSAVEDERRNO;
    const int fd = PerlIO_fileno(ptr);
    bool should_wait;

    svp = av_fetch(PL_fdpid,fd,TRUE);
    pid = (SvTYPE(*svp) == SVt_IV) ? SvIVX(*svp) : -1;
    SvREFCNT_dec(*svp);
    *svp = NULL;

#if defined(USE_PERLIO)
    /* Find out whether the refcount is low enough for us to wait for the
       child proc without blocking. */
    should_wait = PerlIOUnix_refcnt(fd) == 1 && pid > 0;
#else
    should_wait = pid > 0;
#endif

#ifdef OS2
    if (pid == -1) {			/* Opened by popen. */
	return my_syspclose(ptr);
    }
#endif
    close_failed = (PerlIO_close(ptr) == EOF);
    SAVE_ERRNO;
    if (should_wait) do {
	pid2 = wait4pid(pid, &status, 0);
    } while (pid2 == -1 && errno == EINTR);
    if (close_failed) {
	RESTORE_ERRNO;
	return -1;
    }
    return(
      should_wait
       ? pid2 < 0 ? pid2 : status == 0 ? 0 : (errno = 0, status)
       : 0
    );
}


Perl_warner(pTHX_ U32  err, const char* pat,...)
{
    va_list args;
    PERL_ARGS_ASSERT_WARNER;
    va_start(args, pat);
    vwarner(err, pat, &args);
    va_end(args);
}


Perl_fbm_compile(pTHX_ SV *sv, U32 flags)
{
    const U8 *s;
    STRLEN i;
    STRLEN len;
    U32 frequency = 256;
    MAGIC *mg;
    PERL_DEB( STRLEN rarest = 0 );

    PERL_ARGS_ASSERT_FBM_COMPILE;

    if (isGV_with_GP(sv) || SvROK(sv))
	return;

    if (SvVALID(sv))
	return;

    if (flags & FBMcf_TAIL) {
	MAGIC * const mg = SvUTF8(sv) && SvMAGICAL(sv) ? mg_find(sv, PERL_MAGIC_utf8) : NULL;
	sv_catpvs(sv, "\n");		/* Taken into account in fbm_instr() */
	if (mg && mg->mg_len >= 0)
	    mg->mg_len++;
    }
    if (!SvPOK(sv) || SvNIOKp(sv))
	s = (U8*)SvPV_force_mutable(sv, len);
    else s = (U8 *)SvPV_mutable(sv, len);
    if (len == 0)		/* TAIL might be on a zero-length string. */
	return;
    SvUPGRADE(sv, SVt_PVMG);
    SvIOK_off(sv);
    SvNOK_off(sv);

    /* add PERL_MAGIC_bm magic holding the FBM lookup table */

    assert(!mg_find(sv, PERL_MAGIC_bm));
    mg = sv_magicext(sv, NULL, PERL_MAGIC_bm, &PL_vtbl_bm, NULL, 0);
    assert(mg);

    if (len > 2) {
	/* Shorter strings are special-cased in Perl_fbm_instr(), and don't use
	   the BM table.  */
	const U8 mlen = (len>255) ? 255 : (U8)len;
	const unsigned char *const sb = s + len - mlen; /* first char (maybe) */
	U8 *table;

	Newx(table, 256, U8);
	memset((void*)table, mlen, 256);
	mg->mg_ptr = (char *)table;
	mg->mg_len = 256;

	s += len - 1; /* last char */
	i = 0;
	while (s >= sb) {
	    if (table[*s] == mlen)
		table[*s] = (U8)i;
	    s--, i++;
	}
    }

    s = (const unsigned char*)(SvPVX_const(sv));	/* deeper magic */
    for (i = 0; i < len; i++) {
	if (PL_freq[s[i]] < frequency) {
	    PERL_DEB( rarest = i );
	    frequency = PL_freq[s[i]];
	}
    }
    BmUSEFUL(sv) = 100;			/* Initial value */
    ((XPVNV*)SvANY(sv))->xnv_u.xnv_bm_tail = cBOOL(flags & FBMcf_TAIL);
    DEBUG_r(PerlIO_printf(Perl_debug_log, "rarest char %c at %" UVuf "\n",
			  s[rarest], (UV)rarest));
}


Perl_rsignal(pTHX_ int signo, Sighandler_t handler)
{
    struct sigaction act, oact;

#ifdef USE_ITHREADS
    dVAR;
    /* only "parent" interpreter can diddle signals */
    if (PL_curinterp != aTHX)
	return (Sighandler_t) SIG_ERR;
#endif

    act.sa_handler = (void(*)(int))handler;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
#ifdef SA_RESTART
    if (PL_signals & PERL_SIGNALS_UNSAFE_FLAG)
        act.sa_flags |= SA_RESTART;	/* SVR4, 4.3+BSD */
#endif
#if defined(SA_NOCLDWAIT) && !defined(BSDish) /* See [perl #18849] */
    if (signo == SIGCHLD && handler == (Sighandler_t) SIG_IGN)
	act.sa_flags |= SA_NOCLDWAIT;
#endif
    if (sigaction(signo, &act, &oact) == -1)
    	return (Sighandler_t) SIG_ERR;
    else
    	return (Sighandler_t) oact.sa_handler;
}


S_setup_longest(pTHX_ RExC_state_t *pRExC_state,
                      struct reg_substr_datum  *rsd,
                      struct scan_data_substrs *sub,
                      STRLEN longest_length)
{
    /* This is the common code for setting up the floating and fixed length
     * string data extracted from Perl_re_op_compile() below.  Returns a boolean
     * as to whether succeeded or not */

    I32 t;
    SSize_t ml;
    bool eol  = cBOOL(sub->flags & SF_BEFORE_EOL);
    bool meol = cBOOL(sub->flags & SF_BEFORE_MEOL);

    if (! (longest_length
           || (eol /* Can't have SEOL and MULTI */
               && (! meol || (RExC_flags & RXf_PMf_MULTILINE)))
          )
            /* See comments for join_exact for why REG_UNFOLDED_MULTI_SEEN */
        || (RExC_seen & REG_UNFOLDED_MULTI_SEEN))
    {
        return FALSE;
    }

    /* copy the information about the longest from the reg_scan_data
        over to the program. */
    if (SvUTF8(sub->str)) {
        rsd->substr      = NULL;
        rsd->utf8_substr = sub->str;
    } else {
        rsd->substr      = sub->str;
        rsd->utf8_substr = NULL;
    }
    /* end_shift is how many chars that must be matched that
        follow this item. We calculate it ahead of time as once the
        lookbehind offset is added in we lose the ability to correctly
        calculate it.*/
    ml = sub->minlenp ? *(sub->minlenp) : (SSize_t)longest_length;
    rsd->end_shift = ml - sub->min_offset
        - longest_length
            /* XXX SvTAIL is always false here - did you mean FBMcf_TAIL
             * intead? - DAPM
            + (SvTAIL(sub->str) != 0)
            */
        + sub->lookbehind;

    t = (eol/* Can't have SEOL and MULTI */
         && (! meol || (RExC_flags & RXf_PMf_MULTILINE)));
    fbm_compile(sub->str, t ? FBMcf_TAIL : 0);

    return TRUE;
}


S_invlist_iterfinish(SV* invlist)
{
    /* Terminate iterator for invlist.  This is to catch development errors.
     * Any iteration that is interrupted before completed should call this
     * function.  Functions that add code points anywhere else but to the end
     * of an inversion list assert that they are not in the middle of an
     * iteration.  If they were, the addition would make the iteration
     * problematical: if the iteration hadn't reached the place where things
     * were being added, it would be ok */

    PERL_ARGS_ASSERT_INVLIST_ITERFINISH;

    *get_invlist_iter_addr(invlist) = (STRLEN) UV_MAX;
}


S_ssc_or(pTHX_ const RExC_state_t *pRExC_state, regnode_ssc *ssc,
               const regnode_charclass *or_with)
{
    /* Accumulate into SSC 'ssc' its 'OR' with 'or_with', which is either
     * another SSC or a regular ANYOF class.  Can create false positives if
     * 'or_with' is to be inverted. */

    SV* ored_cp_list;
    U8 ored_flags;

    PERL_ARGS_ASSERT_SSC_OR;

    assert(is_ANYOF_SYNTHETIC(ssc));

    /* 'or_with' is used as-is if it too is an SSC; otherwise have to extract
     * the code point inversion list and just the relevant flags */
    if (is_ANYOF_SYNTHETIC(or_with)) {
        ored_cp_list = ((regnode_ssc*) or_with)->invlist;
        ored_flags = ANYOF_FLAGS(or_with);
    }
    else {
        ored_cp_list = get_ANYOF_cp_list_for_ssc(pRExC_state, or_with);
        ored_flags = ANYOF_FLAGS(or_with) & ANYOF_COMMON_FLAGS;
        if (OP(or_with) != ANYOFD) {
            ored_flags
            |= ANYOF_FLAGS(or_with)
             & ( ANYOF_SHARED_d_MATCHES_ALL_NON_UTF8_NON_ASCII_non_d_WARN_SUPER
                |ANYOF_SHARED_d_UPPER_LATIN1_UTF8_STRING_MATCHES_non_d_RUNTIME_USER_PROP);
            if (ANYOFL_UTF8_LOCALE_REQD(ANYOF_FLAGS(or_with))) {
                ored_flags |=
                    ANYOFL_SHARED_UTF8_LOCALE_fold_HAS_MATCHES_nonfold_REQD;
            }
        }
    }

    ANYOF_FLAGS(ssc) |= ored_flags;

    /* Below, C1 is the list of code points in 'ssc'; P1, its posix classes.
     * C2 is the list of code points in 'or-with'; P2, its posix classes.
     * 'or_with' may be inverted.  When not inverted, we have the simple
     * situation of computing:
     *  (C1 | P1) | (C2 | P2)  =  (C1 | C2) | (P1 | P2)
     * If P1|P2 yields a situation with both a class and its complement are
     * set, like having both \w and \W, this matches all code points, and we
     * can delete these from the P component of the ssc going forward.  XXX We
     * might be able to delete all the P components, but I (khw) am not certain
     * about this, and it is better to be safe.
     *
     * Inverted, we have
     *  (C1 | P1) | ~(C2 | P2)  =  (C1 | P1) | (~C2 & ~P2)
     *                         <=  (C1 | P1) | ~C2
     *                         <=  (C1 | ~C2) | P1
     * (which results in actually simpler code than the non-inverted case)
     * */

    if ((ANYOF_FLAGS(or_with) & ANYOF_INVERT)
        && ! is_ANYOF_SYNTHETIC(or_with))
    {
        /* We ignore P2, leaving P1 going forward */
    }   /* else  Not inverted */
    else if (ANYOF_FLAGS(or_with) & ANYOF_MATCHES_POSIXL) {
        ANYOF_POSIXL_OR((regnode_charclass_posixl*)or_with, ssc);
        if (ANYOF_POSIXL_SSC_TEST_ANY_SET(ssc)) {
            unsigned int i;
            for (i = 0; i < ANYOF_MAX; i += 2) {
                if (ANYOF_POSIXL_TEST(ssc, i) && ANYOF_POSIXL_TEST(ssc, i + 1))
                {
                    ssc_match_all_cp(ssc);
                    ANYOF_POSIXL_CLEAR(ssc, i);
                    ANYOF_POSIXL_CLEAR(ssc, i+1);
                }
            }
        }
    }

    ssc_union(ssc,
              ored_cp_list,
              FALSE /* Already has been inverted */
              );
}


Perl_reg_named_buff_scalar(pTHX_ REGEXP * const r, const U32 flags)
{
    SV *ret;
    AV *av;
    SSize_t length;
    struct regexp *const rx = ReANY(r);

    PERL_ARGS_ASSERT_REG_NAMED_BUFF_SCALAR;

    if (rx && RXp_PAREN_NAMES(rx)) {
        if (flags & (RXapif_ALL | RXapif_REGNAMES_COUNT)) {
            return newSViv(HvTOTALKEYS(RXp_PAREN_NAMES(rx)));
        } else if (flags & RXapif_ONE) {
            ret = CALLREG_NAMED_BUFF_ALL(r, (flags | RXapif_REGNAMES));
            av = MUTABLE_AV(SvRV(ret));
            length = av_tindex(av);
	    SvREFCNT_dec_NN(ret);
            return newSViv(length + 1);
        } else {
            Perl_croak(aTHX_ "panic: Unknown flags %d in named_buff_scalar",
                                                (int)flags);
            return NULL;
        }
    }
    return &PL_sv_undef;
}


Perl_pregcomp(pTHX_ SV * const pattern, const U32 flags)
{
    regexp_engine const *eng = current_re_engine();
    GET_RE_DEBUG_FLAGS_DECL;

    PERL_ARGS_ASSERT_PREGCOMP;

    /* Dispatch a request to compile a regexp to correct regexp engine. */
    DEBUG_COMPILE_r({
        Perl_re_printf( aTHX_  "Using engine %" UVxf "\n",
			PTR2UV(eng));
    });
    return CALLREGCOMP_ENG(eng, pattern, flags);
}