You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by gi...@apache.org on 2025/12/02 14:24:02 UTC
(juneau) branch asf-staging updated: Deploy documentation staging from e77a2d1277f2ca0c40eb5086ea555fccbb20a7ff e77a2d1277f2ca0c40eb5086ea555fccbb20a7ff
This is an automated email from the ASF dual-hosted git repository.
github-bot pushed a commit to branch asf-staging
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/asf-staging by this push:
new e9cf42f399 Deploy documentation staging from e77a2d1277f2ca0c40eb5086ea555fccbb20a7ff e77a2d1277f2ca0c40eb5086ea555fccbb20a7ff
e9cf42f399 is described below
commit e9cf42f399f5b85dc733da36d6d0f1ab0a9cd0fa
Author: github-actions[bot] <gi...@users.noreply.github.com>
AuthorDate: Tue Dec 2 14:23:56 2025 +0000
Deploy documentation staging from e77a2d1277f2ca0c40eb5086ea555fccbb20a7ff e77a2d1277f2ca0c40eb5086ea555fccbb20a7ff
---
.../juneau/commons/utils/StringUtils_Test.html | 711 ++++----
.../apache/juneau/commons/utils/StringUtils.html | 1783 ++++++++++----------
2 files changed, 1247 insertions(+), 1247 deletions(-)
diff --git a/site/xref-test/org/apache/juneau/commons/utils/StringUtils_Test.html b/site/xref-test/org/apache/juneau/commons/utils/StringUtils_Test.html
index 30e62a2057..f0dca63126 100644
--- a/site/xref-test/org/apache/juneau/commons/utils/StringUtils_Test.html
+++ b/site/xref-test/org/apache/juneau/commons/utils/StringUtils_Test.html
@@ -6571,360 +6571,363 @@
<a class="jxr_linenumber" name="L6563" href="#L6563">6563</a> <em class="jxr_comment">// - First '\' sees second '\', appends '\' and skips second '\'</em>
<a class="jxr_linenumber" name="L6564" href="#L6564">6564</a> <em class="jxr_comment">// - Then appends the second '\' from the string, then 'b'</em>
<a class="jxr_linenumber" name="L6565" href="#L6565">6565</a> <em class="jxr_comment">// Result: "a\\\\b" (both backslashes preserved)</em>
-<a class="jxr_linenumber" name="L6566" href="#L6566">6566</a> assertEquals(<span class="jxr_string">"a\\\\b"</span>, unescapeChars(<span class="jxr_string">"a\\\\b"</span>, AsciiSet.of(<span class="jxr_string">","</span>))); <em class="jxr_comment">// '\' not in escaped set</em>
-<a class="jxr_linenumber" name="L6567" href="#L6567">6567</a> }
-<a class="jxr_linenumber" name="L6568" href="#L6568">6568</a>
-<a class="jxr_linenumber" name="L6569" href="#L6569">6569</a> <em class="jxr_comment">//====================================================================================================</em>
-<a class="jxr_linenumber" name="L6570" href="#L6570">6570</a> <em class="jxr_comment">// unescapeHtml(String)</em>
-<a class="jxr_linenumber" name="L6571" href="#L6571">6571</a> <em class="jxr_comment">//====================================================================================================</em>
-<a class="jxr_linenumber" name="L6572" href="#L6572">6572</a> @Test
-<a class="jxr_linenumber" name="L6573" href="#L6573">6573</a> <strong class="jxr_keyword">void</strong> a223_unescapeHtml() {
-<a class="jxr_linenumber" name="L6574" href="#L6574">6574</a> assertNull(unescapeHtml(<strong class="jxr_keyword">null</strong>));
-<a class="jxr_linenumber" name="L6575" href="#L6575">6575</a> assertEquals(<span class="jxr_string">""</span>, unescapeHtml(<span class="jxr_string">""</span>));
-<a class="jxr_linenumber" name="L6576" href="#L6576">6576</a> assertEquals(<span class="jxr_string">"Hello World"</span>, unescapeHtml(<span class="jxr_string">"Hello World"</span>));
-<a class="jxr_linenumber" name="L6577" href="#L6577">6577</a> assertEquals(<span class="jxr_string">"<script>"</span>, unescapeHtml(<span class="jxr_string">"&lt;script&gt;"</span>));
-<a class="jxr_linenumber" name="L6578" href="#L6578">6578</a> assertEquals(<span class="jxr_string">"\"Hello\""</span>, unescapeHtml(<span class="jxr_string">"&quot;Hello&quot;"</span>));
-<a class="jxr_linenumber" name="L6579" href="#L6579">6579</a> assertEquals(<span class="jxr_string">"It's a test"</span>, unescapeHtml(<span class="jxr_string">"It&#39;s a test"</span>));
-<a class="jxr_linenumber" name="L6580" href="#L6580">6580</a> assertEquals(<span class="jxr_string">"It's a test"</span>, unescapeHtml(<span class="jxr_string">"It&apos;s a test"</span>));
-<a class="jxr_linenumber" name="L6581" href="#L6581">6581</a> assertEquals(<span class="jxr_string">"&"</span>, unescapeHtml(<span class="jxr_string">"&amp;"</span>));
-<a class="jxr_linenumber" name="L6582" href="#L6582">6582</a> assertEquals(<span class="jxr_string">"<tag>text</tag>"</span>, unescapeHtml(<span class="jxr_string">"&lt;tag&gt;text&lt;/tag&gt;"</span>));
-<a class="jxr_linenumber" name="L6583" href="#L6583">6583</a> <em class="jxr_comment">// Test round-trip</em>
-<a class="jxr_linenumber" name="L6584" href="#L6584">6584</a> assertEquals(<span class="jxr_string">"Hello & World"</span>, unescapeHtml(escapeHtml(<span class="jxr_string">"Hello & World"</span>)));
-<a class="jxr_linenumber" name="L6585" href="#L6585">6585</a> }
-<a class="jxr_linenumber" name="L6586" href="#L6586">6586</a>
-<a class="jxr_linenumber" name="L6587" href="#L6587">6587</a> <em class="jxr_comment">//====================================================================================================</em>
-<a class="jxr_linenumber" name="L6588" href="#L6588">6588</a> <em class="jxr_comment">// unescapeXml(String)</em>
-<a class="jxr_linenumber" name="L6589" href="#L6589">6589</a> <em class="jxr_comment">//====================================================================================================</em>
-<a class="jxr_linenumber" name="L6590" href="#L6590">6590</a> @Test
-<a class="jxr_linenumber" name="L6591" href="#L6591">6591</a> <strong class="jxr_keyword">void</strong> a224_unescapeXml() {
-<a class="jxr_linenumber" name="L6592" href="#L6592">6592</a> assertNull(unescapeXml(<strong class="jxr_keyword">null</strong>));
-<a class="jxr_linenumber" name="L6593" href="#L6593">6593</a> assertEquals(<span class="jxr_string">""</span>, unescapeXml(<span class="jxr_string">""</span>));
-<a class="jxr_linenumber" name="L6594" href="#L6594">6594</a> assertEquals(<span class="jxr_string">"Hello World"</span>, unescapeXml(<span class="jxr_string">"Hello World"</span>));
-<a class="jxr_linenumber" name="L6595" href="#L6595">6595</a> assertEquals(<span class="jxr_string">"<tag>"</span>, unescapeXml(<span class="jxr_string">"&lt;tag&gt;"</span>));
-<a class="jxr_linenumber" name="L6596" href="#L6596">6596</a> assertEquals(<span class="jxr_string">"\"Hello\""</span>, unescapeXml(<span class="jxr_string">"&quot;Hello&quot;"</span>));
-<a class="jxr_linenumber" name="L6597" href="#L6597">6597</a> assertEquals(<span class="jxr_string">"'test'"</span>, unescapeXml(<span class="jxr_string">"&apos;test&apos;"</span>));
-<a class="jxr_linenumber" name="L6598" href="#L6598">6598</a> assertEquals(<span class="jxr_string">"&"</span>, unescapeXml(<span class="jxr_string">"&amp;"</span>));
-<a class="jxr_linenumber" name="L6599" href="#L6599">6599</a> assertEquals(<span class="jxr_string">"<tag>text</tag>"</span>, unescapeXml(<span class="jxr_string">"&lt;tag&gt;text&lt;/tag&gt;"</span>));
-<a class="jxr_linenumber" name="L6600" href="#L6600">6600</a> }
-<a class="jxr_linenumber" name="L6601" href="#L6601">6601</a>
-<a class="jxr_linenumber" name="L6602" href="#L6602">6602</a> <em class="jxr_comment">//====================================================================================================</em>
-<a class="jxr_linenumber" name="L6603" href="#L6603">6603</a> <em class="jxr_comment">// unicodeSequence(char)</em>
-<a class="jxr_linenumber" name="L6604" href="#L6604">6604</a> <em class="jxr_comment">//====================================================================================================</em>
-<a class="jxr_linenumber" name="L6605" href="#L6605">6605</a> @Test
-<a class="jxr_linenumber" name="L6606" href="#L6606">6606</a> <strong class="jxr_keyword">void</strong> a225_unicodeSequence() {
-<a class="jxr_linenumber" name="L6607" href="#L6607">6607</a> assertEquals(<span class="jxr_string">"\\u0041"</span>, unicodeSequence('A'));
-<a class="jxr_linenumber" name="L6608" href="#L6608">6608</a> assertEquals(<span class="jxr_string">"\\u0061"</span>, unicodeSequence('a'));
-<a class="jxr_linenumber" name="L6609" href="#L6609">6609</a> assertEquals(<span class="jxr_string">"\\u0030"</span>, unicodeSequence('0'));
-<a class="jxr_linenumber" name="L6610" href="#L6610">6610</a> assertEquals(<span class="jxr_string">"\\u0000"</span>, unicodeSequence('\u0000'));
-<a class="jxr_linenumber" name="L6611" href="#L6611">6611</a> assertEquals(<span class="jxr_string">"\\u00FF"</span>, unicodeSequence('\u00FF'));
-<a class="jxr_linenumber" name="L6612" href="#L6612">6612</a> assertEquals(<span class="jxr_string">"\\uFFFF"</span>, unicodeSequence('\uFFFF'));
-<a class="jxr_linenumber" name="L6613" href="#L6613">6613</a> }
-<a class="jxr_linenumber" name="L6614" href="#L6614">6614</a>
-<a class="jxr_linenumber" name="L6615" href="#L6615">6615</a> <em class="jxr_comment">//====================================================================================================</em>
-<a class="jxr_linenumber" name="L6616" href="#L6616">6616</a> <em class="jxr_comment">// upperCase(String)</em>
-<a class="jxr_linenumber" name="L6617" href="#L6617">6617</a> <em class="jxr_comment">//====================================================================================================</em>
-<a class="jxr_linenumber" name="L6618" href="#L6618">6618</a> @Test
-<a class="jxr_linenumber" name="L6619" href="#L6619">6619</a> <strong class="jxr_keyword">void</strong> a226_upperCase() {
-<a class="jxr_linenumber" name="L6620" href="#L6620">6620</a> assertNull(upperCase(<strong class="jxr_keyword">null</strong>));
-<a class="jxr_linenumber" name="L6621" href="#L6621">6621</a> assertEquals(<span class="jxr_string">""</span>, upperCase(<span class="jxr_string">""</span>));
-<a class="jxr_linenumber" name="L6622" href="#L6622">6622</a> assertEquals(<span class="jxr_string">"HELLO"</span>, upperCase(<span class="jxr_string">"hello"</span>));
-<a class="jxr_linenumber" name="L6623" href="#L6623">6623</a> assertEquals(<span class="jxr_string">"HELLO WORLD"</span>, upperCase(<span class="jxr_string">"Hello World"</span>));
-<a class="jxr_linenumber" name="L6624" href="#L6624">6624</a> assertEquals(<span class="jxr_string">"123"</span>, upperCase(<span class="jxr_string">"123"</span>));
-<a class="jxr_linenumber" name="L6625" href="#L6625">6625</a> assertEquals(<span class="jxr_string">"ABC"</span>, upperCase(<span class="jxr_string">"abc"</span>));
-<a class="jxr_linenumber" name="L6626" href="#L6626">6626</a> }
-<a class="jxr_linenumber" name="L6627" href="#L6627">6627</a>
-<a class="jxr_linenumber" name="L6628" href="#L6628">6628</a> <em class="jxr_comment">//====================================================================================================</em>
-<a class="jxr_linenumber" name="L6629" href="#L6629">6629</a> <em class="jxr_comment">// urlDecode(String)</em>
-<a class="jxr_linenumber" name="L6630" href="#L6630">6630</a> <em class="jxr_comment">//====================================================================================================</em>
-<a class="jxr_linenumber" name="L6631" href="#L6631">6631</a> @Test
-<a class="jxr_linenumber" name="L6632" href="#L6632">6632</a> <strong class="jxr_keyword">void</strong> a227_urlDecode() {
-<a class="jxr_linenumber" name="L6633" href="#L6633">6633</a> assertNull(urlDecode(<strong class="jxr_keyword">null</strong>));
-<a class="jxr_linenumber" name="L6634" href="#L6634">6634</a> assertEquals(<span class="jxr_string">""</span>, urlDecode(<span class="jxr_string">""</span>));
-<a class="jxr_linenumber" name="L6635" href="#L6635">6635</a> assertEquals(<span class="jxr_string">"Hello World"</span>, urlDecode(<span class="jxr_string">"Hello+World"</span>));
-<a class="jxr_linenumber" name="L6636" href="#L6636">6636</a> assertEquals(<span class="jxr_string">"Hello World"</span>, urlDecode(<span class="jxr_string">"Hello%20World"</span>));
-<a class="jxr_linenumber" name="L6637" href="#L6637">6637</a> assertEquals(<span class="jxr_string">"test@example.com"</span>, urlDecode(<span class="jxr_string">"test%40example.com"</span>));
-<a class="jxr_linenumber" name="L6638" href="#L6638">6638</a> assertEquals(<span class="jxr_string">"a=b&c=d"</span>, urlDecode(<span class="jxr_string">"a%3Db%26c%3Dd"</span>));
-<a class="jxr_linenumber" name="L6639" href="#L6639">6639</a> <em class="jxr_comment">// No encoding needed - returns as-is</em>
-<a class="jxr_linenumber" name="L6640" href="#L6640">6640</a> assertEquals(<span class="jxr_string">"Hello"</span>, urlDecode(<span class="jxr_string">"Hello"</span>));
-<a class="jxr_linenumber" name="L6641" href="#L6641">6641</a> }
-<a class="jxr_linenumber" name="L6642" href="#L6642">6642</a>
-<a class="jxr_linenumber" name="L6643" href="#L6643">6643</a> <em class="jxr_comment">//====================================================================================================</em>
-<a class="jxr_linenumber" name="L6644" href="#L6644">6644</a> <em class="jxr_comment">// urlEncode(String)</em>
-<a class="jxr_linenumber" name="L6645" href="#L6645">6645</a> <em class="jxr_comment">//====================================================================================================</em>
-<a class="jxr_linenumber" name="L6646" href="#L6646">6646</a> @Test
-<a class="jxr_linenumber" name="L6647" href="#L6647">6647</a> <strong class="jxr_keyword">void</strong> a228_urlEncode() {
-<a class="jxr_linenumber" name="L6648" href="#L6648">6648</a> assertNull(urlEncode(<strong class="jxr_keyword">null</strong>));
-<a class="jxr_linenumber" name="L6649" href="#L6649">6649</a> assertEquals(<span class="jxr_string">""</span>, urlEncode(<span class="jxr_string">""</span>));
-<a class="jxr_linenumber" name="L6650" href="#L6650">6650</a> assertEquals(<span class="jxr_string">"Hello+World"</span>, urlEncode(<span class="jxr_string">"Hello World"</span>));
-<a class="jxr_linenumber" name="L6651" href="#L6651">6651</a> assertEquals(<span class="jxr_string">"test%40example.com"</span>, urlEncode(<span class="jxr_string">"test@example.com"</span>));
-<a class="jxr_linenumber" name="L6652" href="#L6652">6652</a> assertEquals(<span class="jxr_string">"a%3Db%26c%3Dd"</span>, urlEncode(<span class="jxr_string">"a=b&c=d"</span>));
-<a class="jxr_linenumber" name="L6653" href="#L6653">6653</a> <em class="jxr_comment">// No encoding needed - returns as-is</em>
-<a class="jxr_linenumber" name="L6654" href="#L6654">6654</a> assertEquals(<span class="jxr_string">"Hello"</span>, urlEncode(<span class="jxr_string">"Hello"</span>));
-<a class="jxr_linenumber" name="L6655" href="#L6655">6655</a> assertEquals(<span class="jxr_string">"test123"</span>, urlEncode(<span class="jxr_string">"test123"</span>));
-<a class="jxr_linenumber" name="L6656" href="#L6656">6656</a>
-<a class="jxr_linenumber" name="L6657" href="#L6657">6657</a> <em class="jxr_comment">// Test</em>
-<a class="jxr_linenumber" name="L6658" href="#L6658">6658</a> <strong class="jxr_keyword">var</strong> result1 = urlEncode(<span class="jxr_string">"test@example.com"</span>);
-<a class="jxr_linenumber" name="L6659" href="#L6659">6659</a> assertTrue(result1.contains(<span class="jxr_string">"%40"</span>)); <em class="jxr_comment">// @ is encoded</em>
-<a class="jxr_linenumber" name="L6660" href="#L6660">6660</a>
-<a class="jxr_linenumber" name="L6661" href="#L6661">6661</a> <em class="jxr_comment">// Test</em>
-<a class="jxr_linenumber" name="L6662" href="#L6662">6662</a> <strong class="jxr_keyword">var</strong> result2 = urlEncode(<span class="jxr_string">"café"</span>);
-<a class="jxr_linenumber" name="L6663" href="#L6663">6663</a> assertNotNull(result2);
-<a class="jxr_linenumber" name="L6664" href="#L6664">6664</a> assertTrue(result2.contains(<span class="jxr_string">"%"</span>)); <em class="jxr_comment">// Contains encoded characters</em>
-<a class="jxr_linenumber" name="L6665" href="#L6665">6665</a>
-<a class="jxr_linenumber" name="L6666" href="#L6666">6666</a> <strong class="jxr_keyword">var</strong> result3 = urlEncode(<span class="jxr_string">"测试"</span>);
-<a class="jxr_linenumber" name="L6667" href="#L6667">6667</a> assertNotNull(result3);
-<a class="jxr_linenumber" name="L6668" href="#L6668">6668</a> assertTrue(result3.contains(<span class="jxr_string">"%"</span>)); <em class="jxr_comment">// Contains UTF-8 encoded characters</em>
-<a class="jxr_linenumber" name="L6669" href="#L6669">6669</a> }
-<a class="jxr_linenumber" name="L6670" href="#L6670">6670</a>
-<a class="jxr_linenumber" name="L6671" href="#L6671">6671</a> <em class="jxr_comment">//====================================================================================================</em>
-<a class="jxr_linenumber" name="L6672" href="#L6672">6672</a> <em class="jxr_comment">// urlEncodeLax(String)</em>
-<a class="jxr_linenumber" name="L6673" href="#L6673">6673</a> <em class="jxr_comment">//====================================================================================================</em>
-<a class="jxr_linenumber" name="L6674" href="#L6674">6674</a> @Test
-<a class="jxr_linenumber" name="L6675" href="#L6675">6675</a> <strong class="jxr_keyword">void</strong> a229_urlEncodeLax() {
-<a class="jxr_linenumber" name="L6676" href="#L6676">6676</a> assertNull(urlEncodeLax(<strong class="jxr_keyword">null</strong>));
-<a class="jxr_linenumber" name="L6677" href="#L6677">6677</a> assertEquals(<span class="jxr_string">""</span>, urlEncodeLax(<span class="jxr_string">""</span>));
-<a class="jxr_linenumber" name="L6678" href="#L6678">6678</a> <em class="jxr_comment">// Lax encoding - fewer characters are encoded</em>
-<a class="jxr_linenumber" name="L6679" href="#L6679">6679</a> assertEquals(<span class="jxr_string">"Hello+World"</span>, urlEncodeLax(<span class="jxr_string">"Hello World"</span>));
-<a class="jxr_linenumber" name="L6680" href="#L6680">6680</a> <em class="jxr_comment">// @ might not be encoded in lax mode</em>
-<a class="jxr_linenumber" name="L6681" href="#L6681">6681</a> <strong class="jxr_keyword">var</strong> result1 = urlEncodeLax(<span class="jxr_string">"test@example.com"</span>);
-<a class="jxr_linenumber" name="L6682" href="#L6682">6682</a> assertNotNull(result1);
-<a class="jxr_linenumber" name="L6683" href="#L6683">6683</a> <em class="jxr_comment">// No encoding needed - returns as-is</em>
-<a class="jxr_linenumber" name="L6684" href="#L6684">6684</a> assertEquals(<span class="jxr_string">"Hello"</span>, urlEncodeLax(<span class="jxr_string">"Hello"</span>));
-<a class="jxr_linenumber" name="L6685" href="#L6685">6685</a> assertEquals(<span class="jxr_string">"test123"</span>, urlEncodeLax(<span class="jxr_string">"test123"</span>));
-<a class="jxr_linenumber" name="L6686" href="#L6686">6686</a>
-<a class="jxr_linenumber" name="L6687" href="#L6687">6687</a> <em class="jxr_comment">// Test that need encoding</em>
-<a class="jxr_linenumber" name="L6688" href="#L6688">6688</a> <em class="jxr_comment">// Characters not in URL_UNENCODED_LAX_CHARS and not space</em>
-<a class="jxr_linenumber" name="L6689" href="#L6689">6689</a> <strong class="jxr_keyword">var</strong> result2 = urlEncodeLax(<span class="jxr_string">"test#value"</span>);
-<a class="jxr_linenumber" name="L6690" href="#L6690">6690</a> assertNotNull(result2);
-<a class="jxr_linenumber" name="L6691" href="#L6691">6691</a> assertTrue(result2.contains(<span class="jxr_string">"%23"</span>)); <em class="jxr_comment">// # is encoded as %23</em>
-<a class="jxr_linenumber" name="L6692" href="#L6692">6692</a> <strong class="jxr_keyword">var</strong> result3 = urlEncodeLax(<span class="jxr_string">"test%value"</span>);
-<a class="jxr_linenumber" name="L6693" href="#L6693">6693</a> assertNotNull(result3);
-<a class="jxr_linenumber" name="L6694" href="#L6694">6694</a> assertTrue(result3.contains(<span class="jxr_string">"%25"</span>)); <em class="jxr_comment">// % is encoded as %25</em>
-<a class="jxr_linenumber" name="L6695" href="#L6695">6695</a> <strong class="jxr_keyword">var</strong> result4 = urlEncodeLax(<span class="jxr_string">"test&value"</span>);
-<a class="jxr_linenumber" name="L6696" href="#L6696">6696</a> assertNotNull(result4);
-<a class="jxr_linenumber" name="L6697" href="#L6697">6697</a> assertTrue(result4.contains(<span class="jxr_string">"%26"</span>)); <em class="jxr_comment">// & is encoded as %26</em>
-<a class="jxr_linenumber" name="L6698" href="#L6698">6698</a>
-<a class="jxr_linenumber" name="L6699" href="#L6699">6699</a> <em class="jxr_comment">// Test that need encoding</em>
-<a class="jxr_linenumber" name="L6700" href="#L6700">6700</a> <em class="jxr_comment">// Unicode characters are encoded using URLEncoder.encode</em>
-<a class="jxr_linenumber" name="L6701" href="#L6701">6701</a> <strong class="jxr_keyword">var</strong> result5 = urlEncodeLax(<span class="jxr_string">"testévalue"</span>);
-<a class="jxr_linenumber" name="L6702" href="#L6702">6702</a> assertNotNull(result5);
-<a class="jxr_linenumber" name="L6703" href="#L6703">6703</a> assertTrue(result5.contains(<span class="jxr_string">"%"</span>)); <em class="jxr_comment">// é should be encoded</em>
-<a class="jxr_linenumber" name="L6704" href="#L6704">6704</a> <strong class="jxr_keyword">var</strong> result6 = urlEncodeLax(<span class="jxr_string">"test中文"</span>);
-<a class="jxr_linenumber" name="L6705" href="#L6705">6705</a> assertNotNull(result6);
-<a class="jxr_linenumber" name="L6706" href="#L6706">6706</a> assertTrue(result6.contains(<span class="jxr_string">"%"</span>)); <em class="jxr_comment">// Chinese characters should be encoded</em>
-<a class="jxr_linenumber" name="L6707" href="#L6707">6707</a> <strong class="jxr_keyword">var</strong> result7 = urlEncodeLax(<span class="jxr_string">"test🎉"</span>);
-<a class="jxr_linenumber" name="L6708" href="#L6708">6708</a> assertNotNull(result7);
-<a class="jxr_linenumber" name="L6709" href="#L6709">6709</a> assertTrue(result7.contains(<span class="jxr_string">"%"</span>)); <em class="jxr_comment">// Emoji should be encoded</em>
-<a class="jxr_linenumber" name="L6710" href="#L6710">6710</a> }
-<a class="jxr_linenumber" name="L6711" href="#L6711">6711</a>
-<a class="jxr_linenumber" name="L6712" href="#L6712">6712</a> <em class="jxr_comment">//====================================================================================================</em>
-<a class="jxr_linenumber" name="L6713" href="#L6713">6713</a> <em class="jxr_comment">// urlEncodePath(Object)</em>
-<a class="jxr_linenumber" name="L6714" href="#L6714">6714</a> <em class="jxr_comment">//====================================================================================================</em>
-<a class="jxr_linenumber" name="L6715" href="#L6715">6715</a> @Test
-<a class="jxr_linenumber" name="L6716" href="#L6716">6716</a> <strong class="jxr_keyword">void</strong> a230_urlEncodePath() {
-<a class="jxr_linenumber" name="L6717" href="#L6717">6717</a> <em class="jxr_comment">// Null input</em>
-<a class="jxr_linenumber" name="L6718" href="#L6718">6718</a> assertNull(urlEncodePath(<strong class="jxr_keyword">null</strong>));
-<a class="jxr_linenumber" name="L6719" href="#L6719">6719</a>
-<a class="jxr_linenumber" name="L6720" href="#L6720">6720</a> <em class="jxr_comment">// Path encoding - doesn't encode slashes</em>
-<a class="jxr_linenumber" name="L6721" href="#L6721">6721</a> <strong class="jxr_keyword">var</strong> result1 = urlEncodePath(<span class="jxr_string">"/path/to/file"</span>);
-<a class="jxr_linenumber" name="L6722" href="#L6722">6722</a> assertNotNull(result1);
-<a class="jxr_linenumber" name="L6723" href="#L6723">6723</a> assertTrue(result1.contains(<span class="jxr_string">"/"</span>));
-<a class="jxr_linenumber" name="L6724" href="#L6724">6724</a>
-<a class="jxr_linenumber" name="L6725" href="#L6725">6725</a> <em class="jxr_comment">// Spaces are encoded</em>
-<a class="jxr_linenumber" name="L6726" href="#L6726">6726</a> <strong class="jxr_keyword">var</strong> result2 = urlEncodePath(<span class="jxr_string">"path with spaces"</span>);
-<a class="jxr_linenumber" name="L6727" href="#L6727">6727</a> assertNotNull(result2);
-<a class="jxr_linenumber" name="L6728" href="#L6728">6728</a> assertTrue(result2.contains(<span class="jxr_string">"+"</span>) || result2.contains(<span class="jxr_string">"%20"</span>));
-<a class="jxr_linenumber" name="L6729" href="#L6729">6729</a>
-<a class="jxr_linenumber" name="L6730" href="#L6730">6730</a> <em class="jxr_comment">// Special characters are encoded</em>
-<a class="jxr_linenumber" name="L6731" href="#L6731">6731</a> <strong class="jxr_keyword">var</strong> result3 = urlEncodePath(<span class="jxr_string">"file@name"</span>);
-<a class="jxr_linenumber" name="L6732" href="#L6732">6732</a> assertNotNull(result3);
-<a class="jxr_linenumber" name="L6733" href="#L6733">6733</a>
-<a class="jxr_linenumber" name="L6734" href="#L6734">6734</a> <em class="jxr_comment">// Test code path</em>
-<a class="jxr_linenumber" name="L6735" href="#L6735">6735</a> <strong class="jxr_keyword">var</strong> result4 = urlEncodePath(<span class="jxr_string">"simplepath"</span>);
-<a class="jxr_linenumber" name="L6736" href="#L6736">6736</a> assertEquals(<span class="jxr_string">"simplepath"</span>, result4); <em class="jxr_comment">// No encoding needed, returns as-is</em>
-<a class="jxr_linenumber" name="L6737" href="#L6737">6737</a>
-<a class="jxr_linenumber" name="L6738" href="#L6738">6738</a> <em class="jxr_comment">// Test</em>
-<a class="jxr_linenumber" name="L6739" href="#L6739">6739</a> <em class="jxr_comment">// The surrogate pair handling code is executed when encoding characters that contain surrogate pairs</em>
-<a class="jxr_linenumber" name="L6740" href="#L6740">6740</a> <em class="jxr_comment">// Use a string that contains a character needing encoding along with surrogate pairs</em>
-<a class="jxr_linenumber" name="L6741" href="#L6741">6741</a> <em class="jxr_comment">// to ensure the encoding path is taken and surrogate pair handling is executed</em>
-<a class="jxr_linenumber" name="L6742" href="#L6742">6742</a> <strong class="jxr_keyword">var</strong> emoji = <span class="jxr_string">"🎉"</span>; <em class="jxr_comment">// This contains surrogate pairs</em>
-<a class="jxr_linenumber" name="L6743" href="#L6743">6743</a> <strong class="jxr_keyword">var</strong> result5 = urlEncodePath(emoji);
-<a class="jxr_linenumber" name="L6744" href="#L6744">6744</a> assertNotNull(result5);
-<a class="jxr_linenumber" name="L6745" href="#L6745">6745</a> <em class="jxr_comment">// The surrogate pair code is executed during encoding</em>
-<a class="jxr_linenumber" name="L6746" href="#L6746">6746</a> <em class="jxr_comment">// Check that the result is different from input (encoding occurred) or contains encoded characters</em>
-<a class="jxr_linenumber" name="L6747" href="#L6747">6747</a> assertTrue(result5.length() > 0);
-<a class="jxr_linenumber" name="L6748" href="#L6748">6748</a> <em class="jxr_comment">// Also test with a string that combines regular characters with surrogate pairs</em>
-<a class="jxr_linenumber" name="L6749" href="#L6749">6749</a> <strong class="jxr_keyword">var</strong> result5b = urlEncodePath(<span class="jxr_string">"test🎉file"</span>);
-<a class="jxr_linenumber" name="L6750" href="#L6750">6750</a> assertNotNull(result5b);
-<a class="jxr_linenumber" name="L6751" href="#L6751">6751</a> assertTrue(result5b.length() > 0);
-<a class="jxr_linenumber" name="L6752" href="#L6752">6752</a>
-<a class="jxr_linenumber" name="L6753" href="#L6753">6753</a> <em class="jxr_comment">// Test - uppercase hex digits (caseDiff applied)</em>
-<a class="jxr_linenumber" name="L6754" href="#L6754">6754</a> <em class="jxr_comment">// forDigit returns lowercase 'a'-'f' for hex digits 10-15, which need to be converted to uppercase</em>
-<a class="jxr_linenumber" name="L6755" href="#L6755">6755</a> <em class="jxr_comment">// We need characters that produce bytes with hex values containing a-f</em>
-<a class="jxr_linenumber" name="L6756" href="#L6756">6756</a> <em class="jxr_comment">// For example, byte 0x0A produces hex "a", byte 0x0B produces "b", etc.</em>
-<a class="jxr_linenumber" name="L6757" href="#L6757">6757</a> <em class="jxr_comment">// Use characters that when UTF-8 encoded produce bytes with values 0x0A-0x0F</em>
-<a class="jxr_linenumber" name="L6758" href="#L6758">6758</a> <em class="jxr_comment">// Actually, any non-ASCII character will produce multi-byte UTF-8 encoding</em>
-<a class="jxr_linenumber" name="L6759" href="#L6759">6759</a> <em class="jxr_comment">// Let's use a character that produces bytes with hex digits a-f</em>
-<a class="jxr_linenumber" name="L6760" href="#L6760">6760</a> <strong class="jxr_keyword">var</strong> result6 = urlEncodePath(<span class="jxr_string">"test@file"</span>);
-<a class="jxr_linenumber" name="L6761" href="#L6761">6761</a> assertNotNull(result6);
-<a class="jxr_linenumber" name="L6762" href="#L6762">6762</a> <em class="jxr_comment">// Check that hex digits are uppercase (A-F, not a-f)</em>
-<a class="jxr_linenumber" name="L6763" href="#L6763">6763</a> <em class="jxr_comment">// The encoding should contain %40 for @</em>
-<a class="jxr_linenumber" name="L6764" href="#L6764">6764</a> assertTrue(result6.contains(<span class="jxr_string">"%40"</span>) || result6.contains(<span class="jxr_string">"%"</span>));
-<a class="jxr_linenumber" name="L6765" href="#L6765">6765</a> <em class="jxr_comment">// Verify all hex sequences are uppercase</em>
-<a class="jxr_linenumber" name="L6766" href="#L6766">6766</a> <strong class="jxr_keyword">var</strong> hexPattern = java.util.regex.Pattern.compile(<span class="jxr_string">"%([0-9A-Fa-f]{2})"</span>);
-<a class="jxr_linenumber" name="L6767" href="#L6767">6767</a> <strong class="jxr_keyword">var</strong> matcher = hexPattern.matcher(result6);
-<a class="jxr_linenumber" name="L6768" href="#L6768">6768</a> <strong class="jxr_keyword">boolean</strong> foundHex = false;
-<a class="jxr_linenumber" name="L6769" href="#L6769">6769</a> <strong class="jxr_keyword">while</strong> (matcher.find()) {
-<a class="jxr_linenumber" name="L6770" href="#L6770">6770</a> foundHex = <strong class="jxr_keyword">true</strong>;
-<a class="jxr_linenumber" name="L6771" href="#L6771">6771</a> <strong class="jxr_keyword">var</strong> hex = matcher.group(1);
-<a class="jxr_linenumber" name="L6772" href="#L6772">6772</a> <em class="jxr_comment">// Verify it's uppercase (caseDiff converts lowercase to uppercase)</em>
-<a class="jxr_linenumber" name="L6773" href="#L6773">6773</a> assertEquals(hex.toUpperCase(), hex);
-<a class="jxr_linenumber" name="L6774" href="#L6774">6774</a> }
-<a class="jxr_linenumber" name="L6775" href="#L6775">6775</a> <em class="jxr_comment">// Test with a character that produces bytes with hex digits a-f</em>
-<a class="jxr_linenumber" name="L6776" href="#L6776">6776</a> <em class="jxr_comment">// Use a character that when UTF-8 encoded produces bytes with values that result in lowercase hex</em>
-<a class="jxr_linenumber" name="L6777" href="#L6777">6777</a> <em class="jxr_comment">// For example, characters that produce bytes 0x0A-0x0F, 0x1A-0x1F, etc.</em>
-<a class="jxr_linenumber" name="L6778" href="#L6778">6778</a> <em class="jxr_comment">// Chinese character or other multi-byte UTF-8 character should work</em>
-<a class="jxr_linenumber" name="L6779" href="#L6779">6779</a> <strong class="jxr_keyword">var</strong> result7 = urlEncodePath(<span class="jxr_string">"test中文"</span>);
-<a class="jxr_linenumber" name="L6780" href="#L6780">6780</a> assertNotNull(result7);
-<a class="jxr_linenumber" name="L6781" href="#L6781">6781</a> assertTrue(result7.contains(<span class="jxr_string">"%"</span>));
-<a class="jxr_linenumber" name="L6782" href="#L6782">6782</a> <em class="jxr_comment">// Verify hex digits are uppercase</em>
-<a class="jxr_linenumber" name="L6783" href="#L6783">6783</a> <strong class="jxr_keyword">var</strong> matcher2 = hexPattern.matcher(result7);
-<a class="jxr_linenumber" name="L6784" href="#L6784">6784</a> <strong class="jxr_keyword">while</strong> (matcher2.find()) {
-<a class="jxr_linenumber" name="L6785" href="#L6785">6785</a> <strong class="jxr_keyword">var</strong> hex = matcher2.group(1);
-<a class="jxr_linenumber" name="L6786" href="#L6786">6786</a> <em class="jxr_comment">// Verify it's uppercase (code path and 7724 convert lowercase to uppercase)</em>
-<a class="jxr_linenumber" name="L6787" href="#L6787">6787</a> assertEquals(hex.toUpperCase(), hex);
-<a class="jxr_linenumber" name="L6788" href="#L6788">6788</a> }
-<a class="jxr_linenumber" name="L6789" href="#L6789">6789</a> <em class="jxr_comment">// If we found hex sequences, verify they're uppercase</em>
-<a class="jxr_linenumber" name="L6790" href="#L6790">6790</a> <strong class="jxr_keyword">if</strong> (foundHex) {
-<a class="jxr_linenumber" name="L6791" href="#L6791">6791</a> <em class="jxr_comment">// All hex should be uppercase</em>
-<a class="jxr_linenumber" name="L6792" href="#L6792">6792</a> assertTrue(result6.equals(result6.toUpperCase()) || result6.matches(<span class="jxr_string">".*%[0-9A-F]{2}.*"</span>));
-<a class="jxr_linenumber" name="L6793" href="#L6793">6793</a> }
-<a class="jxr_linenumber" name="L6794" href="#L6794">6794</a> }
-<a class="jxr_linenumber" name="L6795" href="#L6795">6795</a>
-<a class="jxr_linenumber" name="L6796" href="#L6796">6796</a> <em class="jxr_comment">//====================================================================================================</em>
-<a class="jxr_linenumber" name="L6797" href="#L6797">6797</a> <em class="jxr_comment">// wordCount(String)</em>
-<a class="jxr_linenumber" name="L6798" href="#L6798">6798</a> <em class="jxr_comment">//====================================================================================================</em>
-<a class="jxr_linenumber" name="L6799" href="#L6799">6799</a> @Test
-<a class="jxr_linenumber" name="L6800" href="#L6800">6800</a> <strong class="jxr_keyword">void</strong> a231_wordCount() {
-<a class="jxr_linenumber" name="L6801" href="#L6801">6801</a> assertEquals(0, wordCount(<strong class="jxr_keyword">null</strong>));
-<a class="jxr_linenumber" name="L6802" href="#L6802">6802</a> assertEquals(0, wordCount(<span class="jxr_string">""</span>));
-<a class="jxr_linenumber" name="L6803" href="#L6803">6803</a> assertEquals(0, wordCount(<span class="jxr_string">" "</span>));
-<a class="jxr_linenumber" name="L6804" href="#L6804">6804</a> assertEquals(1, wordCount(<span class="jxr_string">"hello"</span>));
-<a class="jxr_linenumber" name="L6805" href="#L6805">6805</a> assertEquals(2, wordCount(<span class="jxr_string">"Hello world"</span>));
-<a class="jxr_linenumber" name="L6806" href="#L6806">6806</a> assertEquals(4, wordCount(<span class="jxr_string">"The quick brown fox"</span>));
-<a class="jxr_linenumber" name="L6807" href="#L6807">6807</a> assertEquals(5, wordCount(<span class="jxr_string">"Hello, world! How are you?"</span>));
-<a class="jxr_linenumber" name="L6808" href="#L6808">6808</a> assertEquals(3, wordCount(<span class="jxr_string">"one\ttwo\nthree"</span>));
-<a class="jxr_linenumber" name="L6809" href="#L6809">6809</a> assertEquals(1, wordCount(<span class="jxr_string">"hello123"</span>));
-<a class="jxr_linenumber" name="L6810" href="#L6810">6810</a> <em class="jxr_comment">// Underscores are part of word characters, so "hello_world" is one word</em>
-<a class="jxr_linenumber" name="L6811" href="#L6811">6811</a> assertEquals(1, wordCount(<span class="jxr_string">"hello_world"</span>));
-<a class="jxr_linenumber" name="L6812" href="#L6812">6812</a> assertEquals(2, wordCount(<span class="jxr_string">"hello world"</span>));
-<a class="jxr_linenumber" name="L6813" href="#L6813">6813</a> }
-<a class="jxr_linenumber" name="L6814" href="#L6814">6814</a>
-<a class="jxr_linenumber" name="L6815" href="#L6815">6815</a> <em class="jxr_comment">//====================================================================================================</em>
-<a class="jxr_linenumber" name="L6816" href="#L6816">6816</a> <em class="jxr_comment">// wrap(String,int) and wrap(String,int,String)</em>
-<a class="jxr_linenumber" name="L6817" href="#L6817">6817</a> <em class="jxr_comment">//====================================================================================================</em>
-<a class="jxr_linenumber" name="L6818" href="#L6818">6818</a> @Test
-<a class="jxr_linenumber" name="L6819" href="#L6819">6819</a> <strong class="jxr_keyword">void</strong> a232_wrap() {
-<a class="jxr_linenumber" name="L6820" href="#L6820">6820</a> <em class="jxr_comment">// wrap(String,int) - uses default newline "\n"</em>
-<a class="jxr_linenumber" name="L6821" href="#L6821">6821</a> assertNull(wrap(<strong class="jxr_keyword">null</strong>, 10));
-<a class="jxr_linenumber" name="L6822" href="#L6822">6822</a> assertEquals(<span class="jxr_string">""</span>, wrap(<span class="jxr_string">""</span>, 10));
-<a class="jxr_linenumber" name="L6823" href="#L6823">6823</a> assertEquals(<span class="jxr_string">"hello\nworld"</span>, wrap(<span class="jxr_string">"hello world"</span>, 10));
-<a class="jxr_linenumber" name="L6824" href="#L6824">6824</a> assertEquals(<span class="jxr_string">"hello\nworld\ntest"</span>, wrap(<span class="jxr_string">"hello world test"</span>, 10));
-<a class="jxr_linenumber" name="L6825" href="#L6825">6825</a> assertEquals(<span class="jxr_string">"hello world"</span>, wrap(<span class="jxr_string">"hello world"</span>, 20));
-<a class="jxr_linenumber" name="L6826" href="#L6826">6826</a> assertEquals(<span class="jxr_string">"hello\nworld"</span>, wrap(<span class="jxr_string">"hello world"</span>, 5));
-<a class="jxr_linenumber" name="L6827" href="#L6827">6827</a> assertEquals(<span class="jxr_string">"supercalifragilisticexpialidocious"</span>, wrap(<span class="jxr_string">"supercalifragilisticexpialidocious"</span>, 10));
-<a class="jxr_linenumber" name="L6828" href="#L6828">6828</a> assertEquals(<span class="jxr_string">"hello\nworld"</span>, wrap(<span class="jxr_string">"hello world"</span>, 10));
-<a class="jxr_linenumber" name="L6829" href="#L6829">6829</a> assertEquals(<span class="jxr_string">"line1\nline2"</span>, wrap(<span class="jxr_string">"line1\nline2"</span>, 10));
-<a class="jxr_linenumber" name="L6830" href="#L6830">6830</a> assertEquals(<span class="jxr_string">"a\nb\nc"</span>, wrap(<span class="jxr_string">"a b c"</span>, 1));
-<a class="jxr_linenumber" name="L6831" href="#L6831">6831</a> assertThrows(IllegalArgumentException.<strong class="jxr_keyword">class</strong>, () -> wrap(<span class="jxr_string">"test"</span>, 0));
-<a class="jxr_linenumber" name="L6832" href="#L6832">6832</a> assertThrows(IllegalArgumentException.<strong class="jxr_keyword">class</strong>, () -> wrap(<span class="jxr_string">"test"</span>, -1));
-<a class="jxr_linenumber" name="L6833" href="#L6833">6833</a>
-<a class="jxr_linenumber" name="L6834" href="#L6834">6834</a> <em class="jxr_comment">// wrap(String,int,String) - with custom newline</em>
-<a class="jxr_linenumber" name="L6835" href="#L6835">6835</a> assertNull(wrap(<strong class="jxr_keyword">null</strong>, 10, <span class="jxr_string">"<br>"</span>));
-<a class="jxr_linenumber" name="L6836" href="#L6836">6836</a> assertEquals(<span class="jxr_string">""</span>, wrap(<span class="jxr_string">""</span>, 10, <span class="jxr_string">"<br>"</span>));
-<a class="jxr_linenumber" name="L6837" href="#L6837">6837</a> assertEquals(<span class="jxr_string">"hello<br>world"</span>, wrap(<span class="jxr_string">"hello world"</span>, 10, <span class="jxr_string">"<br>"</span>));
-<a class="jxr_linenumber" name="L6838" href="#L6838">6838</a> assertEquals(<span class="jxr_string">"hello<br>world<br>test"</span>, wrap(<span class="jxr_string">"hello world test"</span>, 10, <span class="jxr_string">"<br>"</span>));
-<a class="jxr_linenumber" name="L6839" href="#L6839">6839</a> assertEquals(<span class="jxr_string">"hello world"</span>, wrap(<span class="jxr_string">"hello world"</span>, 20, <span class="jxr_string">"<br>"</span>));
-<a class="jxr_linenumber" name="L6840" href="#L6840">6840</a> assertEquals(<span class="jxr_string">"hello<br>world"</span>, wrap(<span class="jxr_string">"hello world"</span>, 5, <span class="jxr_string">"<br>"</span>));
-<a class="jxr_linenumber" name="L6841" href="#L6841">6841</a> assertEquals(<span class="jxr_string">"supercalifragilisticexpialidocious"</span>, wrap(<span class="jxr_string">"supercalifragilisticexpialidocious"</span>, 10, <span class="jxr_string">"<br>"</span>));
-<a class="jxr_linenumber" name="L6842" href="#L6842">6842</a> assertEquals(<span class="jxr_string">"line1<br>line2"</span>, wrap(<span class="jxr_string">"line1\nline2"</span>, 10, <span class="jxr_string">"<br>"</span>));
-<a class="jxr_linenumber" name="L6843" href="#L6843">6843</a> assertEquals(<span class="jxr_string">"a<br>b<br>c"</span>, wrap(<span class="jxr_string">"a b c"</span>, 1, <span class="jxr_string">"<br>"</span>));
-<a class="jxr_linenumber" name="L6844" href="#L6844">6844</a> assertThrows(IllegalArgumentException.<strong class="jxr_keyword">class</strong>, () -> wrap(<span class="jxr_string">"test"</span>, 0, <span class="jxr_string">"\n"</span>));
-<a class="jxr_linenumber" name="L6845" href="#L6845">6845</a> assertThrows(IllegalArgumentException.<strong class="jxr_keyword">class</strong>, () -> wrap(<span class="jxr_string">"test"</span>, -1, <span class="jxr_string">"\n"</span>));
-<a class="jxr_linenumber" name="L6846" href="#L6846">6846</a> assertThrows(IllegalArgumentException.<strong class="jxr_keyword">class</strong>, () -> wrap(<span class="jxr_string">"test"</span>, 10, <strong class="jxr_keyword">null</strong>));
-<a class="jxr_linenumber" name="L6847" href="#L6847">6847</a>
-<a class="jxr_linenumber" name="L6848" href="#L6848">6848</a> <em class="jxr_comment">// Test</em>
-<a class="jxr_linenumber" name="L6849" href="#L6849">6849</a> <strong class="jxr_keyword">var</strong> result1 = wrap(<span class="jxr_string">"line1\n\nline2"</span>, 10, <span class="jxr_string">"\n"</span>);
-<a class="jxr_linenumber" name="L6850" href="#L6850">6850</a> assertTrue(result1.contains(<span class="jxr_string">"\n\n"</span>)); <em class="jxr_comment">// Empty line preserved</em>
-<a class="jxr_linenumber" name="L6851" href="#L6851">6851</a>
-<a class="jxr_linenumber" name="L6852" href="#L6852">6852</a> <em class="jxr_comment">// Test)</em>
-<a class="jxr_linenumber" name="L6853" href="#L6853">6853</a> <em class="jxr_comment">// Multiple spaces create empty words that should be skipped</em>
-<a class="jxr_linenumber" name="L6854" href="#L6854">6854</a> <strong class="jxr_keyword">var</strong> result2 = wrap(<span class="jxr_string">"word1 word2"</span>, 10, <span class="jxr_string">"\n"</span>);
-<a class="jxr_linenumber" name="L6855" href="#L6855">6855</a> assertTrue(result2.contains(<span class="jxr_string">"word1"</span>));
-<a class="jxr_linenumber" name="L6856" href="#L6856">6856</a> assertTrue(result2.contains(<span class="jxr_string">"word2"</span>));
-<a class="jxr_linenumber" name="L6857" href="#L6857">6857</a> <em class="jxr_comment">// Test with multiple consecutive spaces</em>
-<a class="jxr_linenumber" name="L6858" href="#L6858">6858</a> <strong class="jxr_keyword">var</strong> result2b = wrap(<span class="jxr_string">"a b c"</span>, 10, <span class="jxr_string">"\n"</span>);
-<a class="jxr_linenumber" name="L6859" href="#L6859">6859</a> assertTrue(result2b.contains(<span class="jxr_string">"a"</span>));
-<a class="jxr_linenumber" name="L6860" href="#L6860">6860</a> assertTrue(result2b.contains(<span class="jxr_string">"b"</span>));
-<a class="jxr_linenumber" name="L6861" href="#L6861">6861</a> assertTrue(result2b.contains(<span class="jxr_string">"c"</span>));
-<a class="jxr_linenumber" name="L6862" href="#L6862">6862</a> <em class="jxr_comment">// Test with leading spaces - split(" +") creates empty string at start</em>
-<a class="jxr_linenumber" name="L6863" href="#L6863">6863</a> <strong class="jxr_keyword">var</strong> result2c = wrap(<span class="jxr_string">" hello world"</span>, 10, <span class="jxr_string">"\n"</span>);
-<a class="jxr_linenumber" name="L6864" href="#L6864">6864</a> assertTrue(result2c.contains(<span class="jxr_string">"hello"</span>));
-<a class="jxr_linenumber" name="L6865" href="#L6865">6865</a> assertTrue(result2c.contains(<span class="jxr_string">"world"</span>));
-<a class="jxr_linenumber" name="L6866" href="#L6866">6866</a> <em class="jxr_comment">// Test with trailing spaces - split(" +") creates empty string at end</em>
-<a class="jxr_linenumber" name="L6867" href="#L6867">6867</a> <strong class="jxr_keyword">var</strong> result2d = wrap(<span class="jxr_string">"hello world "</span>, 10, <span class="jxr_string">"\n"</span>);
-<a class="jxr_linenumber" name="L6868" href="#L6868">6868</a> assertTrue(result2d.contains(<span class="jxr_string">"hello"</span>));
-<a class="jxr_linenumber" name="L6869" href="#L6869">6869</a> assertTrue(result2d.contains(<span class="jxr_string">"world"</span>));
-<a class="jxr_linenumber" name="L6870" href="#L6870">6870</a> <em class="jxr_comment">// Test with both leading and trailing spaces</em>
-<a class="jxr_linenumber" name="L6871" href="#L6871">6871</a> <strong class="jxr_keyword">var</strong> result2e = wrap(<span class="jxr_string">" hello world "</span>, 10, <span class="jxr_string">"\n"</span>);
-<a class="jxr_linenumber" name="L6872" href="#L6872">6872</a> assertTrue(result2e.contains(<span class="jxr_string">"hello"</span>));
-<a class="jxr_linenumber" name="L6873" href="#L6873">6873</a> assertTrue(result2e.contains(<span class="jxr_string">"world"</span>));
-<a class="jxr_linenumber" name="L6874" href="#L6874">6874</a>
-<a class="jxr_linenumber" name="L6875" href="#L6875">6875</a> <em class="jxr_comment">// Test</em>
-<a class="jxr_linenumber" name="L6876" href="#L6876">6876</a> <em class="jxr_comment">// This tests breaking a long word when it's the first word on a line</em>
-<a class="jxr_linenumber" name="L6877" href="#L6877">6877</a> <em class="jxr_comment">// Code path: result.length() > 0 (result already has content)</em>
-<a class="jxr_linenumber" name="L6878" href="#L6878">6878</a> <em class="jxr_comment">// Code path: while loop that breaks word into chunks</em>
-<a class="jxr_linenumber" name="L6879" href="#L6879">6879</a> <em class="jxr_comment">// Code path: wordPos > 0 (not first iteration)</em>
-<a class="jxr_linenumber" name="L6880" href="#L6880">6880</a> <em class="jxr_comment">// Code path: remaining <= wrapLength (remaining fits)</em>
-<a class="jxr_linenumber" name="L6881" href="#L6881">6881</a> <em class="jxr_comment">// Code path: append remaining</em>
-<a class="jxr_linenumber" name="L6882" href="#L6882">6882</a> <em class="jxr_comment">// Code path: break</em>
-<a class="jxr_linenumber" name="L6883" href="#L6883">6883</a> <em class="jxr_comment">// Code path: append chunk</em>
-<a class="jxr_linenumber" name="L6884" href="#L6884">6884</a> <em class="jxr_comment">// Code path: advance position</em>
-<a class="jxr_linenumber" name="L6885" href="#L6885">6885</a> <strong class="jxr_keyword">var</strong> result3 = wrap(<span class="jxr_string">"short verylongword here"</span>, 5, <span class="jxr_string">"\n"</span>);
-<a class="jxr_linenumber" name="L6886" href="#L6886">6886</a> assertFalse(result3.contains(<span class="jxr_string">"verylongword"</span>)); <em class="jxr_comment">// Word should be split into chunks</em>
-<a class="jxr_linenumber" name="L6887" href="#L6887">6887</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> line : result3.split(<span class="jxr_string">"\n"</span>)) {
-<a class="jxr_linenumber" name="L6888" href="#L6888">6888</a> <strong class="jxr_keyword">if</strong> (! line.isEmpty())
-<a class="jxr_linenumber" name="L6889" href="#L6889">6889</a> assertTrue(line.length() <= 5);
-<a class="jxr_linenumber" name="L6890" href="#L6890">6890</a> }
-<a class="jxr_linenumber" name="L6891" href="#L6891">6891</a> <em class="jxr_comment">// Test with result already having content > 0)</em>
-<a class="jxr_linenumber" name="L6892" href="#L6892">6892</a> <em class="jxr_comment">// After a previous line, a long word that needs breaking as first word on new line</em>
-<a class="jxr_linenumber" name="L6893" href="#L6893">6893</a> <em class="jxr_comment">// This happens when a previous line was completed and we start a new line</em>
-<a class="jxr_linenumber" name="L6894" href="#L6894">6894</a> <strong class="jxr_keyword">var</strong> result3b = wrap(<span class="jxr_string">"first\nverylongword here"</span>, 5, <span class="jxr_string">"\n"</span>);
-<a class="jxr_linenumber" name="L6895" href="#L6895">6895</a> <em class="jxr_comment">// After "first\n", "verylongword" is the first word on the new line and needs breaking</em>
-<a class="jxr_linenumber" name="L6896" href="#L6896">6896</a> assertTrue(result3b.contains(<span class="jxr_string">"first"</span>));
-<a class="jxr_linenumber" name="L6897" href="#L6897">6897</a> assertFalse(result3b.contains(<span class="jxr_string">"verylongword"</span>)); <em class="jxr_comment">// Long word should be broken</em>
-<a class="jxr_linenumber" name="L6898" href="#L6898">6898</a> <em class="jxr_comment">// Test word that breaks into multiple chunks (covers code path)</em>
-<a class="jxr_linenumber" name="L6899" href="#L6899">6899</a> <em class="jxr_comment">// Word length 15, wrapLength 5 -> 3 chunks of 5, 5, 5</em>
-<a class="jxr_linenumber" name="L6900" href="#L6900">6900</a> <em class="jxr_comment">// This tests: wordPos > 0 , append chunk , advance position </em>
-<a class="jxr_linenumber" name="L6901" href="#L6901">6901</a> <em class="jxr_comment">// And: remaining <= wrapLength , append remaining , break </em>
-<a class="jxr_linenumber" name="L6902" href="#L6902">6902</a> <strong class="jxr_keyword">var</strong> result3c = wrap(<span class="jxr_string">"abcdefghijklmno here"</span>, 5, <span class="jxr_string">"\n"</span>);
-<a class="jxr_linenumber" name="L6903" href="#L6903">6903</a> assertTrue(result3c.contains(<span class="jxr_string">"abcde"</span>)); <em class="jxr_comment">// First chunk (wordPos == 0, no newline before)</em>
-<a class="jxr_linenumber" name="L6904" href="#L6904">6904</a> assertTrue(result3c.contains(<span class="jxr_string">"fghij"</span>)); <em class="jxr_comment">// Second chunk (wordPos > 0, newline before, code path)</em>
-<a class="jxr_linenumber" name="L6905" href="#L6905">6905</a> assertTrue(result3c.contains(<span class="jxr_string">"klmno"</span>)); <em class="jxr_comment">// Third chunk (remaining <= wrapLength, code path)</em>
-<a class="jxr_linenumber" name="L6906" href="#L6906">6906</a>
-<a class="jxr_linenumber" name="L6907" href="#L6907">6907</a> <em class="jxr_comment">// Test</em>
-<a class="jxr_linenumber" name="L6908" href="#L6908">6908</a> <strong class="jxr_keyword">var</strong> result4 = wrap(<span class="jxr_string">"short word verylongword here"</span>, 10, <span class="jxr_string">"\n"</span>);
-<a class="jxr_linenumber" name="L6909" href="#L6909">6909</a> assertFalse(result4.contains(<span class="jxr_string">"verylongword"</span>)); <em class="jxr_comment">// Word should be split into chunks</em>
-<a class="jxr_linenumber" name="L6910" href="#L6910">6910</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> line : result4.split(<span class="jxr_string">"\n"</span>)) {
-<a class="jxr_linenumber" name="L6911" href="#L6911">6911</a> <strong class="jxr_keyword">if</strong> (! line.isEmpty())
-<a class="jxr_linenumber" name="L6912" href="#L6912">6912</a> assertTrue(line.length() <= 10);
-<a class="jxr_linenumber" name="L6913" href="#L6913">6913</a> }
-<a class="jxr_linenumber" name="L6914" href="#L6914">6914</a>
-<a class="jxr_linenumber" name="L6915" href="#L6915">6915</a> <em class="jxr_comment">// Test > 0)</em>
-<a class="jxr_linenumber" name="L6916" href="#L6916">6916</a> <strong class="jxr_keyword">var</strong> result5 = wrap(<span class="jxr_string">"short word"</span>, 20, <span class="jxr_string">"\n"</span>);
-<a class="jxr_linenumber" name="L6917" href="#L6917">6917</a> assertEquals(<span class="jxr_string">"short word"</span>, result5); <em class="jxr_comment">// Remaining line appended</em>
-<a class="jxr_linenumber" name="L6918" href="#L6918">6918</a> }
-<a class="jxr_linenumber" name="L6919" href="#L6919">6919</a> }
+<a class="jxr_linenumber" name="L6566" href="#L6566">6566</a> System.out.println(<span class="jxr_string">"=== Testing unescapeChars with a\\\\b, backslash NOT in escaped set ==="</span>);
+<a class="jxr_linenumber" name="L6567" href="#L6567">6567</a> <strong class="jxr_keyword">var</strong> result2 = unescapeChars(<span class="jxr_string">"a\\\\b"</span>, AsciiSet.of(<span class="jxr_string">","</span>));
+<a class="jxr_linenumber" name="L6568" href="#L6568">6568</a> System.out.println(<span class="jxr_string">"Result: "</span> + java.util.Arrays.toString(result2.toCharArray()));
+<a class="jxr_linenumber" name="L6569" href="#L6569">6569</a> assertEquals(<span class="jxr_string">"a\\\\b"</span>, result2); <em class="jxr_comment">// '\' not in escaped set</em>
+<a class="jxr_linenumber" name="L6570" href="#L6570">6570</a> }
+<a class="jxr_linenumber" name="L6571" href="#L6571">6571</a>
+<a class="jxr_linenumber" name="L6572" href="#L6572">6572</a> <em class="jxr_comment">//====================================================================================================</em>
+<a class="jxr_linenumber" name="L6573" href="#L6573">6573</a> <em class="jxr_comment">// unescapeHtml(String)</em>
+<a class="jxr_linenumber" name="L6574" href="#L6574">6574</a> <em class="jxr_comment">//====================================================================================================</em>
+<a class="jxr_linenumber" name="L6575" href="#L6575">6575</a> @Test
+<a class="jxr_linenumber" name="L6576" href="#L6576">6576</a> <strong class="jxr_keyword">void</strong> a223_unescapeHtml() {
+<a class="jxr_linenumber" name="L6577" href="#L6577">6577</a> assertNull(unescapeHtml(<strong class="jxr_keyword">null</strong>));
+<a class="jxr_linenumber" name="L6578" href="#L6578">6578</a> assertEquals(<span class="jxr_string">""</span>, unescapeHtml(<span class="jxr_string">""</span>));
+<a class="jxr_linenumber" name="L6579" href="#L6579">6579</a> assertEquals(<span class="jxr_string">"Hello World"</span>, unescapeHtml(<span class="jxr_string">"Hello World"</span>));
+<a class="jxr_linenumber" name="L6580" href="#L6580">6580</a> assertEquals(<span class="jxr_string">"<script>"</span>, unescapeHtml(<span class="jxr_string">"&lt;script&gt;"</span>));
+<a class="jxr_linenumber" name="L6581" href="#L6581">6581</a> assertEquals(<span class="jxr_string">"\"Hello\""</span>, unescapeHtml(<span class="jxr_string">"&quot;Hello&quot;"</span>));
+<a class="jxr_linenumber" name="L6582" href="#L6582">6582</a> assertEquals(<span class="jxr_string">"It's a test"</span>, unescapeHtml(<span class="jxr_string">"It&#39;s a test"</span>));
+<a class="jxr_linenumber" name="L6583" href="#L6583">6583</a> assertEquals(<span class="jxr_string">"It's a test"</span>, unescapeHtml(<span class="jxr_string">"It&apos;s a test"</span>));
+<a class="jxr_linenumber" name="L6584" href="#L6584">6584</a> assertEquals(<span class="jxr_string">"&"</span>, unescapeHtml(<span class="jxr_string">"&amp;"</span>));
+<a class="jxr_linenumber" name="L6585" href="#L6585">6585</a> assertEquals(<span class="jxr_string">"<tag>text</tag>"</span>, unescapeHtml(<span class="jxr_string">"&lt;tag&gt;text&lt;/tag&gt;"</span>));
+<a class="jxr_linenumber" name="L6586" href="#L6586">6586</a> <em class="jxr_comment">// Test round-trip</em>
+<a class="jxr_linenumber" name="L6587" href="#L6587">6587</a> assertEquals(<span class="jxr_string">"Hello & World"</span>, unescapeHtml(escapeHtml(<span class="jxr_string">"Hello & World"</span>)));
+<a class="jxr_linenumber" name="L6588" href="#L6588">6588</a> }
+<a class="jxr_linenumber" name="L6589" href="#L6589">6589</a>
+<a class="jxr_linenumber" name="L6590" href="#L6590">6590</a> <em class="jxr_comment">//====================================================================================================</em>
+<a class="jxr_linenumber" name="L6591" href="#L6591">6591</a> <em class="jxr_comment">// unescapeXml(String)</em>
+<a class="jxr_linenumber" name="L6592" href="#L6592">6592</a> <em class="jxr_comment">//====================================================================================================</em>
+<a class="jxr_linenumber" name="L6593" href="#L6593">6593</a> @Test
+<a class="jxr_linenumber" name="L6594" href="#L6594">6594</a> <strong class="jxr_keyword">void</strong> a224_unescapeXml() {
+<a class="jxr_linenumber" name="L6595" href="#L6595">6595</a> assertNull(unescapeXml(<strong class="jxr_keyword">null</strong>));
+<a class="jxr_linenumber" name="L6596" href="#L6596">6596</a> assertEquals(<span class="jxr_string">""</span>, unescapeXml(<span class="jxr_string">""</span>));
+<a class="jxr_linenumber" name="L6597" href="#L6597">6597</a> assertEquals(<span class="jxr_string">"Hello World"</span>, unescapeXml(<span class="jxr_string">"Hello World"</span>));
+<a class="jxr_linenumber" name="L6598" href="#L6598">6598</a> assertEquals(<span class="jxr_string">"<tag>"</span>, unescapeXml(<span class="jxr_string">"&lt;tag&gt;"</span>));
+<a class="jxr_linenumber" name="L6599" href="#L6599">6599</a> assertEquals(<span class="jxr_string">"\"Hello\""</span>, unescapeXml(<span class="jxr_string">"&quot;Hello&quot;"</span>));
+<a class="jxr_linenumber" name="L6600" href="#L6600">6600</a> assertEquals(<span class="jxr_string">"'test'"</span>, unescapeXml(<span class="jxr_string">"&apos;test&apos;"</span>));
+<a class="jxr_linenumber" name="L6601" href="#L6601">6601</a> assertEquals(<span class="jxr_string">"&"</span>, unescapeXml(<span class="jxr_string">"&amp;"</span>));
+<a class="jxr_linenumber" name="L6602" href="#L6602">6602</a> assertEquals(<span class="jxr_string">"<tag>text</tag>"</span>, unescapeXml(<span class="jxr_string">"&lt;tag&gt;text&lt;/tag&gt;"</span>));
+<a class="jxr_linenumber" name="L6603" href="#L6603">6603</a> }
+<a class="jxr_linenumber" name="L6604" href="#L6604">6604</a>
+<a class="jxr_linenumber" name="L6605" href="#L6605">6605</a> <em class="jxr_comment">//====================================================================================================</em>
+<a class="jxr_linenumber" name="L6606" href="#L6606">6606</a> <em class="jxr_comment">// unicodeSequence(char)</em>
+<a class="jxr_linenumber" name="L6607" href="#L6607">6607</a> <em class="jxr_comment">//====================================================================================================</em>
+<a class="jxr_linenumber" name="L6608" href="#L6608">6608</a> @Test
+<a class="jxr_linenumber" name="L6609" href="#L6609">6609</a> <strong class="jxr_keyword">void</strong> a225_unicodeSequence() {
+<a class="jxr_linenumber" name="L6610" href="#L6610">6610</a> assertEquals(<span class="jxr_string">"\\u0041"</span>, unicodeSequence('A'));
+<a class="jxr_linenumber" name="L6611" href="#L6611">6611</a> assertEquals(<span class="jxr_string">"\\u0061"</span>, unicodeSequence('a'));
+<a class="jxr_linenumber" name="L6612" href="#L6612">6612</a> assertEquals(<span class="jxr_string">"\\u0030"</span>, unicodeSequence('0'));
+<a class="jxr_linenumber" name="L6613" href="#L6613">6613</a> assertEquals(<span class="jxr_string">"\\u0000"</span>, unicodeSequence('\u0000'));
+<a class="jxr_linenumber" name="L6614" href="#L6614">6614</a> assertEquals(<span class="jxr_string">"\\u00FF"</span>, unicodeSequence('\u00FF'));
+<a class="jxr_linenumber" name="L6615" href="#L6615">6615</a> assertEquals(<span class="jxr_string">"\\uFFFF"</span>, unicodeSequence('\uFFFF'));
+<a class="jxr_linenumber" name="L6616" href="#L6616">6616</a> }
+<a class="jxr_linenumber" name="L6617" href="#L6617">6617</a>
+<a class="jxr_linenumber" name="L6618" href="#L6618">6618</a> <em class="jxr_comment">//====================================================================================================</em>
+<a class="jxr_linenumber" name="L6619" href="#L6619">6619</a> <em class="jxr_comment">// upperCase(String)</em>
+<a class="jxr_linenumber" name="L6620" href="#L6620">6620</a> <em class="jxr_comment">//====================================================================================================</em>
+<a class="jxr_linenumber" name="L6621" href="#L6621">6621</a> @Test
+<a class="jxr_linenumber" name="L6622" href="#L6622">6622</a> <strong class="jxr_keyword">void</strong> a226_upperCase() {
+<a class="jxr_linenumber" name="L6623" href="#L6623">6623</a> assertNull(upperCase(<strong class="jxr_keyword">null</strong>));
+<a class="jxr_linenumber" name="L6624" href="#L6624">6624</a> assertEquals(<span class="jxr_string">""</span>, upperCase(<span class="jxr_string">""</span>));
+<a class="jxr_linenumber" name="L6625" href="#L6625">6625</a> assertEquals(<span class="jxr_string">"HELLO"</span>, upperCase(<span class="jxr_string">"hello"</span>));
+<a class="jxr_linenumber" name="L6626" href="#L6626">6626</a> assertEquals(<span class="jxr_string">"HELLO WORLD"</span>, upperCase(<span class="jxr_string">"Hello World"</span>));
+<a class="jxr_linenumber" name="L6627" href="#L6627">6627</a> assertEquals(<span class="jxr_string">"123"</span>, upperCase(<span class="jxr_string">"123"</span>));
+<a class="jxr_linenumber" name="L6628" href="#L6628">6628</a> assertEquals(<span class="jxr_string">"ABC"</span>, upperCase(<span class="jxr_string">"abc"</span>));
+<a class="jxr_linenumber" name="L6629" href="#L6629">6629</a> }
+<a class="jxr_linenumber" name="L6630" href="#L6630">6630</a>
+<a class="jxr_linenumber" name="L6631" href="#L6631">6631</a> <em class="jxr_comment">//====================================================================================================</em>
+<a class="jxr_linenumber" name="L6632" href="#L6632">6632</a> <em class="jxr_comment">// urlDecode(String)</em>
+<a class="jxr_linenumber" name="L6633" href="#L6633">6633</a> <em class="jxr_comment">//====================================================================================================</em>
+<a class="jxr_linenumber" name="L6634" href="#L6634">6634</a> @Test
+<a class="jxr_linenumber" name="L6635" href="#L6635">6635</a> <strong class="jxr_keyword">void</strong> a227_urlDecode() {
+<a class="jxr_linenumber" name="L6636" href="#L6636">6636</a> assertNull(urlDecode(<strong class="jxr_keyword">null</strong>));
+<a class="jxr_linenumber" name="L6637" href="#L6637">6637</a> assertEquals(<span class="jxr_string">""</span>, urlDecode(<span class="jxr_string">""</span>));
+<a class="jxr_linenumber" name="L6638" href="#L6638">6638</a> assertEquals(<span class="jxr_string">"Hello World"</span>, urlDecode(<span class="jxr_string">"Hello+World"</span>));
+<a class="jxr_linenumber" name="L6639" href="#L6639">6639</a> assertEquals(<span class="jxr_string">"Hello World"</span>, urlDecode(<span class="jxr_string">"Hello%20World"</span>));
+<a class="jxr_linenumber" name="L6640" href="#L6640">6640</a> assertEquals(<span class="jxr_string">"test@example.com"</span>, urlDecode(<span class="jxr_string">"test%40example.com"</span>));
+<a class="jxr_linenumber" name="L6641" href="#L6641">6641</a> assertEquals(<span class="jxr_string">"a=b&c=d"</span>, urlDecode(<span class="jxr_string">"a%3Db%26c%3Dd"</span>));
+<a class="jxr_linenumber" name="L6642" href="#L6642">6642</a> <em class="jxr_comment">// No encoding needed - returns as-is</em>
+<a class="jxr_linenumber" name="L6643" href="#L6643">6643</a> assertEquals(<span class="jxr_string">"Hello"</span>, urlDecode(<span class="jxr_string">"Hello"</span>));
+<a class="jxr_linenumber" name="L6644" href="#L6644">6644</a> }
+<a class="jxr_linenumber" name="L6645" href="#L6645">6645</a>
+<a class="jxr_linenumber" name="L6646" href="#L6646">6646</a> <em class="jxr_comment">//====================================================================================================</em>
+<a class="jxr_linenumber" name="L6647" href="#L6647">6647</a> <em class="jxr_comment">// urlEncode(String)</em>
+<a class="jxr_linenumber" name="L6648" href="#L6648">6648</a> <em class="jxr_comment">//====================================================================================================</em>
+<a class="jxr_linenumber" name="L6649" href="#L6649">6649</a> @Test
+<a class="jxr_linenumber" name="L6650" href="#L6650">6650</a> <strong class="jxr_keyword">void</strong> a228_urlEncode() {
+<a class="jxr_linenumber" name="L6651" href="#L6651">6651</a> assertNull(urlEncode(<strong class="jxr_keyword">null</strong>));
+<a class="jxr_linenumber" name="L6652" href="#L6652">6652</a> assertEquals(<span class="jxr_string">""</span>, urlEncode(<span class="jxr_string">""</span>));
+<a class="jxr_linenumber" name="L6653" href="#L6653">6653</a> assertEquals(<span class="jxr_string">"Hello+World"</span>, urlEncode(<span class="jxr_string">"Hello World"</span>));
+<a class="jxr_linenumber" name="L6654" href="#L6654">6654</a> assertEquals(<span class="jxr_string">"test%40example.com"</span>, urlEncode(<span class="jxr_string">"test@example.com"</span>));
+<a class="jxr_linenumber" name="L6655" href="#L6655">6655</a> assertEquals(<span class="jxr_string">"a%3Db%26c%3Dd"</span>, urlEncode(<span class="jxr_string">"a=b&c=d"</span>));
+<a class="jxr_linenumber" name="L6656" href="#L6656">6656</a> <em class="jxr_comment">// No encoding needed - returns as-is</em>
+<a class="jxr_linenumber" name="L6657" href="#L6657">6657</a> assertEquals(<span class="jxr_string">"Hello"</span>, urlEncode(<span class="jxr_string">"Hello"</span>));
+<a class="jxr_linenumber" name="L6658" href="#L6658">6658</a> assertEquals(<span class="jxr_string">"test123"</span>, urlEncode(<span class="jxr_string">"test123"</span>));
+<a class="jxr_linenumber" name="L6659" href="#L6659">6659</a>
+<a class="jxr_linenumber" name="L6660" href="#L6660">6660</a> <em class="jxr_comment">// Test</em>
+<a class="jxr_linenumber" name="L6661" href="#L6661">6661</a> <strong class="jxr_keyword">var</strong> result1 = urlEncode(<span class="jxr_string">"test@example.com"</span>);
+<a class="jxr_linenumber" name="L6662" href="#L6662">6662</a> assertTrue(result1.contains(<span class="jxr_string">"%40"</span>)); <em class="jxr_comment">// @ is encoded</em>
+<a class="jxr_linenumber" name="L6663" href="#L6663">6663</a>
+<a class="jxr_linenumber" name="L6664" href="#L6664">6664</a> <em class="jxr_comment">// Test</em>
+<a class="jxr_linenumber" name="L6665" href="#L6665">6665</a> <strong class="jxr_keyword">var</strong> result2 = urlEncode(<span class="jxr_string">"café"</span>);
+<a class="jxr_linenumber" name="L6666" href="#L6666">6666</a> assertNotNull(result2);
+<a class="jxr_linenumber" name="L6667" href="#L6667">6667</a> assertTrue(result2.contains(<span class="jxr_string">"%"</span>)); <em class="jxr_comment">// Contains encoded characters</em>
+<a class="jxr_linenumber" name="L6668" href="#L6668">6668</a>
+<a class="jxr_linenumber" name="L6669" href="#L6669">6669</a> <strong class="jxr_keyword">var</strong> result3 = urlEncode(<span class="jxr_string">"测试"</span>);
+<a class="jxr_linenumber" name="L6670" href="#L6670">6670</a> assertNotNull(result3);
+<a class="jxr_linenumber" name="L6671" href="#L6671">6671</a> assertTrue(result3.contains(<span class="jxr_string">"%"</span>)); <em class="jxr_comment">// Contains UTF-8 encoded characters</em>
+<a class="jxr_linenumber" name="L6672" href="#L6672">6672</a> }
+<a class="jxr_linenumber" name="L6673" href="#L6673">6673</a>
+<a class="jxr_linenumber" name="L6674" href="#L6674">6674</a> <em class="jxr_comment">//====================================================================================================</em>
+<a class="jxr_linenumber" name="L6675" href="#L6675">6675</a> <em class="jxr_comment">// urlEncodeLax(String)</em>
+<a class="jxr_linenumber" name="L6676" href="#L6676">6676</a> <em class="jxr_comment">//====================================================================================================</em>
+<a class="jxr_linenumber" name="L6677" href="#L6677">6677</a> @Test
+<a class="jxr_linenumber" name="L6678" href="#L6678">6678</a> <strong class="jxr_keyword">void</strong> a229_urlEncodeLax() {
+<a class="jxr_linenumber" name="L6679" href="#L6679">6679</a> assertNull(urlEncodeLax(<strong class="jxr_keyword">null</strong>));
+<a class="jxr_linenumber" name="L6680" href="#L6680">6680</a> assertEquals(<span class="jxr_string">""</span>, urlEncodeLax(<span class="jxr_string">""</span>));
+<a class="jxr_linenumber" name="L6681" href="#L6681">6681</a> <em class="jxr_comment">// Lax encoding - fewer characters are encoded</em>
+<a class="jxr_linenumber" name="L6682" href="#L6682">6682</a> assertEquals(<span class="jxr_string">"Hello+World"</span>, urlEncodeLax(<span class="jxr_string">"Hello World"</span>));
+<a class="jxr_linenumber" name="L6683" href="#L6683">6683</a> <em class="jxr_comment">// @ might not be encoded in lax mode</em>
+<a class="jxr_linenumber" name="L6684" href="#L6684">6684</a> <strong class="jxr_keyword">var</strong> result1 = urlEncodeLax(<span class="jxr_string">"test@example.com"</span>);
+<a class="jxr_linenumber" name="L6685" href="#L6685">6685</a> assertNotNull(result1);
+<a class="jxr_linenumber" name="L6686" href="#L6686">6686</a> <em class="jxr_comment">// No encoding needed - returns as-is</em>
+<a class="jxr_linenumber" name="L6687" href="#L6687">6687</a> assertEquals(<span class="jxr_string">"Hello"</span>, urlEncodeLax(<span class="jxr_string">"Hello"</span>));
+<a class="jxr_linenumber" name="L6688" href="#L6688">6688</a> assertEquals(<span class="jxr_string">"test123"</span>, urlEncodeLax(<span class="jxr_string">"test123"</span>));
+<a class="jxr_linenumber" name="L6689" href="#L6689">6689</a>
+<a class="jxr_linenumber" name="L6690" href="#L6690">6690</a> <em class="jxr_comment">// Test that need encoding</em>
+<a class="jxr_linenumber" name="L6691" href="#L6691">6691</a> <em class="jxr_comment">// Characters not in URL_UNENCODED_LAX_CHARS and not space</em>
+<a class="jxr_linenumber" name="L6692" href="#L6692">6692</a> <strong class="jxr_keyword">var</strong> result2 = urlEncodeLax(<span class="jxr_string">"test#value"</span>);
+<a class="jxr_linenumber" name="L6693" href="#L6693">6693</a> assertNotNull(result2);
+<a class="jxr_linenumber" name="L6694" href="#L6694">6694</a> assertTrue(result2.contains(<span class="jxr_string">"%23"</span>)); <em class="jxr_comment">// # is encoded as %23</em>
+<a class="jxr_linenumber" name="L6695" href="#L6695">6695</a> <strong class="jxr_keyword">var</strong> result3 = urlEncodeLax(<span class="jxr_string">"test%value"</span>);
+<a class="jxr_linenumber" name="L6696" href="#L6696">6696</a> assertNotNull(result3);
+<a class="jxr_linenumber" name="L6697" href="#L6697">6697</a> assertTrue(result3.contains(<span class="jxr_string">"%25"</span>)); <em class="jxr_comment">// % is encoded as %25</em>
+<a class="jxr_linenumber" name="L6698" href="#L6698">6698</a> <strong class="jxr_keyword">var</strong> result4 = urlEncodeLax(<span class="jxr_string">"test&value"</span>);
+<a class="jxr_linenumber" name="L6699" href="#L6699">6699</a> assertNotNull(result4);
+<a class="jxr_linenumber" name="L6700" href="#L6700">6700</a> assertTrue(result4.contains(<span class="jxr_string">"%26"</span>)); <em class="jxr_comment">// & is encoded as %26</em>
+<a class="jxr_linenumber" name="L6701" href="#L6701">6701</a>
+<a class="jxr_linenumber" name="L6702" href="#L6702">6702</a> <em class="jxr_comment">// Test that need encoding</em>
+<a class="jxr_linenumber" name="L6703" href="#L6703">6703</a> <em class="jxr_comment">// Unicode characters are encoded using URLEncoder.encode</em>
+<a class="jxr_linenumber" name="L6704" href="#L6704">6704</a> <strong class="jxr_keyword">var</strong> result5 = urlEncodeLax(<span class="jxr_string">"testévalue"</span>);
+<a class="jxr_linenumber" name="L6705" href="#L6705">6705</a> assertNotNull(result5);
+<a class="jxr_linenumber" name="L6706" href="#L6706">6706</a> assertTrue(result5.contains(<span class="jxr_string">"%"</span>)); <em class="jxr_comment">// é should be encoded</em>
+<a class="jxr_linenumber" name="L6707" href="#L6707">6707</a> <strong class="jxr_keyword">var</strong> result6 = urlEncodeLax(<span class="jxr_string">"test中文"</span>);
+<a class="jxr_linenumber" name="L6708" href="#L6708">6708</a> assertNotNull(result6);
+<a class="jxr_linenumber" name="L6709" href="#L6709">6709</a> assertTrue(result6.contains(<span class="jxr_string">"%"</span>)); <em class="jxr_comment">// Chinese characters should be encoded</em>
+<a class="jxr_linenumber" name="L6710" href="#L6710">6710</a> <strong class="jxr_keyword">var</strong> result7 = urlEncodeLax(<span class="jxr_string">"test🎉"</span>);
+<a class="jxr_linenumber" name="L6711" href="#L6711">6711</a> assertNotNull(result7);
+<a class="jxr_linenumber" name="L6712" href="#L6712">6712</a> assertTrue(result7.contains(<span class="jxr_string">"%"</span>)); <em class="jxr_comment">// Emoji should be encoded</em>
+<a class="jxr_linenumber" name="L6713" href="#L6713">6713</a> }
+<a class="jxr_linenumber" name="L6714" href="#L6714">6714</a>
+<a class="jxr_linenumber" name="L6715" href="#L6715">6715</a> <em class="jxr_comment">//====================================================================================================</em>
+<a class="jxr_linenumber" name="L6716" href="#L6716">6716</a> <em class="jxr_comment">// urlEncodePath(Object)</em>
+<a class="jxr_linenumber" name="L6717" href="#L6717">6717</a> <em class="jxr_comment">//====================================================================================================</em>
+<a class="jxr_linenumber" name="L6718" href="#L6718">6718</a> @Test
+<a class="jxr_linenumber" name="L6719" href="#L6719">6719</a> <strong class="jxr_keyword">void</strong> a230_urlEncodePath() {
+<a class="jxr_linenumber" name="L6720" href="#L6720">6720</a> <em class="jxr_comment">// Null input</em>
+<a class="jxr_linenumber" name="L6721" href="#L6721">6721</a> assertNull(urlEncodePath(<strong class="jxr_keyword">null</strong>));
+<a class="jxr_linenumber" name="L6722" href="#L6722">6722</a>
+<a class="jxr_linenumber" name="L6723" href="#L6723">6723</a> <em class="jxr_comment">// Path encoding - doesn't encode slashes</em>
+<a class="jxr_linenumber" name="L6724" href="#L6724">6724</a> <strong class="jxr_keyword">var</strong> result1 = urlEncodePath(<span class="jxr_string">"/path/to/file"</span>);
+<a class="jxr_linenumber" name="L6725" href="#L6725">6725</a> assertNotNull(result1);
+<a class="jxr_linenumber" name="L6726" href="#L6726">6726</a> assertTrue(result1.contains(<span class="jxr_string">"/"</span>));
+<a class="jxr_linenumber" name="L6727" href="#L6727">6727</a>
+<a class="jxr_linenumber" name="L6728" href="#L6728">6728</a> <em class="jxr_comment">// Spaces are encoded</em>
+<a class="jxr_linenumber" name="L6729" href="#L6729">6729</a> <strong class="jxr_keyword">var</strong> result2 = urlEncodePath(<span class="jxr_string">"path with spaces"</span>);
+<a class="jxr_linenumber" name="L6730" href="#L6730">6730</a> assertNotNull(result2);
+<a class="jxr_linenumber" name="L6731" href="#L6731">6731</a> assertTrue(result2.contains(<span class="jxr_string">"+"</span>) || result2.contains(<span class="jxr_string">"%20"</span>));
+<a class="jxr_linenumber" name="L6732" href="#L6732">6732</a>
+<a class="jxr_linenumber" name="L6733" href="#L6733">6733</a> <em class="jxr_comment">// Special characters are encoded</em>
+<a class="jxr_linenumber" name="L6734" href="#L6734">6734</a> <strong class="jxr_keyword">var</strong> result3 = urlEncodePath(<span class="jxr_string">"file@name"</span>);
+<a class="jxr_linenumber" name="L6735" href="#L6735">6735</a> assertNotNull(result3);
+<a class="jxr_linenumber" name="L6736" href="#L6736">6736</a>
+<a class="jxr_linenumber" name="L6737" href="#L6737">6737</a> <em class="jxr_comment">// Test code path</em>
+<a class="jxr_linenumber" name="L6738" href="#L6738">6738</a> <strong class="jxr_keyword">var</strong> result4 = urlEncodePath(<span class="jxr_string">"simplepath"</span>);
+<a class="jxr_linenumber" name="L6739" href="#L6739">6739</a> assertEquals(<span class="jxr_string">"simplepath"</span>, result4); <em class="jxr_comment">// No encoding needed, returns as-is</em>
+<a class="jxr_linenumber" name="L6740" href="#L6740">6740</a>
+<a class="jxr_linenumber" name="L6741" href="#L6741">6741</a> <em class="jxr_comment">// Test</em>
+<a class="jxr_linenumber" name="L6742" href="#L6742">6742</a> <em class="jxr_comment">// The surrogate pair handling code is executed when encoding characters that contain surrogate pairs</em>
+<a class="jxr_linenumber" name="L6743" href="#L6743">6743</a> <em class="jxr_comment">// Use a string that contains a character needing encoding along with surrogate pairs</em>
+<a class="jxr_linenumber" name="L6744" href="#L6744">6744</a> <em class="jxr_comment">// to ensure the encoding path is taken and surrogate pair handling is executed</em>
+<a class="jxr_linenumber" name="L6745" href="#L6745">6745</a> <strong class="jxr_keyword">var</strong> emoji = <span class="jxr_string">"🎉"</span>; <em class="jxr_comment">// This contains surrogate pairs</em>
+<a class="jxr_linenumber" name="L6746" href="#L6746">6746</a> <strong class="jxr_keyword">var</strong> result5 = urlEncodePath(emoji);
+<a class="jxr_linenumber" name="L6747" href="#L6747">6747</a> assertNotNull(result5);
+<a class="jxr_linenumber" name="L6748" href="#L6748">6748</a> <em class="jxr_comment">// The surrogate pair code is executed during encoding</em>
+<a class="jxr_linenumber" name="L6749" href="#L6749">6749</a> <em class="jxr_comment">// Check that the result is different from input (encoding occurred) or contains encoded characters</em>
+<a class="jxr_linenumber" name="L6750" href="#L6750">6750</a> assertTrue(result5.length() > 0);
+<a class="jxr_linenumber" name="L6751" href="#L6751">6751</a> <em class="jxr_comment">// Also test with a string that combines regular characters with surrogate pairs</em>
+<a class="jxr_linenumber" name="L6752" href="#L6752">6752</a> <strong class="jxr_keyword">var</strong> result5b = urlEncodePath(<span class="jxr_string">"test🎉file"</span>);
+<a class="jxr_linenumber" name="L6753" href="#L6753">6753</a> assertNotNull(result5b);
+<a class="jxr_linenumber" name="L6754" href="#L6754">6754</a> assertTrue(result5b.length() > 0);
+<a class="jxr_linenumber" name="L6755" href="#L6755">6755</a>
+<a class="jxr_linenumber" name="L6756" href="#L6756">6756</a> <em class="jxr_comment">// Test - uppercase hex digits (caseDiff applied)</em>
+<a class="jxr_linenumber" name="L6757" href="#L6757">6757</a> <em class="jxr_comment">// forDigit returns lowercase 'a'-'f' for hex digits 10-15, which need to be converted to uppercase</em>
+<a class="jxr_linenumber" name="L6758" href="#L6758">6758</a> <em class="jxr_comment">// We need characters that produce bytes with hex values containing a-f</em>
+<a class="jxr_linenumber" name="L6759" href="#L6759">6759</a> <em class="jxr_comment">// For example, byte 0x0A produces hex "a", byte 0x0B produces "b", etc.</em>
+<a class="jxr_linenumber" name="L6760" href="#L6760">6760</a> <em class="jxr_comment">// Use characters that when UTF-8 encoded produce bytes with values 0x0A-0x0F</em>
+<a class="jxr_linenumber" name="L6761" href="#L6761">6761</a> <em class="jxr_comment">// Actually, any non-ASCII character will produce multi-byte UTF-8 encoding</em>
+<a class="jxr_linenumber" name="L6762" href="#L6762">6762</a> <em class="jxr_comment">// Let's use a character that produces bytes with hex digits a-f</em>
+<a class="jxr_linenumber" name="L6763" href="#L6763">6763</a> <strong class="jxr_keyword">var</strong> result6 = urlEncodePath(<span class="jxr_string">"test@file"</span>);
+<a class="jxr_linenumber" name="L6764" href="#L6764">6764</a> assertNotNull(result6);
+<a class="jxr_linenumber" name="L6765" href="#L6765">6765</a> <em class="jxr_comment">// Check that hex digits are uppercase (A-F, not a-f)</em>
+<a class="jxr_linenumber" name="L6766" href="#L6766">6766</a> <em class="jxr_comment">// The encoding should contain %40 for @</em>
+<a class="jxr_linenumber" name="L6767" href="#L6767">6767</a> assertTrue(result6.contains(<span class="jxr_string">"%40"</span>) || result6.contains(<span class="jxr_string">"%"</span>));
+<a class="jxr_linenumber" name="L6768" href="#L6768">6768</a> <em class="jxr_comment">// Verify all hex sequences are uppercase</em>
+<a class="jxr_linenumber" name="L6769" href="#L6769">6769</a> <strong class="jxr_keyword">var</strong> hexPattern = java.util.regex.Pattern.compile(<span class="jxr_string">"%([0-9A-Fa-f]{2})"</span>);
+<a class="jxr_linenumber" name="L6770" href="#L6770">6770</a> <strong class="jxr_keyword">var</strong> matcher = hexPattern.matcher(result6);
+<a class="jxr_linenumber" name="L6771" href="#L6771">6771</a> <strong class="jxr_keyword">boolean</strong> foundHex = false;
+<a class="jxr_linenumber" name="L6772" href="#L6772">6772</a> <strong class="jxr_keyword">while</strong> (matcher.find()) {
+<a class="jxr_linenumber" name="L6773" href="#L6773">6773</a> foundHex = <strong class="jxr_keyword">true</strong>;
+<a class="jxr_linenumber" name="L6774" href="#L6774">6774</a> <strong class="jxr_keyword">var</strong> hex = matcher.group(1);
+<a class="jxr_linenumber" name="L6775" href="#L6775">6775</a> <em class="jxr_comment">// Verify it's uppercase (caseDiff converts lowercase to uppercase)</em>
+<a class="jxr_linenumber" name="L6776" href="#L6776">6776</a> assertEquals(hex.toUpperCase(), hex);
+<a class="jxr_linenumber" name="L6777" href="#L6777">6777</a> }
+<a class="jxr_linenumber" name="L6778" href="#L6778">6778</a> <em class="jxr_comment">// Test with a character that produces bytes with hex digits a-f</em>
+<a class="jxr_linenumber" name="L6779" href="#L6779">6779</a> <em class="jxr_comment">// Use a character that when UTF-8 encoded produces bytes with values that result in lowercase hex</em>
+<a class="jxr_linenumber" name="L6780" href="#L6780">6780</a> <em class="jxr_comment">// For example, characters that produce bytes 0x0A-0x0F, 0x1A-0x1F, etc.</em>
+<a class="jxr_linenumber" name="L6781" href="#L6781">6781</a> <em class="jxr_comment">// Chinese character or other multi-byte UTF-8 character should work</em>
+<a class="jxr_linenumber" name="L6782" href="#L6782">6782</a> <strong class="jxr_keyword">var</strong> result7 = urlEncodePath(<span class="jxr_string">"test中文"</span>);
+<a class="jxr_linenumber" name="L6783" href="#L6783">6783</a> assertNotNull(result7);
+<a class="jxr_linenumber" name="L6784" href="#L6784">6784</a> assertTrue(result7.contains(<span class="jxr_string">"%"</span>));
+<a class="jxr_linenumber" name="L6785" href="#L6785">6785</a> <em class="jxr_comment">// Verify hex digits are uppercase</em>
+<a class="jxr_linenumber" name="L6786" href="#L6786">6786</a> <strong class="jxr_keyword">var</strong> matcher2 = hexPattern.matcher(result7);
+<a class="jxr_linenumber" name="L6787" href="#L6787">6787</a> <strong class="jxr_keyword">while</strong> (matcher2.find()) {
+<a class="jxr_linenumber" name="L6788" href="#L6788">6788</a> <strong class="jxr_keyword">var</strong> hex = matcher2.group(1);
+<a class="jxr_linenumber" name="L6789" href="#L6789">6789</a> <em class="jxr_comment">// Verify it's uppercase (code path and 7724 convert lowercase to uppercase)</em>
+<a class="jxr_linenumber" name="L6790" href="#L6790">6790</a> assertEquals(hex.toUpperCase(), hex);
+<a class="jxr_linenumber" name="L6791" href="#L6791">6791</a> }
+<a class="jxr_linenumber" name="L6792" href="#L6792">6792</a> <em class="jxr_comment">// If we found hex sequences, verify they're uppercase</em>
+<a class="jxr_linenumber" name="L6793" href="#L6793">6793</a> <strong class="jxr_keyword">if</strong> (foundHex) {
+<a class="jxr_linenumber" name="L6794" href="#L6794">6794</a> <em class="jxr_comment">// All hex should be uppercase</em>
+<a class="jxr_linenumber" name="L6795" href="#L6795">6795</a> assertTrue(result6.equals(result6.toUpperCase()) || result6.matches(<span class="jxr_string">".*%[0-9A-F]{2}.*"</span>));
+<a class="jxr_linenumber" name="L6796" href="#L6796">6796</a> }
+<a class="jxr_linenumber" name="L6797" href="#L6797">6797</a> }
+<a class="jxr_linenumber" name="L6798" href="#L6798">6798</a>
+<a class="jxr_linenumber" name="L6799" href="#L6799">6799</a> <em class="jxr_comment">//====================================================================================================</em>
+<a class="jxr_linenumber" name="L6800" href="#L6800">6800</a> <em class="jxr_comment">// wordCount(String)</em>
+<a class="jxr_linenumber" name="L6801" href="#L6801">6801</a> <em class="jxr_comment">//====================================================================================================</em>
+<a class="jxr_linenumber" name="L6802" href="#L6802">6802</a> @Test
+<a class="jxr_linenumber" name="L6803" href="#L6803">6803</a> <strong class="jxr_keyword">void</strong> a231_wordCount() {
+<a class="jxr_linenumber" name="L6804" href="#L6804">6804</a> assertEquals(0, wordCount(<strong class="jxr_keyword">null</strong>));
+<a class="jxr_linenumber" name="L6805" href="#L6805">6805</a> assertEquals(0, wordCount(<span class="jxr_string">""</span>));
+<a class="jxr_linenumber" name="L6806" href="#L6806">6806</a> assertEquals(0, wordCount(<span class="jxr_string">" "</span>));
+<a class="jxr_linenumber" name="L6807" href="#L6807">6807</a> assertEquals(1, wordCount(<span class="jxr_string">"hello"</span>));
+<a class="jxr_linenumber" name="L6808" href="#L6808">6808</a> assertEquals(2, wordCount(<span class="jxr_string">"Hello world"</span>));
+<a class="jxr_linenumber" name="L6809" href="#L6809">6809</a> assertEquals(4, wordCount(<span class="jxr_string">"The quick brown fox"</span>));
+<a class="jxr_linenumber" name="L6810" href="#L6810">6810</a> assertEquals(5, wordCount(<span class="jxr_string">"Hello, world! How are you?"</span>));
+<a class="jxr_linenumber" name="L6811" href="#L6811">6811</a> assertEquals(3, wordCount(<span class="jxr_string">"one\ttwo\nthree"</span>));
+<a class="jxr_linenumber" name="L6812" href="#L6812">6812</a> assertEquals(1, wordCount(<span class="jxr_string">"hello123"</span>));
+<a class="jxr_linenumber" name="L6813" href="#L6813">6813</a> <em class="jxr_comment">// Underscores are part of word characters, so "hello_world" is one word</em>
+<a class="jxr_linenumber" name="L6814" href="#L6814">6814</a> assertEquals(1, wordCount(<span class="jxr_string">"hello_world"</span>));
+<a class="jxr_linenumber" name="L6815" href="#L6815">6815</a> assertEquals(2, wordCount(<span class="jxr_string">"hello world"</span>));
+<a class="jxr_linenumber" name="L6816" href="#L6816">6816</a> }
+<a class="jxr_linenumber" name="L6817" href="#L6817">6817</a>
+<a class="jxr_linenumber" name="L6818" href="#L6818">6818</a> <em class="jxr_comment">//====================================================================================================</em>
+<a class="jxr_linenumber" name="L6819" href="#L6819">6819</a> <em class="jxr_comment">// wrap(String,int) and wrap(String,int,String)</em>
+<a class="jxr_linenumber" name="L6820" href="#L6820">6820</a> <em class="jxr_comment">//====================================================================================================</em>
+<a class="jxr_linenumber" name="L6821" href="#L6821">6821</a> @Test
+<a class="jxr_linenumber" name="L6822" href="#L6822">6822</a> <strong class="jxr_keyword">void</strong> a232_wrap() {
+<a class="jxr_linenumber" name="L6823" href="#L6823">6823</a> <em class="jxr_comment">// wrap(String,int) - uses default newline "\n"</em>
+<a class="jxr_linenumber" name="L6824" href="#L6824">6824</a> assertNull(wrap(<strong class="jxr_keyword">null</strong>, 10));
+<a class="jxr_linenumber" name="L6825" href="#L6825">6825</a> assertEquals(<span class="jxr_string">""</span>, wrap(<span class="jxr_string">""</span>, 10));
+<a class="jxr_linenumber" name="L6826" href="#L6826">6826</a> assertEquals(<span class="jxr_string">"hello\nworld"</span>, wrap(<span class="jxr_string">"hello world"</span>, 10));
+<a class="jxr_linenumber" name="L6827" href="#L6827">6827</a> assertEquals(<span class="jxr_string">"hello\nworld\ntest"</span>, wrap(<span class="jxr_string">"hello world test"</span>, 10));
+<a class="jxr_linenumber" name="L6828" href="#L6828">6828</a> assertEquals(<span class="jxr_string">"hello world"</span>, wrap(<span class="jxr_string">"hello world"</span>, 20));
+<a class="jxr_linenumber" name="L6829" href="#L6829">6829</a> assertEquals(<span class="jxr_string">"hello\nworld"</span>, wrap(<span class="jxr_string">"hello world"</span>, 5));
+<a class="jxr_linenumber" name="L6830" href="#L6830">6830</a> assertEquals(<span class="jxr_string">"supercalifragilisticexpialidocious"</span>, wrap(<span class="jxr_string">"supercalifragilisticexpialidocious"</span>, 10));
+<a class="jxr_linenumber" name="L6831" href="#L6831">6831</a> assertEquals(<span class="jxr_string">"hello\nworld"</span>, wrap(<span class="jxr_string">"hello world"</span>, 10));
+<a class="jxr_linenumber" name="L6832" href="#L6832">6832</a> assertEquals(<span class="jxr_string">"line1\nline2"</span>, wrap(<span class="jxr_string">"line1\nline2"</span>, 10));
+<a class="jxr_linenumber" name="L6833" href="#L6833">6833</a> assertEquals(<span class="jxr_string">"a\nb\nc"</span>, wrap(<span class="jxr_string">"a b c"</span>, 1));
+<a class="jxr_linenumber" name="L6834" href="#L6834">6834</a> assertThrows(IllegalArgumentException.<strong class="jxr_keyword">class</strong>, () -> wrap(<span class="jxr_string">"test"</span>, 0));
+<a class="jxr_linenumber" name="L6835" href="#L6835">6835</a> assertThrows(IllegalArgumentException.<strong class="jxr_keyword">class</strong>, () -> wrap(<span class="jxr_string">"test"</span>, -1));
+<a class="jxr_linenumber" name="L6836" href="#L6836">6836</a>
+<a class="jxr_linenumber" name="L6837" href="#L6837">6837</a> <em class="jxr_comment">// wrap(String,int,String) - with custom newline</em>
+<a class="jxr_linenumber" name="L6838" href="#L6838">6838</a> assertNull(wrap(<strong class="jxr_keyword">null</strong>, 10, <span class="jxr_string">"<br>"</span>));
+<a class="jxr_linenumber" name="L6839" href="#L6839">6839</a> assertEquals(<span class="jxr_string">""</span>, wrap(<span class="jxr_string">""</span>, 10, <span class="jxr_string">"<br>"</span>));
+<a class="jxr_linenumber" name="L6840" href="#L6840">6840</a> assertEquals(<span class="jxr_string">"hello<br>world"</span>, wrap(<span class="jxr_string">"hello world"</span>, 10, <span class="jxr_string">"<br>"</span>));
+<a class="jxr_linenumber" name="L6841" href="#L6841">6841</a> assertEquals(<span class="jxr_string">"hello<br>world<br>test"</span>, wrap(<span class="jxr_string">"hello world test"</span>, 10, <span class="jxr_string">"<br>"</span>));
+<a class="jxr_linenumber" name="L6842" href="#L6842">6842</a> assertEquals(<span class="jxr_string">"hello world"</span>, wrap(<span class="jxr_string">"hello world"</span>, 20, <span class="jxr_string">"<br>"</span>));
+<a class="jxr_linenumber" name="L6843" href="#L6843">6843</a> assertEquals(<span class="jxr_string">"hello<br>world"</span>, wrap(<span class="jxr_string">"hello world"</span>, 5, <span class="jxr_string">"<br>"</span>));
+<a class="jxr_linenumber" name="L6844" href="#L6844">6844</a> assertEquals(<span class="jxr_string">"supercalifragilisticexpialidocious"</span>, wrap(<span class="jxr_string">"supercalifragilisticexpialidocious"</span>, 10, <span class="jxr_string">"<br>"</span>));
+<a class="jxr_linenumber" name="L6845" href="#L6845">6845</a> assertEquals(<span class="jxr_string">"line1<br>line2"</span>, wrap(<span class="jxr_string">"line1\nline2"</span>, 10, <span class="jxr_string">"<br>"</span>));
+<a class="jxr_linenumber" name="L6846" href="#L6846">6846</a> assertEquals(<span class="jxr_string">"a<br>b<br>c"</span>, wrap(<span class="jxr_string">"a b c"</span>, 1, <span class="jxr_string">"<br>"</span>));
+<a class="jxr_linenumber" name="L6847" href="#L6847">6847</a> assertThrows(IllegalArgumentException.<strong class="jxr_keyword">class</strong>, () -> wrap(<span class="jxr_string">"test"</span>, 0, <span class="jxr_string">"\n"</span>));
+<a class="jxr_linenumber" name="L6848" href="#L6848">6848</a> assertThrows(IllegalArgumentException.<strong class="jxr_keyword">class</strong>, () -> wrap(<span class="jxr_string">"test"</span>, -1, <span class="jxr_string">"\n"</span>));
+<a class="jxr_linenumber" name="L6849" href="#L6849">6849</a> assertThrows(IllegalArgumentException.<strong class="jxr_keyword">class</strong>, () -> wrap(<span class="jxr_string">"test"</span>, 10, <strong class="jxr_keyword">null</strong>));
+<a class="jxr_linenumber" name="L6850" href="#L6850">6850</a>
+<a class="jxr_linenumber" name="L6851" href="#L6851">6851</a> <em class="jxr_comment">// Test</em>
+<a class="jxr_linenumber" name="L6852" href="#L6852">6852</a> <strong class="jxr_keyword">var</strong> result1 = wrap(<span class="jxr_string">"line1\n\nline2"</span>, 10, <span class="jxr_string">"\n"</span>);
+<a class="jxr_linenumber" name="L6853" href="#L6853">6853</a> assertTrue(result1.contains(<span class="jxr_string">"\n\n"</span>)); <em class="jxr_comment">// Empty line preserved</em>
+<a class="jxr_linenumber" name="L6854" href="#L6854">6854</a>
+<a class="jxr_linenumber" name="L6855" href="#L6855">6855</a> <em class="jxr_comment">// Test)</em>
+<a class="jxr_linenumber" name="L6856" href="#L6856">6856</a> <em class="jxr_comment">// Multiple spaces create empty words that should be skipped</em>
+<a class="jxr_linenumber" name="L6857" href="#L6857">6857</a> <strong class="jxr_keyword">var</strong> result2 = wrap(<span class="jxr_string">"word1 word2"</span>, 10, <span class="jxr_string">"\n"</span>);
+<a class="jxr_linenumber" name="L6858" href="#L6858">6858</a> assertTrue(result2.contains(<span class="jxr_string">"word1"</span>));
+<a class="jxr_linenumber" name="L6859" href="#L6859">6859</a> assertTrue(result2.contains(<span class="jxr_string">"word2"</span>));
+<a class="jxr_linenumber" name="L6860" href="#L6860">6860</a> <em class="jxr_comment">// Test with multiple consecutive spaces</em>
+<a class="jxr_linenumber" name="L6861" href="#L6861">6861</a> <strong class="jxr_keyword">var</strong> result2b = wrap(<span class="jxr_string">"a b c"</span>, 10, <span class="jxr_string">"\n"</span>);
+<a class="jxr_linenumber" name="L6862" href="#L6862">6862</a> assertTrue(result2b.contains(<span class="jxr_string">"a"</span>));
+<a class="jxr_linenumber" name="L6863" href="#L6863">6863</a> assertTrue(result2b.contains(<span class="jxr_string">"b"</span>));
+<a class="jxr_linenumber" name="L6864" href="#L6864">6864</a> assertTrue(result2b.contains(<span class="jxr_string">"c"</span>));
+<a class="jxr_linenumber" name="L6865" href="#L6865">6865</a> <em class="jxr_comment">// Test with leading spaces - split(" +") creates empty string at start</em>
+<a class="jxr_linenumber" name="L6866" href="#L6866">6866</a> <strong class="jxr_keyword">var</strong> result2c = wrap(<span class="jxr_string">" hello world"</span>, 10, <span class="jxr_string">"\n"</span>);
+<a class="jxr_linenumber" name="L6867" href="#L6867">6867</a> assertTrue(result2c.contains(<span class="jxr_string">"hello"</span>));
+<a class="jxr_linenumber" name="L6868" href="#L6868">6868</a> assertTrue(result2c.contains(<span class="jxr_string">"world"</span>));
+<a class="jxr_linenumber" name="L6869" href="#L6869">6869</a> <em class="jxr_comment">// Test with trailing spaces - split(" +") creates empty string at end</em>
+<a class="jxr_linenumber" name="L6870" href="#L6870">6870</a> <strong class="jxr_keyword">var</strong> result2d = wrap(<span class="jxr_string">"hello world "</span>, 10, <span class="jxr_string">"\n"</span>);
+<a class="jxr_linenumber" name="L6871" href="#L6871">6871</a> assertTrue(result2d.contains(<span class="jxr_string">"hello"</span>));
+<a class="jxr_linenumber" name="L6872" href="#L6872">6872</a> assertTrue(result2d.contains(<span class="jxr_string">"world"</span>));
+<a class="jxr_linenumber" name="L6873" href="#L6873">6873</a> <em class="jxr_comment">// Test with both leading and trailing spaces</em>
+<a class="jxr_linenumber" name="L6874" href="#L6874">6874</a> <strong class="jxr_keyword">var</strong> result2e = wrap(<span class="jxr_string">" hello world "</span>, 10, <span class="jxr_string">"\n"</span>);
+<a class="jxr_linenumber" name="L6875" href="#L6875">6875</a> assertTrue(result2e.contains(<span class="jxr_string">"hello"</span>));
+<a class="jxr_linenumber" name="L6876" href="#L6876">6876</a> assertTrue(result2e.contains(<span class="jxr_string">"world"</span>));
+<a class="jxr_linenumber" name="L6877" href="#L6877">6877</a>
+<a class="jxr_linenumber" name="L6878" href="#L6878">6878</a> <em class="jxr_comment">// Test</em>
+<a class="jxr_linenumber" name="L6879" href="#L6879">6879</a> <em class="jxr_comment">// This tests breaking a long word when it's the first word on a line</em>
+<a class="jxr_linenumber" name="L6880" href="#L6880">6880</a> <em class="jxr_comment">// Code path: result.length() > 0 (result already has content)</em>
+<a class="jxr_linenumber" name="L6881" href="#L6881">6881</a> <em class="jxr_comment">// Code path: while loop that breaks word into chunks</em>
+<a class="jxr_linenumber" name="L6882" href="#L6882">6882</a> <em class="jxr_comment">// Code path: wordPos > 0 (not first iteration)</em>
+<a class="jxr_linenumber" name="L6883" href="#L6883">6883</a> <em class="jxr_comment">// Code path: remaining <= wrapLength (remaining fits)</em>
+<a class="jxr_linenumber" name="L6884" href="#L6884">6884</a> <em class="jxr_comment">// Code path: append remaining</em>
+<a class="jxr_linenumber" name="L6885" href="#L6885">6885</a> <em class="jxr_comment">// Code path: break</em>
+<a class="jxr_linenumber" name="L6886" href="#L6886">6886</a> <em class="jxr_comment">// Code path: append chunk</em>
+<a class="jxr_linenumber" name="L6887" href="#L6887">6887</a> <em class="jxr_comment">// Code path: advance position</em>
+<a class="jxr_linenumber" name="L6888" href="#L6888">6888</a> <strong class="jxr_keyword">var</strong> result3 = wrap(<span class="jxr_string">"short verylongword here"</span>, 5, <span class="jxr_string">"\n"</span>);
+<a class="jxr_linenumber" name="L6889" href="#L6889">6889</a> assertFalse(result3.contains(<span class="jxr_string">"verylongword"</span>)); <em class="jxr_comment">// Word should be split into chunks</em>
+<a class="jxr_linenumber" name="L6890" href="#L6890">6890</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> line : result3.split(<span class="jxr_string">"\n"</span>)) {
+<a class="jxr_linenumber" name="L6891" href="#L6891">6891</a> <strong class="jxr_keyword">if</strong> (! line.isEmpty())
+<a class="jxr_linenumber" name="L6892" href="#L6892">6892</a> assertTrue(line.length() <= 5);
+<a class="jxr_linenumber" name="L6893" href="#L6893">6893</a> }
+<a class="jxr_linenumber" name="L6894" href="#L6894">6894</a> <em class="jxr_comment">// Test with result already having content > 0)</em>
+<a class="jxr_linenumber" name="L6895" href="#L6895">6895</a> <em class="jxr_comment">// After a previous line, a long word that needs breaking as first word on new line</em>
+<a class="jxr_linenumber" name="L6896" href="#L6896">6896</a> <em class="jxr_comment">// This happens when a previous line was completed and we start a new line</em>
+<a class="jxr_linenumber" name="L6897" href="#L6897">6897</a> <strong class="jxr_keyword">var</strong> result3b = wrap(<span class="jxr_string">"first\nverylongword here"</span>, 5, <span class="jxr_string">"\n"</span>);
+<a class="jxr_linenumber" name="L6898" href="#L6898">6898</a> <em class="jxr_comment">// After "first\n", "verylongword" is the first word on the new line and needs breaking</em>
+<a class="jxr_linenumber" name="L6899" href="#L6899">6899</a> assertTrue(result3b.contains(<span class="jxr_string">"first"</span>));
+<a class="jxr_linenumber" name="L6900" href="#L6900">6900</a> assertFalse(result3b.contains(<span class="jxr_string">"verylongword"</span>)); <em class="jxr_comment">// Long word should be broken</em>
+<a class="jxr_linenumber" name="L6901" href="#L6901">6901</a> <em class="jxr_comment">// Test word that breaks into multiple chunks (covers code path)</em>
+<a class="jxr_linenumber" name="L6902" href="#L6902">6902</a> <em class="jxr_comment">// Word length 15, wrapLength 5 -> 3 chunks of 5, 5, 5</em>
+<a class="jxr_linenumber" name="L6903" href="#L6903">6903</a> <em class="jxr_comment">// This tests: wordPos > 0 , append chunk , advance position </em>
+<a class="jxr_linenumber" name="L6904" href="#L6904">6904</a> <em class="jxr_comment">// And: remaining <= wrapLength , append remaining , break </em>
+<a class="jxr_linenumber" name="L6905" href="#L6905">6905</a> <strong class="jxr_keyword">var</strong> result3c = wrap(<span class="jxr_string">"abcdefghijklmno here"</span>, 5, <span class="jxr_string">"\n"</span>);
+<a class="jxr_linenumber" name="L6906" href="#L6906">6906</a> assertTrue(result3c.contains(<span class="jxr_string">"abcde"</span>)); <em class="jxr_comment">// First chunk (wordPos == 0, no newline before)</em>
+<a class="jxr_linenumber" name="L6907" href="#L6907">6907</a> assertTrue(result3c.contains(<span class="jxr_string">"fghij"</span>)); <em class="jxr_comment">// Second chunk (wordPos > 0, newline before, code path)</em>
+<a class="jxr_linenumber" name="L6908" href="#L6908">6908</a> assertTrue(result3c.contains(<span class="jxr_string">"klmno"</span>)); <em class="jxr_comment">// Third chunk (remaining <= wrapLength, code path)</em>
+<a class="jxr_linenumber" name="L6909" href="#L6909">6909</a>
+<a class="jxr_linenumber" name="L6910" href="#L6910">6910</a> <em class="jxr_comment">// Test</em>
+<a class="jxr_linenumber" name="L6911" href="#L6911">6911</a> <strong class="jxr_keyword">var</strong> result4 = wrap(<span class="jxr_string">"short word verylongword here"</span>, 10, <span class="jxr_string">"\n"</span>);
+<a class="jxr_linenumber" name="L6912" href="#L6912">6912</a> assertFalse(result4.contains(<span class="jxr_string">"verylongword"</span>)); <em class="jxr_comment">// Word should be split into chunks</em>
+<a class="jxr_linenumber" name="L6913" href="#L6913">6913</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> line : result4.split(<span class="jxr_string">"\n"</span>)) {
+<a class="jxr_linenumber" name="L6914" href="#L6914">6914</a> <strong class="jxr_keyword">if</strong> (! line.isEmpty())
+<a class="jxr_linenumber" name="L6915" href="#L6915">6915</a> assertTrue(line.length() <= 10);
+<a class="jxr_linenumber" name="L6916" href="#L6916">6916</a> }
+<a class="jxr_linenumber" name="L6917" href="#L6917">6917</a>
+<a class="jxr_linenumber" name="L6918" href="#L6918">6918</a> <em class="jxr_comment">// Test > 0)</em>
+<a class="jxr_linenumber" name="L6919" href="#L6919">6919</a> <strong class="jxr_keyword">var</strong> result5 = wrap(<span class="jxr_string">"short word"</span>, 20, <span class="jxr_string">"\n"</span>);
+<a class="jxr_linenumber" name="L6920" href="#L6920">6920</a> assertEquals(<span class="jxr_string">"short word"</span>, result5); <em class="jxr_comment">// Remaining line appended</em>
+<a class="jxr_linenumber" name="L6921" href="#L6921">6921</a> }
+<a class="jxr_linenumber" name="L6922" href="#L6922">6922</a> }
</pre>
<hr/>
<div id="footer">© 2016–2025 <a href="https://www.apache.org/">The Apache Software Foundation</a></div>
diff --git a/site/xref/org/apache/juneau/commons/utils/StringUtils.html b/site/xref/org/apache/juneau/commons/utils/StringUtils.html
index c3dcc18c98..c4ea2087bd 100644
--- a/site/xref/org/apache/juneau/commons/utils/StringUtils.html
+++ b/site/xref/org/apache/juneau/commons/utils/StringUtils.html
@@ -7466,917 +7466,914 @@
<a class="jxr_linenumber" name="L7458" href="#L7458">7458</a> <strong class="jxr_keyword">var</strong> c2 = s.charAt(i + 1);
<a class="jxr_linenumber" name="L7459" href="#L7459">7459</a> <strong class="jxr_keyword">if</strong> (escaped.contains(c2)) {
<a class="jxr_linenumber" name="L7460" href="#L7460">7460</a> i++; <em class="jxr_comment">// NOSONAR - Intentional.</em>
-<a class="jxr_linenumber" name="L7461" href="#L7461">7461</a> } <strong class="jxr_keyword">else</strong> <strong class="jxr_keyword">if</strong> (c2 == '\\') {
-<a class="jxr_linenumber" name="L7462" href="#L7462">7462</a> sb.append('\\');
-<a class="jxr_linenumber" name="L7463" href="#L7463">7463</a> i++; <em class="jxr_comment">// NOSONAR - Intentional.</em>
-<a class="jxr_linenumber" name="L7464" href="#L7464">7464</a> }
-<a class="jxr_linenumber" name="L7465" href="#L7465">7465</a> }
-<a class="jxr_linenumber" name="L7466" href="#L7466">7466</a> }
-<a class="jxr_linenumber" name="L7467" href="#L7467">7467</a> sb.append(s.charAt(i));
-<a class="jxr_linenumber" name="L7468" href="#L7468">7468</a> }
-<a class="jxr_linenumber" name="L7469" href="#L7469">7469</a> <strong class="jxr_keyword">return</strong> sb.toString();
-<a class="jxr_linenumber" name="L7470" href="#L7470">7470</a> }
-<a class="jxr_linenumber" name="L7471" href="#L7471">7471</a>
-<a class="jxr_linenumber" name="L7472" href="#L7472">7472</a> <em class="jxr_javadoccomment">/**</em>
-<a class="jxr_linenumber" name="L7473" href="#L7473">7473</a> <em class="jxr_javadoccomment"> * Unescapes HTML entities in a string.</em>
-<a class="jxr_linenumber" name="L7474" href="#L7474">7474</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7475" href="#L7475">7475</a> <em class="jxr_javadoccomment"> * <p></em>
-<a class="jxr_linenumber" name="L7476" href="#L7476">7476</a> <em class="jxr_javadoccomment"> * Unescapes the following HTML entities:</em>
-<a class="jxr_linenumber" name="L7477" href="#L7477">7477</a> <em class="jxr_javadoccomment"> * <ul></em>
-<a class="jxr_linenumber" name="L7478" href="#L7478">7478</a> <em class="jxr_javadoccomment"> * <li><js>"&amp;amp;"</js> → <js>'&amp;'</js></li></em>
-<a class="jxr_linenumber" name="L7479" href="#L7479">7479</a> <em class="jxr_javadoccomment"> * <li><js>"&amp;lt;"</js> → <js>'&lt;'</js></li></em>
-<a class="jxr_linenumber" name="L7480" href="#L7480">7480</a> <em class="jxr_javadoccomment"> * <li><js>"&amp;gt;"</js> → <js>'&gt;'</js></li></em>
-<a class="jxr_linenumber" name="L7481" href="#L7481">7481</a> <em class="jxr_javadoccomment"> * <li><js>"&amp;quot;"</js> → <js>'"'</js></li></em>
-<a class="jxr_linenumber" name="L7482" href="#L7482">7482</a> <em class="jxr_javadoccomment"> * <li><js>"&amp;#39;"</js> or <js>"&amp;apos;"</js> → <js>'\''</js></li></em>
-<a class="jxr_linenumber" name="L7483" href="#L7483">7483</a> <em class="jxr_javadoccomment"> * </ul></em>
-<a class="jxr_linenumber" name="L7484" href="#L7484">7484</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7485" href="#L7485">7485</a> <em class="jxr_javadoccomment"> * <h5 class='section'>Example:</h5></em>
-<a class="jxr_linenumber" name="L7486" href="#L7486">7486</a> <em class="jxr_javadoccomment"> * <p class='bjava'></em>
-<a class="jxr_linenumber" name="L7487" href="#L7487">7487</a> <em class="jxr_javadoccomment"> * unescapeHtml(<js>"&amp;lt;script&amp;gt;"</js>); <jc>// Returns: "&lt;script&gt;"</jc></em>
-<a class="jxr_linenumber" name="L7488" href="#L7488">7488</a> <em class="jxr_javadoccomment"> * </p></em>
-<a class="jxr_linenumber" name="L7489" href="#L7489">7489</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7490" href="#L7490">7490</a> <em class="jxr_javadoccomment"> * @param str The string to unescape.</em>
-<a class="jxr_linenumber" name="L7491" href="#L7491">7491</a> <em class="jxr_javadoccomment"> * @return The unescaped string, or <jk>null</jk> if input is <jk>null</jk>.</em>
-<a class="jxr_linenumber" name="L7492" href="#L7492">7492</a> <em class="jxr_javadoccomment"> */</em>
-<a class="jxr_linenumber" name="L7493" href="#L7493">7493</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> String unescapeHtml(String str) {
-<a class="jxr_linenumber" name="L7494" href="#L7494">7494</a> <strong class="jxr_keyword">if</strong> (str == <strong class="jxr_keyword">null</strong>)
-<a class="jxr_linenumber" name="L7495" href="#L7495">7495</a> <strong class="jxr_keyword">return</strong> <strong class="jxr_keyword">null</strong>;
-<a class="jxr_linenumber" name="L7496" href="#L7496">7496</a> <em class="jxr_comment">// Must unescape &amp; last to avoid interfering with other entities</em>
-<a class="jxr_linenumber" name="L7497" href="#L7497">7497</a> <strong class="jxr_keyword">return</strong> str.replace(<span class="jxr_string">"&lt;"</span>, <span class="jxr_string">"<"</span>).replace(<span class="jxr_string">"&gt;"</span>, <span class="jxr_string">">"</span>).replace(<span class="jxr_string">"&quot;"</span>, <span class="jxr_string">"\""</span>).replace(<span class="jxr_string">"&#39;"</span>, <span class="jxr_string">"'"</span>).replace(< [...]
-<a class="jxr_linenumber" name="L7498" href="#L7498">7498</a> }
-<a class="jxr_linenumber" name="L7499" href="#L7499">7499</a>
-<a class="jxr_linenumber" name="L7500" href="#L7500">7500</a> <em class="jxr_javadoccomment">/**</em>
-<a class="jxr_linenumber" name="L7501" href="#L7501">7501</a> <em class="jxr_javadoccomment"> * Unescapes XML entities in a string.</em>
-<a class="jxr_linenumber" name="L7502" href="#L7502">7502</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7503" href="#L7503">7503</a> <em class="jxr_javadoccomment"> * <p></em>
-<a class="jxr_linenumber" name="L7504" href="#L7504">7504</a> <em class="jxr_javadoccomment"> * Unescapes the following XML entities:</em>
-<a class="jxr_linenumber" name="L7505" href="#L7505">7505</a> <em class="jxr_javadoccomment"> * <ul></em>
-<a class="jxr_linenumber" name="L7506" href="#L7506">7506</a> <em class="jxr_javadoccomment"> * <li><js>"&amp;amp;"</js> → <js>'&amp;'</js></li></em>
-<a class="jxr_linenumber" name="L7507" href="#L7507">7507</a> <em class="jxr_javadoccomment"> * <li><js>"&amp;lt;"</js> → <js>'&lt;'</js></li></em>
-<a class="jxr_linenumber" name="L7508" href="#L7508">7508</a> <em class="jxr_javadoccomment"> * <li><js>"&amp;gt;"</js> → <js>'&gt;'</js></li></em>
-<a class="jxr_linenumber" name="L7509" href="#L7509">7509</a> <em class="jxr_javadoccomment"> * <li><js>"&amp;quot;"</js> → <js>'"'</js></li></em>
-<a class="jxr_linenumber" name="L7510" href="#L7510">7510</a> <em class="jxr_javadoccomment"> * <li><js>"&amp;apos;"</js> → <js>'\''</js></li></em>
-<a class="jxr_linenumber" name="L7511" href="#L7511">7511</a> <em class="jxr_javadoccomment"> * </ul></em>
-<a class="jxr_linenumber" name="L7512" href="#L7512">7512</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7513" href="#L7513">7513</a> <em class="jxr_javadoccomment"> * <h5 class='section'>Example:</h5></em>
-<a class="jxr_linenumber" name="L7514" href="#L7514">7514</a> <em class="jxr_javadoccomment"> * <p class='bjava'></em>
-<a class="jxr_linenumber" name="L7515" href="#L7515">7515</a> <em class="jxr_javadoccomment"> * unescapeXml(<js>"&amp;lt;tag&amp;gt;"</js>); <jc>// Returns: "&lt;tag&gt;"</jc></em>
-<a class="jxr_linenumber" name="L7516" href="#L7516">7516</a> <em class="jxr_javadoccomment"> * </p></em>
-<a class="jxr_linenumber" name="L7517" href="#L7517">7517</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7518" href="#L7518">7518</a> <em class="jxr_javadoccomment"> * @param str The string to unescape.</em>
-<a class="jxr_linenumber" name="L7519" href="#L7519">7519</a> <em class="jxr_javadoccomment"> * @return The unescaped string, or <jk>null</jk> if input is <jk>null</jk>.</em>
-<a class="jxr_linenumber" name="L7520" href="#L7520">7520</a> <em class="jxr_javadoccomment"> */</em>
-<a class="jxr_linenumber" name="L7521" href="#L7521">7521</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> String unescapeXml(String str) {
-<a class="jxr_linenumber" name="L7522" href="#L7522">7522</a> <strong class="jxr_keyword">if</strong> (str == <strong class="jxr_keyword">null</strong>)
-<a class="jxr_linenumber" name="L7523" href="#L7523">7523</a> <strong class="jxr_keyword">return</strong> <strong class="jxr_keyword">null</strong>;
-<a class="jxr_linenumber" name="L7524" href="#L7524">7524</a> <em class="jxr_comment">// Must unescape &amp; last to avoid interfering with other entities</em>
-<a class="jxr_linenumber" name="L7525" href="#L7525">7525</a> <strong class="jxr_keyword">return</strong> str.replace(<span class="jxr_string">"&lt;"</span>, <span class="jxr_string">"<"</span>).replace(<span class="jxr_string">"&gt;"</span>, <span class="jxr_string">">"</span>).replace(<span class="jxr_string">"&quot;"</span>, <span class="jxr_string">"\""</span>).replace(<span class="jxr_string">"&apos;"</span>, <span class="jxr_string">"'"</span>).replace( [...]
-<a class="jxr_linenumber" name="L7526" href="#L7526">7526</a> }
-<a class="jxr_linenumber" name="L7527" href="#L7527">7527</a>
-<a class="jxr_linenumber" name="L7528" href="#L7528">7528</a> <em class="jxr_javadoccomment">/**</em>
-<a class="jxr_linenumber" name="L7529" href="#L7529">7529</a> <em class="jxr_javadoccomment"> * Creates an escaped-unicode sequence (e.g. <js>"\\u1234"</js>) for the specified character.</em>
-<a class="jxr_linenumber" name="L7530" href="#L7530">7530</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7531" href="#L7531">7531</a> <em class="jxr_javadoccomment"> * @param c The character to create a sequence for.</em>
-<a class="jxr_linenumber" name="L7532" href="#L7532">7532</a> <em class="jxr_javadoccomment"> * @return An escaped-unicode sequence.</em>
-<a class="jxr_linenumber" name="L7533" href="#L7533">7533</a> <em class="jxr_javadoccomment"> */</em>
-<a class="jxr_linenumber" name="L7534" href="#L7534">7534</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> String unicodeSequence(<strong class="jxr_keyword">char</strong> c) {
-<a class="jxr_linenumber" name="L7535" href="#L7535">7535</a> <strong class="jxr_keyword">var</strong> sb = <strong class="jxr_keyword">new</strong> StringBuilder(6);
-<a class="jxr_linenumber" name="L7536" href="#L7536">7536</a> sb.append('\\').append('u');
-<a class="jxr_linenumber" name="L7537" href="#L7537">7537</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> cc : toHex4(c))
-<a class="jxr_linenumber" name="L7538" href="#L7538">7538</a> sb.append(cc);
-<a class="jxr_linenumber" name="L7539" href="#L7539">7539</a> <strong class="jxr_keyword">return</strong> sb.toString();
-<a class="jxr_linenumber" name="L7540" href="#L7540">7540</a> }
-<a class="jxr_linenumber" name="L7541" href="#L7541">7541</a>
-<a class="jxr_linenumber" name="L7542" href="#L7542">7542</a> <em class="jxr_javadoccomment">/**</em>
-<a class="jxr_linenumber" name="L7543" href="#L7543">7543</a> <em class="jxr_javadoccomment"> * Null-safe convenience method for {@link String#toUpperCase()}.</em>
+<a class="jxr_linenumber" name="L7461" href="#L7461">7461</a> }
+<a class="jxr_linenumber" name="L7462" href="#L7462">7462</a> }
+<a class="jxr_linenumber" name="L7463" href="#L7463">7463</a> }
+<a class="jxr_linenumber" name="L7464" href="#L7464">7464</a> sb.append(s.charAt(i));
+<a class="jxr_linenumber" name="L7465" href="#L7465">7465</a> }
+<a class="jxr_linenumber" name="L7466" href="#L7466">7466</a> <strong class="jxr_keyword">return</strong> sb.toString();
+<a class="jxr_linenumber" name="L7467" href="#L7467">7467</a> }
+<a class="jxr_linenumber" name="L7468" href="#L7468">7468</a>
+<a class="jxr_linenumber" name="L7469" href="#L7469">7469</a> <em class="jxr_javadoccomment">/**</em>
+<a class="jxr_linenumber" name="L7470" href="#L7470">7470</a> <em class="jxr_javadoccomment"> * Unescapes HTML entities in a string.</em>
+<a class="jxr_linenumber" name="L7471" href="#L7471">7471</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7472" href="#L7472">7472</a> <em class="jxr_javadoccomment"> * <p></em>
+<a class="jxr_linenumber" name="L7473" href="#L7473">7473</a> <em class="jxr_javadoccomment"> * Unescapes the following HTML entities:</em>
+<a class="jxr_linenumber" name="L7474" href="#L7474">7474</a> <em class="jxr_javadoccomment"> * <ul></em>
+<a class="jxr_linenumber" name="L7475" href="#L7475">7475</a> <em class="jxr_javadoccomment"> * <li><js>"&amp;amp;"</js> → <js>'&amp;'</js></li></em>
+<a class="jxr_linenumber" name="L7476" href="#L7476">7476</a> <em class="jxr_javadoccomment"> * <li><js>"&amp;lt;"</js> → <js>'&lt;'</js></li></em>
+<a class="jxr_linenumber" name="L7477" href="#L7477">7477</a> <em class="jxr_javadoccomment"> * <li><js>"&amp;gt;"</js> → <js>'&gt;'</js></li></em>
+<a class="jxr_linenumber" name="L7478" href="#L7478">7478</a> <em class="jxr_javadoccomment"> * <li><js>"&amp;quot;"</js> → <js>'"'</js></li></em>
+<a class="jxr_linenumber" name="L7479" href="#L7479">7479</a> <em class="jxr_javadoccomment"> * <li><js>"&amp;#39;"</js> or <js>"&amp;apos;"</js> → <js>'\''</js></li></em>
+<a class="jxr_linenumber" name="L7480" href="#L7480">7480</a> <em class="jxr_javadoccomment"> * </ul></em>
+<a class="jxr_linenumber" name="L7481" href="#L7481">7481</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7482" href="#L7482">7482</a> <em class="jxr_javadoccomment"> * <h5 class='section'>Example:</h5></em>
+<a class="jxr_linenumber" name="L7483" href="#L7483">7483</a> <em class="jxr_javadoccomment"> * <p class='bjava'></em>
+<a class="jxr_linenumber" name="L7484" href="#L7484">7484</a> <em class="jxr_javadoccomment"> * unescapeHtml(<js>"&amp;lt;script&amp;gt;"</js>); <jc>// Returns: "&lt;script&gt;"</jc></em>
+<a class="jxr_linenumber" name="L7485" href="#L7485">7485</a> <em class="jxr_javadoccomment"> * </p></em>
+<a class="jxr_linenumber" name="L7486" href="#L7486">7486</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7487" href="#L7487">7487</a> <em class="jxr_javadoccomment"> * @param str The string to unescape.</em>
+<a class="jxr_linenumber" name="L7488" href="#L7488">7488</a> <em class="jxr_javadoccomment"> * @return The unescaped string, or <jk>null</jk> if input is <jk>null</jk>.</em>
+<a class="jxr_linenumber" name="L7489" href="#L7489">7489</a> <em class="jxr_javadoccomment"> */</em>
+<a class="jxr_linenumber" name="L7490" href="#L7490">7490</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> String unescapeHtml(String str) {
+<a class="jxr_linenumber" name="L7491" href="#L7491">7491</a> <strong class="jxr_keyword">if</strong> (str == <strong class="jxr_keyword">null</strong>)
+<a class="jxr_linenumber" name="L7492" href="#L7492">7492</a> <strong class="jxr_keyword">return</strong> <strong class="jxr_keyword">null</strong>;
+<a class="jxr_linenumber" name="L7493" href="#L7493">7493</a> <em class="jxr_comment">// Must unescape &amp; last to avoid interfering with other entities</em>
+<a class="jxr_linenumber" name="L7494" href="#L7494">7494</a> <strong class="jxr_keyword">return</strong> str.replace(<span class="jxr_string">"&lt;"</span>, <span class="jxr_string">"<"</span>).replace(<span class="jxr_string">"&gt;"</span>, <span class="jxr_string">">"</span>).replace(<span class="jxr_string">"&quot;"</span>, <span class="jxr_string">"\""</span>).replace(<span class="jxr_string">"&#39;"</span>, <span class="jxr_string">"'"</span>).replace(< [...]
+<a class="jxr_linenumber" name="L7495" href="#L7495">7495</a> }
+<a class="jxr_linenumber" name="L7496" href="#L7496">7496</a>
+<a class="jxr_linenumber" name="L7497" href="#L7497">7497</a> <em class="jxr_javadoccomment">/**</em>
+<a class="jxr_linenumber" name="L7498" href="#L7498">7498</a> <em class="jxr_javadoccomment"> * Unescapes XML entities in a string.</em>
+<a class="jxr_linenumber" name="L7499" href="#L7499">7499</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7500" href="#L7500">7500</a> <em class="jxr_javadoccomment"> * <p></em>
+<a class="jxr_linenumber" name="L7501" href="#L7501">7501</a> <em class="jxr_javadoccomment"> * Unescapes the following XML entities:</em>
+<a class="jxr_linenumber" name="L7502" href="#L7502">7502</a> <em class="jxr_javadoccomment"> * <ul></em>
+<a class="jxr_linenumber" name="L7503" href="#L7503">7503</a> <em class="jxr_javadoccomment"> * <li><js>"&amp;amp;"</js> → <js>'&amp;'</js></li></em>
+<a class="jxr_linenumber" name="L7504" href="#L7504">7504</a> <em class="jxr_javadoccomment"> * <li><js>"&amp;lt;"</js> → <js>'&lt;'</js></li></em>
+<a class="jxr_linenumber" name="L7505" href="#L7505">7505</a> <em class="jxr_javadoccomment"> * <li><js>"&amp;gt;"</js> → <js>'&gt;'</js></li></em>
+<a class="jxr_linenumber" name="L7506" href="#L7506">7506</a> <em class="jxr_javadoccomment"> * <li><js>"&amp;quot;"</js> → <js>'"'</js></li></em>
+<a class="jxr_linenumber" name="L7507" href="#L7507">7507</a> <em class="jxr_javadoccomment"> * <li><js>"&amp;apos;"</js> → <js>'\''</js></li></em>
+<a class="jxr_linenumber" name="L7508" href="#L7508">7508</a> <em class="jxr_javadoccomment"> * </ul></em>
+<a class="jxr_linenumber" name="L7509" href="#L7509">7509</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7510" href="#L7510">7510</a> <em class="jxr_javadoccomment"> * <h5 class='section'>Example:</h5></em>
+<a class="jxr_linenumber" name="L7511" href="#L7511">7511</a> <em class="jxr_javadoccomment"> * <p class='bjava'></em>
+<a class="jxr_linenumber" name="L7512" href="#L7512">7512</a> <em class="jxr_javadoccomment"> * unescapeXml(<js>"&amp;lt;tag&amp;gt;"</js>); <jc>// Returns: "&lt;tag&gt;"</jc></em>
+<a class="jxr_linenumber" name="L7513" href="#L7513">7513</a> <em class="jxr_javadoccomment"> * </p></em>
+<a class="jxr_linenumber" name="L7514" href="#L7514">7514</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7515" href="#L7515">7515</a> <em class="jxr_javadoccomment"> * @param str The string to unescape.</em>
+<a class="jxr_linenumber" name="L7516" href="#L7516">7516</a> <em class="jxr_javadoccomment"> * @return The unescaped string, or <jk>null</jk> if input is <jk>null</jk>.</em>
+<a class="jxr_linenumber" name="L7517" href="#L7517">7517</a> <em class="jxr_javadoccomment"> */</em>
+<a class="jxr_linenumber" name="L7518" href="#L7518">7518</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> String unescapeXml(String str) {
+<a class="jxr_linenumber" name="L7519" href="#L7519">7519</a> <strong class="jxr_keyword">if</strong> (str == <strong class="jxr_keyword">null</strong>)
+<a class="jxr_linenumber" name="L7520" href="#L7520">7520</a> <strong class="jxr_keyword">return</strong> <strong class="jxr_keyword">null</strong>;
+<a class="jxr_linenumber" name="L7521" href="#L7521">7521</a> <em class="jxr_comment">// Must unescape &amp; last to avoid interfering with other entities</em>
+<a class="jxr_linenumber" name="L7522" href="#L7522">7522</a> <strong class="jxr_keyword">return</strong> str.replace(<span class="jxr_string">"&lt;"</span>, <span class="jxr_string">"<"</span>).replace(<span class="jxr_string">"&gt;"</span>, <span class="jxr_string">">"</span>).replace(<span class="jxr_string">"&quot;"</span>, <span class="jxr_string">"\""</span>).replace(<span class="jxr_string">"&apos;"</span>, <span class="jxr_string">"'"</span>).replace( [...]
+<a class="jxr_linenumber" name="L7523" href="#L7523">7523</a> }
+<a class="jxr_linenumber" name="L7524" href="#L7524">7524</a>
+<a class="jxr_linenumber" name="L7525" href="#L7525">7525</a> <em class="jxr_javadoccomment">/**</em>
+<a class="jxr_linenumber" name="L7526" href="#L7526">7526</a> <em class="jxr_javadoccomment"> * Creates an escaped-unicode sequence (e.g. <js>"\\u1234"</js>) for the specified character.</em>
+<a class="jxr_linenumber" name="L7527" href="#L7527">7527</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7528" href="#L7528">7528</a> <em class="jxr_javadoccomment"> * @param c The character to create a sequence for.</em>
+<a class="jxr_linenumber" name="L7529" href="#L7529">7529</a> <em class="jxr_javadoccomment"> * @return An escaped-unicode sequence.</em>
+<a class="jxr_linenumber" name="L7530" href="#L7530">7530</a> <em class="jxr_javadoccomment"> */</em>
+<a class="jxr_linenumber" name="L7531" href="#L7531">7531</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> String unicodeSequence(<strong class="jxr_keyword">char</strong> c) {
+<a class="jxr_linenumber" name="L7532" href="#L7532">7532</a> <strong class="jxr_keyword">var</strong> sb = <strong class="jxr_keyword">new</strong> StringBuilder(6);
+<a class="jxr_linenumber" name="L7533" href="#L7533">7533</a> sb.append('\\').append('u');
+<a class="jxr_linenumber" name="L7534" href="#L7534">7534</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> cc : toHex4(c))
+<a class="jxr_linenumber" name="L7535" href="#L7535">7535</a> sb.append(cc);
+<a class="jxr_linenumber" name="L7536" href="#L7536">7536</a> <strong class="jxr_keyword">return</strong> sb.toString();
+<a class="jxr_linenumber" name="L7537" href="#L7537">7537</a> }
+<a class="jxr_linenumber" name="L7538" href="#L7538">7538</a>
+<a class="jxr_linenumber" name="L7539" href="#L7539">7539</a> <em class="jxr_javadoccomment">/**</em>
+<a class="jxr_linenumber" name="L7540" href="#L7540">7540</a> <em class="jxr_javadoccomment"> * Null-safe convenience method for {@link String#toUpperCase()}.</em>
+<a class="jxr_linenumber" name="L7541" href="#L7541">7541</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7542" href="#L7542">7542</a> <em class="jxr_javadoccomment"> * <p></em>
+<a class="jxr_linenumber" name="L7543" href="#L7543">7543</a> <em class="jxr_javadoccomment"> * Converts the string to uppercase if not null.</em>
<a class="jxr_linenumber" name="L7544" href="#L7544">7544</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7545" href="#L7545">7545</a> <em class="jxr_javadoccomment"> * <p></em>
-<a class="jxr_linenumber" name="L7546" href="#L7546">7546</a> <em class="jxr_javadoccomment"> * Converts the string to uppercase if not null.</em>
-<a class="jxr_linenumber" name="L7547" href="#L7547">7547</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7548" href="#L7548">7548</a> <em class="jxr_javadoccomment"> * @param s The string to convert.</em>
-<a class="jxr_linenumber" name="L7549" href="#L7549">7549</a> <em class="jxr_javadoccomment"> * @return The uppercase string, or <jk>null</jk> if the input was <jk>null</jk>.</em>
-<a class="jxr_linenumber" name="L7550" href="#L7550">7550</a> <em class="jxr_javadoccomment"> * @see #lowerCase(String)</em>
-<a class="jxr_linenumber" name="L7551" href="#L7551">7551</a> <em class="jxr_javadoccomment"> * @see Utils#uc(String)</em>
-<a class="jxr_linenumber" name="L7552" href="#L7552">7552</a> <em class="jxr_javadoccomment"> */</em>
-<a class="jxr_linenumber" name="L7553" href="#L7553">7553</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> String upperCase(String s) {
-<a class="jxr_linenumber" name="L7554" href="#L7554">7554</a> <strong class="jxr_keyword">return</strong> s == <strong class="jxr_keyword">null</strong> ? <strong class="jxr_keyword">null</strong> : s.toUpperCase();
-<a class="jxr_linenumber" name="L7555" href="#L7555">7555</a> }
-<a class="jxr_linenumber" name="L7556" href="#L7556">7556</a>
-<a class="jxr_linenumber" name="L7557" href="#L7557">7557</a> <em class="jxr_javadoccomment">/**</em>
-<a class="jxr_linenumber" name="L7558" href="#L7558">7558</a> <em class="jxr_javadoccomment"> * Decodes a <c>application/x-www-form-urlencoded</c> string using <c>UTF-8</c> encoding scheme.</em>
-<a class="jxr_linenumber" name="L7559" href="#L7559">7559</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7560" href="#L7560">7560</a> <em class="jxr_javadoccomment"> * @param s The string to decode.</em>
-<a class="jxr_linenumber" name="L7561" href="#L7561">7561</a> <em class="jxr_javadoccomment"> * @return The decoded string, or <jk>null</jk> if input is <jk>null</jk>.</em>
-<a class="jxr_linenumber" name="L7562" href="#L7562">7562</a> <em class="jxr_javadoccomment"> */</em>
-<a class="jxr_linenumber" name="L7563" href="#L7563">7563</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> String urlDecode(String s) {
+<a class="jxr_linenumber" name="L7545" href="#L7545">7545</a> <em class="jxr_javadoccomment"> * @param s The string to convert.</em>
+<a class="jxr_linenumber" name="L7546" href="#L7546">7546</a> <em class="jxr_javadoccomment"> * @return The uppercase string, or <jk>null</jk> if the input was <jk>null</jk>.</em>
+<a class="jxr_linenumber" name="L7547" href="#L7547">7547</a> <em class="jxr_javadoccomment"> * @see #lowerCase(String)</em>
+<a class="jxr_linenumber" name="L7548" href="#L7548">7548</a> <em class="jxr_javadoccomment"> * @see Utils#uc(String)</em>
+<a class="jxr_linenumber" name="L7549" href="#L7549">7549</a> <em class="jxr_javadoccomment"> */</em>
+<a class="jxr_linenumber" name="L7550" href="#L7550">7550</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> String upperCase(String s) {
+<a class="jxr_linenumber" name="L7551" href="#L7551">7551</a> <strong class="jxr_keyword">return</strong> s == <strong class="jxr_keyword">null</strong> ? <strong class="jxr_keyword">null</strong> : s.toUpperCase();
+<a class="jxr_linenumber" name="L7552" href="#L7552">7552</a> }
+<a class="jxr_linenumber" name="L7553" href="#L7553">7553</a>
+<a class="jxr_linenumber" name="L7554" href="#L7554">7554</a> <em class="jxr_javadoccomment">/**</em>
+<a class="jxr_linenumber" name="L7555" href="#L7555">7555</a> <em class="jxr_javadoccomment"> * Decodes a <c>application/x-www-form-urlencoded</c> string using <c>UTF-8</c> encoding scheme.</em>
+<a class="jxr_linenumber" name="L7556" href="#L7556">7556</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7557" href="#L7557">7557</a> <em class="jxr_javadoccomment"> * @param s The string to decode.</em>
+<a class="jxr_linenumber" name="L7558" href="#L7558">7558</a> <em class="jxr_javadoccomment"> * @return The decoded string, or <jk>null</jk> if input is <jk>null</jk>.</em>
+<a class="jxr_linenumber" name="L7559" href="#L7559">7559</a> <em class="jxr_javadoccomment"> */</em>
+<a class="jxr_linenumber" name="L7560" href="#L7560">7560</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> String urlDecode(String s) {
+<a class="jxr_linenumber" name="L7561" href="#L7561">7561</a>
+<a class="jxr_linenumber" name="L7562" href="#L7562">7562</a> <strong class="jxr_keyword">if</strong> (s == <strong class="jxr_keyword">null</strong>)
+<a class="jxr_linenumber" name="L7563" href="#L7563">7563</a> <strong class="jxr_keyword">return</strong> s;
<a class="jxr_linenumber" name="L7564" href="#L7564">7564</a>
-<a class="jxr_linenumber" name="L7565" href="#L7565">7565</a> <strong class="jxr_keyword">if</strong> (s == <strong class="jxr_keyword">null</strong>)
-<a class="jxr_linenumber" name="L7566" href="#L7566">7566</a> <strong class="jxr_keyword">return</strong> s;
-<a class="jxr_linenumber" name="L7567" href="#L7567">7567</a>
-<a class="jxr_linenumber" name="L7568" href="#L7568">7568</a> <strong class="jxr_keyword">var</strong> needsDecode = false;
-<a class="jxr_linenumber" name="L7569" href="#L7569">7569</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> i = 0; i < s.length() && ! needsDecode; i++) {
-<a class="jxr_linenumber" name="L7570" href="#L7570">7570</a> <strong class="jxr_keyword">var</strong> c = s.charAt(i);
-<a class="jxr_linenumber" name="L7571" href="#L7571">7571</a> <strong class="jxr_keyword">if</strong> (c == '+' || c == '%')
-<a class="jxr_linenumber" name="L7572" href="#L7572">7572</a> needsDecode = <strong class="jxr_keyword">true</strong>;
-<a class="jxr_linenumber" name="L7573" href="#L7573">7573</a> }
-<a class="jxr_linenumber" name="L7574" href="#L7574">7574</a>
-<a class="jxr_linenumber" name="L7575" href="#L7575">7575</a> <strong class="jxr_keyword">if</strong> (needsDecode) {
-<a class="jxr_linenumber" name="L7576" href="#L7576">7576</a> <strong class="jxr_keyword">return</strong> safe(()->URLDecoder.decode(s, <span class="jxr_string">"UTF-8"</span>));
-<a class="jxr_linenumber" name="L7577" href="#L7577">7577</a> }
-<a class="jxr_linenumber" name="L7578" href="#L7578">7578</a> <strong class="jxr_keyword">return</strong> s;
-<a class="jxr_linenumber" name="L7579" href="#L7579">7579</a> }
-<a class="jxr_linenumber" name="L7580" href="#L7580">7580</a>
-<a class="jxr_linenumber" name="L7581" href="#L7581">7581</a> <em class="jxr_javadoccomment">/**</em>
-<a class="jxr_linenumber" name="L7582" href="#L7582">7582</a> <em class="jxr_javadoccomment"> * Encodes a <c>application/x-www-form-urlencoded</c> string using <c>UTF-8</c> encoding scheme.</em>
-<a class="jxr_linenumber" name="L7583" href="#L7583">7583</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7584" href="#L7584">7584</a> <em class="jxr_javadoccomment"> * @param s The string to encode.</em>
-<a class="jxr_linenumber" name="L7585" href="#L7585">7585</a> <em class="jxr_javadoccomment"> * @return The encoded string, or <jk>null</jk> if input is <jk>null</jk>.</em>
-<a class="jxr_linenumber" name="L7586" href="#L7586">7586</a> <em class="jxr_javadoccomment"> */</em>
-<a class="jxr_linenumber" name="L7587" href="#L7587">7587</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> String urlEncode(String s) {
+<a class="jxr_linenumber" name="L7565" href="#L7565">7565</a> <strong class="jxr_keyword">var</strong> needsDecode = false;
+<a class="jxr_linenumber" name="L7566" href="#L7566">7566</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> i = 0; i < s.length() && ! needsDecode; i++) {
+<a class="jxr_linenumber" name="L7567" href="#L7567">7567</a> <strong class="jxr_keyword">var</strong> c = s.charAt(i);
+<a class="jxr_linenumber" name="L7568" href="#L7568">7568</a> <strong class="jxr_keyword">if</strong> (c == '+' || c == '%')
+<a class="jxr_linenumber" name="L7569" href="#L7569">7569</a> needsDecode = <strong class="jxr_keyword">true</strong>;
+<a class="jxr_linenumber" name="L7570" href="#L7570">7570</a> }
+<a class="jxr_linenumber" name="L7571" href="#L7571">7571</a>
+<a class="jxr_linenumber" name="L7572" href="#L7572">7572</a> <strong class="jxr_keyword">if</strong> (needsDecode) {
+<a class="jxr_linenumber" name="L7573" href="#L7573">7573</a> <strong class="jxr_keyword">return</strong> safe(()->URLDecoder.decode(s, <span class="jxr_string">"UTF-8"</span>));
+<a class="jxr_linenumber" name="L7574" href="#L7574">7574</a> }
+<a class="jxr_linenumber" name="L7575" href="#L7575">7575</a> <strong class="jxr_keyword">return</strong> s;
+<a class="jxr_linenumber" name="L7576" href="#L7576">7576</a> }
+<a class="jxr_linenumber" name="L7577" href="#L7577">7577</a>
+<a class="jxr_linenumber" name="L7578" href="#L7578">7578</a> <em class="jxr_javadoccomment">/**</em>
+<a class="jxr_linenumber" name="L7579" href="#L7579">7579</a> <em class="jxr_javadoccomment"> * Encodes a <c>application/x-www-form-urlencoded</c> string using <c>UTF-8</c> encoding scheme.</em>
+<a class="jxr_linenumber" name="L7580" href="#L7580">7580</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7581" href="#L7581">7581</a> <em class="jxr_javadoccomment"> * @param s The string to encode.</em>
+<a class="jxr_linenumber" name="L7582" href="#L7582">7582</a> <em class="jxr_javadoccomment"> * @return The encoded string, or <jk>null</jk> if input is <jk>null</jk>.</em>
+<a class="jxr_linenumber" name="L7583" href="#L7583">7583</a> <em class="jxr_javadoccomment"> */</em>
+<a class="jxr_linenumber" name="L7584" href="#L7584">7584</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> String urlEncode(String s) {
+<a class="jxr_linenumber" name="L7585" href="#L7585">7585</a>
+<a class="jxr_linenumber" name="L7586" href="#L7586">7586</a> <strong class="jxr_keyword">if</strong> (s == <strong class="jxr_keyword">null</strong>)
+<a class="jxr_linenumber" name="L7587" href="#L7587">7587</a> <strong class="jxr_keyword">return</strong> <strong class="jxr_keyword">null</strong>;
<a class="jxr_linenumber" name="L7588" href="#L7588">7588</a>
-<a class="jxr_linenumber" name="L7589" href="#L7589">7589</a> <strong class="jxr_keyword">if</strong> (s == <strong class="jxr_keyword">null</strong>)
-<a class="jxr_linenumber" name="L7590" href="#L7590">7590</a> <strong class="jxr_keyword">return</strong> <strong class="jxr_keyword">null</strong>;
-<a class="jxr_linenumber" name="L7591" href="#L7591">7591</a>
-<a class="jxr_linenumber" name="L7592" href="#L7592">7592</a> <strong class="jxr_keyword">var</strong> needsEncode = false;
+<a class="jxr_linenumber" name="L7589" href="#L7589">7589</a> <strong class="jxr_keyword">var</strong> needsEncode = false;
+<a class="jxr_linenumber" name="L7590" href="#L7590">7590</a>
+<a class="jxr_linenumber" name="L7591" href="#L7591">7591</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> i = 0; i < s.length() && ! needsEncode; i++)
+<a class="jxr_linenumber" name="L7592" href="#L7592">7592</a> needsEncode |= (! URL_UNENCODED_CHARS.contains(s.charAt(i)));
<a class="jxr_linenumber" name="L7593" href="#L7593">7593</a>
-<a class="jxr_linenumber" name="L7594" href="#L7594">7594</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> i = 0; i < s.length() && ! needsEncode; i++)
-<a class="jxr_linenumber" name="L7595" href="#L7595">7595</a> needsEncode |= (! URL_UNENCODED_CHARS.contains(s.charAt(i)));
-<a class="jxr_linenumber" name="L7596" href="#L7596">7596</a>
-<a class="jxr_linenumber" name="L7597" href="#L7597">7597</a> <strong class="jxr_keyword">if</strong> (needsEncode) {
-<a class="jxr_linenumber" name="L7598" href="#L7598">7598</a> <strong class="jxr_keyword">return</strong> safe(()->URLEncoder.encode(s, <span class="jxr_string">"UTF-8"</span>));
-<a class="jxr_linenumber" name="L7599" href="#L7599">7599</a> }
+<a class="jxr_linenumber" name="L7594" href="#L7594">7594</a> <strong class="jxr_keyword">if</strong> (needsEncode) {
+<a class="jxr_linenumber" name="L7595" href="#L7595">7595</a> <strong class="jxr_keyword">return</strong> safe(()->URLEncoder.encode(s, <span class="jxr_string">"UTF-8"</span>));
+<a class="jxr_linenumber" name="L7596" href="#L7596">7596</a> }
+<a class="jxr_linenumber" name="L7597" href="#L7597">7597</a>
+<a class="jxr_linenumber" name="L7598" href="#L7598">7598</a> <strong class="jxr_keyword">return</strong> s;
+<a class="jxr_linenumber" name="L7599" href="#L7599">7599</a> }
<a class="jxr_linenumber" name="L7600" href="#L7600">7600</a>
-<a class="jxr_linenumber" name="L7601" href="#L7601">7601</a> <strong class="jxr_keyword">return</strong> s;
-<a class="jxr_linenumber" name="L7602" href="#L7602">7602</a> }
-<a class="jxr_linenumber" name="L7603" href="#L7603">7603</a>
-<a class="jxr_linenumber" name="L7604" href="#L7604">7604</a> <em class="jxr_javadoccomment">/**</em>
-<a class="jxr_linenumber" name="L7605" href="#L7605">7605</a> <em class="jxr_javadoccomment"> * Same as {@link #urlEncode(String)} except only escapes characters that absolutely need to be escaped.</em>
-<a class="jxr_linenumber" name="L7606" href="#L7606">7606</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7607" href="#L7607">7607</a> <em class="jxr_javadoccomment"> * @param s The string to escape.</em>
-<a class="jxr_linenumber" name="L7608" href="#L7608">7608</a> <em class="jxr_javadoccomment"> * @return The encoded string, or <jk>null</jk> if input is <jk>null</jk>.</em>
-<a class="jxr_linenumber" name="L7609" href="#L7609">7609</a> <em class="jxr_javadoccomment"> */</em>
-<a class="jxr_linenumber" name="L7610" href="#L7610">7610</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> String urlEncodeLax(String s) {
-<a class="jxr_linenumber" name="L7611" href="#L7611">7611</a> <strong class="jxr_keyword">if</strong> (s == <strong class="jxr_keyword">null</strong>)
-<a class="jxr_linenumber" name="L7612" href="#L7612">7612</a> <strong class="jxr_keyword">return</strong> <strong class="jxr_keyword">null</strong>;
-<a class="jxr_linenumber" name="L7613" href="#L7613">7613</a> <strong class="jxr_keyword">var</strong> needsEncode = false;
-<a class="jxr_linenumber" name="L7614" href="#L7614">7614</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> i = 0; i < s.length() && ! needsEncode; i++)
-<a class="jxr_linenumber" name="L7615" href="#L7615">7615</a> needsEncode |= (! URL_UNENCODED_LAX_CHARS.contains(s.charAt(i)));
-<a class="jxr_linenumber" name="L7616" href="#L7616">7616</a> <strong class="jxr_keyword">if</strong> (needsEncode) {
-<a class="jxr_linenumber" name="L7617" href="#L7617">7617</a> <strong class="jxr_keyword">var</strong> sb = <strong class="jxr_keyword">new</strong> StringBuilder(s.length() * 2);
-<a class="jxr_linenumber" name="L7618" href="#L7618">7618</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> i = 0; i < s.length(); i++) {
-<a class="jxr_linenumber" name="L7619" href="#L7619">7619</a> <strong class="jxr_keyword">var</strong> c = s.charAt(i);
-<a class="jxr_linenumber" name="L7620" href="#L7620">7620</a> <strong class="jxr_keyword">if</strong> (URL_UNENCODED_LAX_CHARS.contains(c))
-<a class="jxr_linenumber" name="L7621" href="#L7621">7621</a> sb.append(c);
-<a class="jxr_linenumber" name="L7622" href="#L7622">7622</a> <strong class="jxr_keyword">else</strong> <strong class="jxr_keyword">if</strong> (c == ' ')
-<a class="jxr_linenumber" name="L7623" href="#L7623">7623</a> sb.append(<span class="jxr_string">"+"</span>);
-<a class="jxr_linenumber" name="L7624" href="#L7624">7624</a> <strong class="jxr_keyword">else</strong> <strong class="jxr_keyword">if</strong> (c <= 127)
-<a class="jxr_linenumber" name="L7625" href="#L7625">7625</a> sb.append('%').append(toHex2(c));
-<a class="jxr_linenumber" name="L7626" href="#L7626">7626</a> <strong class="jxr_keyword">else</strong>
-<a class="jxr_linenumber" name="L7627" href="#L7627">7627</a> safe(()->sb.append(URLEncoder.encode(<span class="jxr_string">""</span> + c, <span class="jxr_string">"UTF-8"</span>))); <em class="jxr_comment">// Yuck.</em>
-<a class="jxr_linenumber" name="L7628" href="#L7628">7628</a> }
-<a class="jxr_linenumber" name="L7629" href="#L7629">7629</a> s = sb.toString();
-<a class="jxr_linenumber" name="L7630" href="#L7630">7630</a> }
-<a class="jxr_linenumber" name="L7631" href="#L7631">7631</a> <strong class="jxr_keyword">return</strong> s;
-<a class="jxr_linenumber" name="L7632" href="#L7632">7632</a> }
-<a class="jxr_linenumber" name="L7633" href="#L7633">7633</a>
-<a class="jxr_linenumber" name="L7634" href="#L7634">7634</a> <em class="jxr_javadoccomment">/**</em>
-<a class="jxr_linenumber" name="L7635" href="#L7635">7635</a> <em class="jxr_javadoccomment"> * Similar to {@link URLEncoder#encode(String, String)} but doesn't encode <js>"/"</js> characters.</em>
-<a class="jxr_linenumber" name="L7636" href="#L7636">7636</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7637" href="#L7637">7637</a> <em class="jxr_javadoccomment"> * @param o The object to encode.</em>
-<a class="jxr_linenumber" name="L7638" href="#L7638">7638</a> <em class="jxr_javadoccomment"> * @return The URL encoded string, or <jk>null</jk> if the object was null.</em>
-<a class="jxr_linenumber" name="L7639" href="#L7639">7639</a> <em class="jxr_javadoccomment"> */</em>
-<a class="jxr_linenumber" name="L7640" href="#L7640">7640</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> String urlEncodePath(Object o) {
+<a class="jxr_linenumber" name="L7601" href="#L7601">7601</a> <em class="jxr_javadoccomment">/**</em>
+<a class="jxr_linenumber" name="L7602" href="#L7602">7602</a> <em class="jxr_javadoccomment"> * Same as {@link #urlEncode(String)} except only escapes characters that absolutely need to be escaped.</em>
+<a class="jxr_linenumber" name="L7603" href="#L7603">7603</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7604" href="#L7604">7604</a> <em class="jxr_javadoccomment"> * @param s The string to escape.</em>
+<a class="jxr_linenumber" name="L7605" href="#L7605">7605</a> <em class="jxr_javadoccomment"> * @return The encoded string, or <jk>null</jk> if input is <jk>null</jk>.</em>
+<a class="jxr_linenumber" name="L7606" href="#L7606">7606</a> <em class="jxr_javadoccomment"> */</em>
+<a class="jxr_linenumber" name="L7607" href="#L7607">7607</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> String urlEncodeLax(String s) {
+<a class="jxr_linenumber" name="L7608" href="#L7608">7608</a> <strong class="jxr_keyword">if</strong> (s == <strong class="jxr_keyword">null</strong>)
+<a class="jxr_linenumber" name="L7609" href="#L7609">7609</a> <strong class="jxr_keyword">return</strong> <strong class="jxr_keyword">null</strong>;
+<a class="jxr_linenumber" name="L7610" href="#L7610">7610</a> <strong class="jxr_keyword">var</strong> needsEncode = false;
+<a class="jxr_linenumber" name="L7611" href="#L7611">7611</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> i = 0; i < s.length() && ! needsEncode; i++)
+<a class="jxr_linenumber" name="L7612" href="#L7612">7612</a> needsEncode |= (! URL_UNENCODED_LAX_CHARS.contains(s.charAt(i)));
+<a class="jxr_linenumber" name="L7613" href="#L7613">7613</a> <strong class="jxr_keyword">if</strong> (needsEncode) {
+<a class="jxr_linenumber" name="L7614" href="#L7614">7614</a> <strong class="jxr_keyword">var</strong> sb = <strong class="jxr_keyword">new</strong> StringBuilder(s.length() * 2);
+<a class="jxr_linenumber" name="L7615" href="#L7615">7615</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> i = 0; i < s.length(); i++) {
+<a class="jxr_linenumber" name="L7616" href="#L7616">7616</a> <strong class="jxr_keyword">var</strong> c = s.charAt(i);
+<a class="jxr_linenumber" name="L7617" href="#L7617">7617</a> <strong class="jxr_keyword">if</strong> (URL_UNENCODED_LAX_CHARS.contains(c))
+<a class="jxr_linenumber" name="L7618" href="#L7618">7618</a> sb.append(c);
+<a class="jxr_linenumber" name="L7619" href="#L7619">7619</a> <strong class="jxr_keyword">else</strong> <strong class="jxr_keyword">if</strong> (c == ' ')
+<a class="jxr_linenumber" name="L7620" href="#L7620">7620</a> sb.append(<span class="jxr_string">"+"</span>);
+<a class="jxr_linenumber" name="L7621" href="#L7621">7621</a> <strong class="jxr_keyword">else</strong> <strong class="jxr_keyword">if</strong> (c <= 127)
+<a class="jxr_linenumber" name="L7622" href="#L7622">7622</a> sb.append('%').append(toHex2(c));
+<a class="jxr_linenumber" name="L7623" href="#L7623">7623</a> <strong class="jxr_keyword">else</strong>
+<a class="jxr_linenumber" name="L7624" href="#L7624">7624</a> safe(()->sb.append(URLEncoder.encode(<span class="jxr_string">""</span> + c, <span class="jxr_string">"UTF-8"</span>))); <em class="jxr_comment">// Yuck.</em>
+<a class="jxr_linenumber" name="L7625" href="#L7625">7625</a> }
+<a class="jxr_linenumber" name="L7626" href="#L7626">7626</a> s = sb.toString();
+<a class="jxr_linenumber" name="L7627" href="#L7627">7627</a> }
+<a class="jxr_linenumber" name="L7628" href="#L7628">7628</a> <strong class="jxr_keyword">return</strong> s;
+<a class="jxr_linenumber" name="L7629" href="#L7629">7629</a> }
+<a class="jxr_linenumber" name="L7630" href="#L7630">7630</a>
+<a class="jxr_linenumber" name="L7631" href="#L7631">7631</a> <em class="jxr_javadoccomment">/**</em>
+<a class="jxr_linenumber" name="L7632" href="#L7632">7632</a> <em class="jxr_javadoccomment"> * Similar to {@link URLEncoder#encode(String, String)} but doesn't encode <js>"/"</js> characters.</em>
+<a class="jxr_linenumber" name="L7633" href="#L7633">7633</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7634" href="#L7634">7634</a> <em class="jxr_javadoccomment"> * @param o The object to encode.</em>
+<a class="jxr_linenumber" name="L7635" href="#L7635">7635</a> <em class="jxr_javadoccomment"> * @return The URL encoded string, or <jk>null</jk> if the object was null.</em>
+<a class="jxr_linenumber" name="L7636" href="#L7636">7636</a> <em class="jxr_javadoccomment"> */</em>
+<a class="jxr_linenumber" name="L7637" href="#L7637">7637</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> String urlEncodePath(Object o) {
+<a class="jxr_linenumber" name="L7638" href="#L7638">7638</a>
+<a class="jxr_linenumber" name="L7639" href="#L7639">7639</a> <strong class="jxr_keyword">if</strong> (o == <strong class="jxr_keyword">null</strong>)
+<a class="jxr_linenumber" name="L7640" href="#L7640">7640</a> <strong class="jxr_keyword">return</strong> <strong class="jxr_keyword">null</strong>;
<a class="jxr_linenumber" name="L7641" href="#L7641">7641</a>
-<a class="jxr_linenumber" name="L7642" href="#L7642">7642</a> <strong class="jxr_keyword">if</strong> (o == <strong class="jxr_keyword">null</strong>)
-<a class="jxr_linenumber" name="L7643" href="#L7643">7643</a> <strong class="jxr_keyword">return</strong> <strong class="jxr_keyword">null</strong>;
-<a class="jxr_linenumber" name="L7644" href="#L7644">7644</a>
-<a class="jxr_linenumber" name="L7645" href="#L7645">7645</a> <strong class="jxr_keyword">var</strong> s = s(o);
-<a class="jxr_linenumber" name="L7646" href="#L7646">7646</a>
-<a class="jxr_linenumber" name="L7647" href="#L7647">7647</a> <strong class="jxr_keyword">var</strong> needsEncode = false;
-<a class="jxr_linenumber" name="L7648" href="#L7648">7648</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> i = 0; i < s.length() && ! needsEncode; i++)
-<a class="jxr_linenumber" name="L7649" href="#L7649">7649</a> needsEncode = URL_ENCODE_PATHINFO_VALIDCHARS.contains(s.charAt(i));
-<a class="jxr_linenumber" name="L7650" href="#L7650">7650</a> <strong class="jxr_keyword">if</strong> (! needsEncode)
-<a class="jxr_linenumber" name="L7651" href="#L7651">7651</a> <strong class="jxr_keyword">return</strong> s;
-<a class="jxr_linenumber" name="L7652" href="#L7652">7652</a>
-<a class="jxr_linenumber" name="L7653" href="#L7653">7653</a> <strong class="jxr_keyword">var</strong> sb = <strong class="jxr_keyword">new</strong> StringBuilder();
-<a class="jxr_linenumber" name="L7654" href="#L7654">7654</a> <strong class="jxr_keyword">var</strong> caw = <strong class="jxr_keyword">new</strong> CharArrayWriter();
-<a class="jxr_linenumber" name="L7655" href="#L7655">7655</a> <strong class="jxr_keyword">var</strong> caseDiff = ('a' - 'A');
-<a class="jxr_linenumber" name="L7656" href="#L7656">7656</a>
-<a class="jxr_linenumber" name="L7657" href="#L7657">7657</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> i = 0; i < s.length();) {
-<a class="jxr_linenumber" name="L7658" href="#L7658">7658</a> <strong class="jxr_keyword">var</strong> c = s.charAt(i);
-<a class="jxr_linenumber" name="L7659" href="#L7659">7659</a> <strong class="jxr_keyword">if</strong> (URL_ENCODE_PATHINFO_VALIDCHARS.contains(c)) {
-<a class="jxr_linenumber" name="L7660" href="#L7660">7660</a> sb.append(c);
-<a class="jxr_linenumber" name="L7661" href="#L7661">7661</a> i++; <em class="jxr_comment">// NOSONAR - Intentional.</em>
-<a class="jxr_linenumber" name="L7662" href="#L7662">7662</a> } <strong class="jxr_keyword">else</strong> {
-<a class="jxr_linenumber" name="L7663" href="#L7663">7663</a> <strong class="jxr_keyword">if</strong> (c == ' ') {
-<a class="jxr_linenumber" name="L7664" href="#L7664">7664</a> sb.append('+');
-<a class="jxr_linenumber" name="L7665" href="#L7665">7665</a> i++; <em class="jxr_comment">// NOSONAR - Intentional.</em>
-<a class="jxr_linenumber" name="L7666" href="#L7666">7666</a> } <strong class="jxr_keyword">else</strong> {
-<a class="jxr_linenumber" name="L7667" href="#L7667">7667</a> <strong class="jxr_keyword">do</strong> {
-<a class="jxr_linenumber" name="L7668" href="#L7668">7668</a> caw.write(c);
-<a class="jxr_linenumber" name="L7669" href="#L7669">7669</a> <strong class="jxr_keyword">if</strong> (c >= 0xD800 && c <= 0xDBFF) {
-<a class="jxr_linenumber" name="L7670" href="#L7670">7670</a> <strong class="jxr_keyword">if</strong> ((i + 1) < s.length()) { <em class="jxr_comment">// NOSONAR - Intentional.</em>
-<a class="jxr_linenumber" name="L7671" href="#L7671">7671</a> <strong class="jxr_keyword">int</strong> d = s.charAt(i + 1);
-<a class="jxr_linenumber" name="L7672" href="#L7672">7672</a> <strong class="jxr_keyword">if</strong> (d >= 0xDC00 && d <= 0xDFFF) {
-<a class="jxr_linenumber" name="L7673" href="#L7673">7673</a> caw.write(d);
-<a class="jxr_linenumber" name="L7674" href="#L7674">7674</a> i++; <em class="jxr_comment">// NOSONAR - Intentional.</em>
-<a class="jxr_linenumber" name="L7675" href="#L7675">7675</a> }
-<a class="jxr_linenumber" name="L7676" href="#L7676">7676</a> }
-<a class="jxr_linenumber" name="L7677" href="#L7677">7677</a> }
-<a class="jxr_linenumber" name="L7678" href="#L7678">7678</a> i++; <em class="jxr_comment">// NOSONAR - Intentional.</em>
-<a class="jxr_linenumber" name="L7679" href="#L7679">7679</a> } <strong class="jxr_keyword">while</strong> (i < s.length() && ! URL_ENCODE_PATHINFO_VALIDCHARS.contains((c = s.charAt(i)))); <em class="jxr_comment">// NOSONAR - Intentional.</em>
-<a class="jxr_linenumber" name="L7680" href="#L7680">7680</a>
-<a class="jxr_linenumber" name="L7681" href="#L7681">7681</a> caw.flush();
-<a class="jxr_linenumber" name="L7682" href="#L7682">7682</a> <strong class="jxr_keyword">var</strong> s2 = <strong class="jxr_keyword">new</strong> String(caw.toCharArray());
-<a class="jxr_linenumber" name="L7683" href="#L7683">7683</a> <strong class="jxr_keyword">var</strong> ba = s2.getBytes(UTF8);
-<a class="jxr_linenumber" name="L7684" href="#L7684">7684</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> element : ba) {
-<a class="jxr_linenumber" name="L7685" href="#L7685">7685</a> sb.append('%');
-<a class="jxr_linenumber" name="L7686" href="#L7686">7686</a> <strong class="jxr_keyword">var</strong> ch = forDigit((element >> 4) & 0xF, 16);
-<a class="jxr_linenumber" name="L7687" href="#L7687">7687</a> <strong class="jxr_keyword">if</strong> (isLetter(ch)) {
-<a class="jxr_linenumber" name="L7688" href="#L7688">7688</a> ch -= caseDiff;
-<a class="jxr_linenumber" name="L7689" href="#L7689">7689</a> }
-<a class="jxr_linenumber" name="L7690" href="#L7690">7690</a> sb.append(ch);
-<a class="jxr_linenumber" name="L7691" href="#L7691">7691</a> ch = forDigit(element & 0xF, 16);
-<a class="jxr_linenumber" name="L7692" href="#L7692">7692</a> <strong class="jxr_keyword">if</strong> (isLetter(ch)) {
-<a class="jxr_linenumber" name="L7693" href="#L7693">7693</a> ch -= caseDiff;
-<a class="jxr_linenumber" name="L7694" href="#L7694">7694</a> }
-<a class="jxr_linenumber" name="L7695" href="#L7695">7695</a> sb.append(ch);
-<a class="jxr_linenumber" name="L7696" href="#L7696">7696</a> }
-<a class="jxr_linenumber" name="L7697" href="#L7697">7697</a> caw.reset();
-<a class="jxr_linenumber" name="L7698" href="#L7698">7698</a> }
-<a class="jxr_linenumber" name="L7699" href="#L7699">7699</a> }
-<a class="jxr_linenumber" name="L7700" href="#L7700">7700</a> }
-<a class="jxr_linenumber" name="L7701" href="#L7701">7701</a> <strong class="jxr_keyword">return</strong> sb.toString();
-<a class="jxr_linenumber" name="L7702" href="#L7702">7702</a> }
-<a class="jxr_linenumber" name="L7703" href="#L7703">7703</a>
-<a class="jxr_linenumber" name="L7704" href="#L7704">7704</a> <em class="jxr_javadoccomment">/**</em>
-<a class="jxr_linenumber" name="L7705" href="#L7705">7705</a> <em class="jxr_javadoccomment"> * Counts the number of words in a string.</em>
-<a class="jxr_linenumber" name="L7706" href="#L7706">7706</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7707" href="#L7707">7707</a> <em class="jxr_javadoccomment"> * <p></em>
-<a class="jxr_linenumber" name="L7708" href="#L7708">7708</a> <em class="jxr_javadoccomment"> * A word is defined as a sequence of one or more word characters (letters, digits, underscores)</em>
-<a class="jxr_linenumber" name="L7709" href="#L7709">7709</a> <em class="jxr_javadoccomment"> * separated by non-word characters.</em>
-<a class="jxr_linenumber" name="L7710" href="#L7710">7710</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7711" href="#L7711">7711</a> <em class="jxr_javadoccomment"> * <h5 class='section'>Example:</h5></em>
-<a class="jxr_linenumber" name="L7712" href="#L7712">7712</a> <em class="jxr_javadoccomment"> * <p class='bjava'></em>
-<a class="jxr_linenumber" name="L7713" href="#L7713">7713</a> <em class="jxr_javadoccomment"> * wordCount(<js>"Hello world"</js>); <jc>// 2</jc></em>
-<a class="jxr_linenumber" name="L7714" href="#L7714">7714</a> <em class="jxr_javadoccomment"> * wordCount(<js>"The quick brown fox"</js>); <jc>// 4</jc></em>
-<a class="jxr_linenumber" name="L7715" href="#L7715">7715</a> <em class="jxr_javadoccomment"> * wordCount(<js>"Hello, world! How are you?"</js>); <jc>// 5</jc></em>
-<a class="jxr_linenumber" name="L7716" href="#L7716">7716</a> <em class="jxr_javadoccomment"> * </p></em>
-<a class="jxr_linenumber" name="L7717" href="#L7717">7717</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7718" href="#L7718">7718</a> <em class="jxr_javadoccomment"> * @param str The string to count words in. Can be <jk>null</jk>.</em>
-<a class="jxr_linenumber" name="L7719" href="#L7719">7719</a> <em class="jxr_javadoccomment"> * @return The number of words, or <c>0</c> if the string is <jk>null</jk> or empty.</em>
-<a class="jxr_linenumber" name="L7720" href="#L7720">7720</a> <em class="jxr_javadoccomment"> */</em>
-<a class="jxr_linenumber" name="L7721" href="#L7721">7721</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> <strong class="jxr_keyword">int</strong> wordCount(String str) {
-<a class="jxr_linenumber" name="L7722" href="#L7722">7722</a> <strong class="jxr_keyword">if</strong> (isEmpty(str))
-<a class="jxr_linenumber" name="L7723" href="#L7723">7723</a> <strong class="jxr_keyword">return</strong> 0;
+<a class="jxr_linenumber" name="L7642" href="#L7642">7642</a> <strong class="jxr_keyword">var</strong> s = s(o);
+<a class="jxr_linenumber" name="L7643" href="#L7643">7643</a>
+<a class="jxr_linenumber" name="L7644" href="#L7644">7644</a> <strong class="jxr_keyword">var</strong> needsEncode = false;
+<a class="jxr_linenumber" name="L7645" href="#L7645">7645</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> i = 0; i < s.length() && ! needsEncode; i++)
+<a class="jxr_linenumber" name="L7646" href="#L7646">7646</a> needsEncode = URL_ENCODE_PATHINFO_VALIDCHARS.contains(s.charAt(i));
+<a class="jxr_linenumber" name="L7647" href="#L7647">7647</a> <strong class="jxr_keyword">if</strong> (! needsEncode)
+<a class="jxr_linenumber" name="L7648" href="#L7648">7648</a> <strong class="jxr_keyword">return</strong> s;
+<a class="jxr_linenumber" name="L7649" href="#L7649">7649</a>
+<a class="jxr_linenumber" name="L7650" href="#L7650">7650</a> <strong class="jxr_keyword">var</strong> sb = <strong class="jxr_keyword">new</strong> StringBuilder();
+<a class="jxr_linenumber" name="L7651" href="#L7651">7651</a> <strong class="jxr_keyword">var</strong> caw = <strong class="jxr_keyword">new</strong> CharArrayWriter();
+<a class="jxr_linenumber" name="L7652" href="#L7652">7652</a> <strong class="jxr_keyword">var</strong> caseDiff = ('a' - 'A');
+<a class="jxr_linenumber" name="L7653" href="#L7653">7653</a>
+<a class="jxr_linenumber" name="L7654" href="#L7654">7654</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> i = 0; i < s.length();) {
+<a class="jxr_linenumber" name="L7655" href="#L7655">7655</a> <strong class="jxr_keyword">var</strong> c = s.charAt(i);
+<a class="jxr_linenumber" name="L7656" href="#L7656">7656</a> <strong class="jxr_keyword">if</strong> (URL_ENCODE_PATHINFO_VALIDCHARS.contains(c)) {
+<a class="jxr_linenumber" name="L7657" href="#L7657">7657</a> sb.append(c);
+<a class="jxr_linenumber" name="L7658" href="#L7658">7658</a> i++; <em class="jxr_comment">// NOSONAR - Intentional.</em>
+<a class="jxr_linenumber" name="L7659" href="#L7659">7659</a> } <strong class="jxr_keyword">else</strong> {
+<a class="jxr_linenumber" name="L7660" href="#L7660">7660</a> <strong class="jxr_keyword">if</strong> (c == ' ') {
+<a class="jxr_linenumber" name="L7661" href="#L7661">7661</a> sb.append('+');
+<a class="jxr_linenumber" name="L7662" href="#L7662">7662</a> i++; <em class="jxr_comment">// NOSONAR - Intentional.</em>
+<a class="jxr_linenumber" name="L7663" href="#L7663">7663</a> } <strong class="jxr_keyword">else</strong> {
+<a class="jxr_linenumber" name="L7664" href="#L7664">7664</a> <strong class="jxr_keyword">do</strong> {
+<a class="jxr_linenumber" name="L7665" href="#L7665">7665</a> caw.write(c);
+<a class="jxr_linenumber" name="L7666" href="#L7666">7666</a> <strong class="jxr_keyword">if</strong> (c >= 0xD800 && c <= 0xDBFF) {
+<a class="jxr_linenumber" name="L7667" href="#L7667">7667</a> <strong class="jxr_keyword">if</strong> ((i + 1) < s.length()) { <em class="jxr_comment">// NOSONAR - Intentional.</em>
+<a class="jxr_linenumber" name="L7668" href="#L7668">7668</a> <strong class="jxr_keyword">int</strong> d = s.charAt(i + 1);
+<a class="jxr_linenumber" name="L7669" href="#L7669">7669</a> <strong class="jxr_keyword">if</strong> (d >= 0xDC00 && d <= 0xDFFF) {
+<a class="jxr_linenumber" name="L7670" href="#L7670">7670</a> caw.write(d);
+<a class="jxr_linenumber" name="L7671" href="#L7671">7671</a> i++; <em class="jxr_comment">// NOSONAR - Intentional.</em>
+<a class="jxr_linenumber" name="L7672" href="#L7672">7672</a> }
+<a class="jxr_linenumber" name="L7673" href="#L7673">7673</a> }
+<a class="jxr_linenumber" name="L7674" href="#L7674">7674</a> }
+<a class="jxr_linenumber" name="L7675" href="#L7675">7675</a> i++; <em class="jxr_comment">// NOSONAR - Intentional.</em>
+<a class="jxr_linenumber" name="L7676" href="#L7676">7676</a> } <strong class="jxr_keyword">while</strong> (i < s.length() && ! URL_ENCODE_PATHINFO_VALIDCHARS.contains((c = s.charAt(i)))); <em class="jxr_comment">// NOSONAR - Intentional.</em>
+<a class="jxr_linenumber" name="L7677" href="#L7677">7677</a>
+<a class="jxr_linenumber" name="L7678" href="#L7678">7678</a> caw.flush();
+<a class="jxr_linenumber" name="L7679" href="#L7679">7679</a> <strong class="jxr_keyword">var</strong> s2 = <strong class="jxr_keyword">new</strong> String(caw.toCharArray());
+<a class="jxr_linenumber" name="L7680" href="#L7680">7680</a> <strong class="jxr_keyword">var</strong> ba = s2.getBytes(UTF8);
+<a class="jxr_linenumber" name="L7681" href="#L7681">7681</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> element : ba) {
+<a class="jxr_linenumber" name="L7682" href="#L7682">7682</a> sb.append('%');
+<a class="jxr_linenumber" name="L7683" href="#L7683">7683</a> <strong class="jxr_keyword">var</strong> ch = forDigit((element >> 4) & 0xF, 16);
+<a class="jxr_linenumber" name="L7684" href="#L7684">7684</a> <strong class="jxr_keyword">if</strong> (isLetter(ch)) {
+<a class="jxr_linenumber" name="L7685" href="#L7685">7685</a> ch -= caseDiff;
+<a class="jxr_linenumber" name="L7686" href="#L7686">7686</a> }
+<a class="jxr_linenumber" name="L7687" href="#L7687">7687</a> sb.append(ch);
+<a class="jxr_linenumber" name="L7688" href="#L7688">7688</a> ch = forDigit(element & 0xF, 16);
+<a class="jxr_linenumber" name="L7689" href="#L7689">7689</a> <strong class="jxr_keyword">if</strong> (isLetter(ch)) {
+<a class="jxr_linenumber" name="L7690" href="#L7690">7690</a> ch -= caseDiff;
+<a class="jxr_linenumber" name="L7691" href="#L7691">7691</a> }
+<a class="jxr_linenumber" name="L7692" href="#L7692">7692</a> sb.append(ch);
+<a class="jxr_linenumber" name="L7693" href="#L7693">7693</a> }
+<a class="jxr_linenumber" name="L7694" href="#L7694">7694</a> caw.reset();
+<a class="jxr_linenumber" name="L7695" href="#L7695">7695</a> }
+<a class="jxr_linenumber" name="L7696" href="#L7696">7696</a> }
+<a class="jxr_linenumber" name="L7697" href="#L7697">7697</a> }
+<a class="jxr_linenumber" name="L7698" href="#L7698">7698</a> <strong class="jxr_keyword">return</strong> sb.toString();
+<a class="jxr_linenumber" name="L7699" href="#L7699">7699</a> }
+<a class="jxr_linenumber" name="L7700" href="#L7700">7700</a>
+<a class="jxr_linenumber" name="L7701" href="#L7701">7701</a> <em class="jxr_javadoccomment">/**</em>
+<a class="jxr_linenumber" name="L7702" href="#L7702">7702</a> <em class="jxr_javadoccomment"> * Counts the number of words in a string.</em>
+<a class="jxr_linenumber" name="L7703" href="#L7703">7703</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7704" href="#L7704">7704</a> <em class="jxr_javadoccomment"> * <p></em>
+<a class="jxr_linenumber" name="L7705" href="#L7705">7705</a> <em class="jxr_javadoccomment"> * A word is defined as a sequence of one or more word characters (letters, digits, underscores)</em>
+<a class="jxr_linenumber" name="L7706" href="#L7706">7706</a> <em class="jxr_javadoccomment"> * separated by non-word characters.</em>
+<a class="jxr_linenumber" name="L7707" href="#L7707">7707</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7708" href="#L7708">7708</a> <em class="jxr_javadoccomment"> * <h5 class='section'>Example:</h5></em>
+<a class="jxr_linenumber" name="L7709" href="#L7709">7709</a> <em class="jxr_javadoccomment"> * <p class='bjava'></em>
+<a class="jxr_linenumber" name="L7710" href="#L7710">7710</a> <em class="jxr_javadoccomment"> * wordCount(<js>"Hello world"</js>); <jc>// 2</jc></em>
+<a class="jxr_linenumber" name="L7711" href="#L7711">7711</a> <em class="jxr_javadoccomment"> * wordCount(<js>"The quick brown fox"</js>); <jc>// 4</jc></em>
+<a class="jxr_linenumber" name="L7712" href="#L7712">7712</a> <em class="jxr_javadoccomment"> * wordCount(<js>"Hello, world! How are you?"</js>); <jc>// 5</jc></em>
+<a class="jxr_linenumber" name="L7713" href="#L7713">7713</a> <em class="jxr_javadoccomment"> * </p></em>
+<a class="jxr_linenumber" name="L7714" href="#L7714">7714</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7715" href="#L7715">7715</a> <em class="jxr_javadoccomment"> * @param str The string to count words in. Can be <jk>null</jk>.</em>
+<a class="jxr_linenumber" name="L7716" href="#L7716">7716</a> <em class="jxr_javadoccomment"> * @return The number of words, or <c>0</c> if the string is <jk>null</jk> or empty.</em>
+<a class="jxr_linenumber" name="L7717" href="#L7717">7717</a> <em class="jxr_javadoccomment"> */</em>
+<a class="jxr_linenumber" name="L7718" href="#L7718">7718</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> <strong class="jxr_keyword">int</strong> wordCount(String str) {
+<a class="jxr_linenumber" name="L7719" href="#L7719">7719</a> <strong class="jxr_keyword">if</strong> (isEmpty(str))
+<a class="jxr_linenumber" name="L7720" href="#L7720">7720</a> <strong class="jxr_keyword">return</strong> 0;
+<a class="jxr_linenumber" name="L7721" href="#L7721">7721</a>
+<a class="jxr_linenumber" name="L7722" href="#L7722">7722</a> <strong class="jxr_keyword">var</strong> count = 0;
+<a class="jxr_linenumber" name="L7723" href="#L7723">7723</a> <strong class="jxr_keyword">var</strong> inWord = false;
<a class="jxr_linenumber" name="L7724" href="#L7724">7724</a>
-<a class="jxr_linenumber" name="L7725" href="#L7725">7725</a> <strong class="jxr_keyword">var</strong> count = 0;
-<a class="jxr_linenumber" name="L7726" href="#L7726">7726</a> <strong class="jxr_keyword">var</strong> inWord = false;
-<a class="jxr_linenumber" name="L7727" href="#L7727">7727</a>
-<a class="jxr_linenumber" name="L7728" href="#L7728">7728</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> i = 0; i < str.length(); i++) {
-<a class="jxr_linenumber" name="L7729" href="#L7729">7729</a> <strong class="jxr_keyword">var</strong> c = str.charAt(i);
-<a class="jxr_linenumber" name="L7730" href="#L7730">7730</a> <strong class="jxr_keyword">if</strong> ((LETTER.contains(c) || DIGIT.contains(c)) || c == '_') {
-<a class="jxr_linenumber" name="L7731" href="#L7731">7731</a> <strong class="jxr_keyword">if</strong> (! inWord) {
-<a class="jxr_linenumber" name="L7732" href="#L7732">7732</a> count++;
-<a class="jxr_linenumber" name="L7733" href="#L7733">7733</a> inWord = <strong class="jxr_keyword">true</strong>;
-<a class="jxr_linenumber" name="L7734" href="#L7734">7734</a> }
-<a class="jxr_linenumber" name="L7735" href="#L7735">7735</a> } <strong class="jxr_keyword">else</strong> {
-<a class="jxr_linenumber" name="L7736" href="#L7736">7736</a> inWord = false;
-<a class="jxr_linenumber" name="L7737" href="#L7737">7737</a> }
-<a class="jxr_linenumber" name="L7738" href="#L7738">7738</a> }
+<a class="jxr_linenumber" name="L7725" href="#L7725">7725</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> i = 0; i < str.length(); i++) {
+<a class="jxr_linenumber" name="L7726" href="#L7726">7726</a> <strong class="jxr_keyword">var</strong> c = str.charAt(i);
+<a class="jxr_linenumber" name="L7727" href="#L7727">7727</a> <strong class="jxr_keyword">if</strong> ((LETTER.contains(c) || DIGIT.contains(c)) || c == '_') {
+<a class="jxr_linenumber" name="L7728" href="#L7728">7728</a> <strong class="jxr_keyword">if</strong> (! inWord) {
+<a class="jxr_linenumber" name="L7729" href="#L7729">7729</a> count++;
+<a class="jxr_linenumber" name="L7730" href="#L7730">7730</a> inWord = <strong class="jxr_keyword">true</strong>;
+<a class="jxr_linenumber" name="L7731" href="#L7731">7731</a> }
+<a class="jxr_linenumber" name="L7732" href="#L7732">7732</a> } <strong class="jxr_keyword">else</strong> {
+<a class="jxr_linenumber" name="L7733" href="#L7733">7733</a> inWord = false;
+<a class="jxr_linenumber" name="L7734" href="#L7734">7734</a> }
+<a class="jxr_linenumber" name="L7735" href="#L7735">7735</a> }
+<a class="jxr_linenumber" name="L7736" href="#L7736">7736</a>
+<a class="jxr_linenumber" name="L7737" href="#L7737">7737</a> <strong class="jxr_keyword">return</strong> count;
+<a class="jxr_linenumber" name="L7738" href="#L7738">7738</a> }
<a class="jxr_linenumber" name="L7739" href="#L7739">7739</a>
-<a class="jxr_linenumber" name="L7740" href="#L7740">7740</a> <strong class="jxr_keyword">return</strong> count;
-<a class="jxr_linenumber" name="L7741" href="#L7741">7741</a> }
-<a class="jxr_linenumber" name="L7742" href="#L7742">7742</a>
-<a class="jxr_linenumber" name="L7743" href="#L7743">7743</a> <em class="jxr_javadoccomment">/**</em>
-<a class="jxr_linenumber" name="L7744" href="#L7744">7744</a> <em class="jxr_javadoccomment"> * Wraps text to a specified line length.</em>
-<a class="jxr_linenumber" name="L7745" href="#L7745">7745</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7746" href="#L7746">7746</a> <em class="jxr_javadoccomment"> * <p></em>
-<a class="jxr_linenumber" name="L7747" href="#L7747">7747</a> <em class="jxr_javadoccomment"> * Wraps text by breaking at word boundaries (spaces). Words longer than the wrap length</em>
-<a class="jxr_linenumber" name="L7748" href="#L7748">7748</a> <em class="jxr_javadoccomment"> * will be broken at the wrap length. Existing newlines are preserved.</em>
-<a class="jxr_linenumber" name="L7749" href="#L7749">7749</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7750" href="#L7750">7750</a> <em class="jxr_javadoccomment"> * <h5 class='section'>Example:</h5></em>
-<a class="jxr_linenumber" name="L7751" href="#L7751">7751</a> <em class="jxr_javadoccomment"> * <p class='bjava'></em>
-<a class="jxr_linenumber" name="L7752" href="#L7752">7752</a> <em class="jxr_javadoccomment"> * wrap(<js>"hello world test"</js>, 10); <jc>// "hello world\ntest"</jc></em>
-<a class="jxr_linenumber" name="L7753" href="#L7753">7753</a> <em class="jxr_javadoccomment"> * wrap(<jk>null</jk>, 10); <jc>// null</jc></em>
-<a class="jxr_linenumber" name="L7754" href="#L7754">7754</a> <em class="jxr_javadoccomment"> * </p></em>
-<a class="jxr_linenumber" name="L7755" href="#L7755">7755</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7756" href="#L7756">7756</a> <em class="jxr_javadoccomment"> * @param str The string to wrap.</em>
-<a class="jxr_linenumber" name="L7757" href="#L7757">7757</a> <em class="jxr_javadoccomment"> * @param wrapLength The maximum line length (must be &gt; 0).</em>
-<a class="jxr_linenumber" name="L7758" href="#L7758">7758</a> <em class="jxr_javadoccomment"> * @return The wrapped string, or <jk>null</jk> if input is <jk>null</jk>.</em>
-<a class="jxr_linenumber" name="L7759" href="#L7759">7759</a> <em class="jxr_javadoccomment"> * @throws IllegalArgumentException if wrapLength is &lt;= 0.</em>
-<a class="jxr_linenumber" name="L7760" href="#L7760">7760</a> <em class="jxr_javadoccomment"> */</em>
-<a class="jxr_linenumber" name="L7761" href="#L7761">7761</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> String wrap(String str, <strong class="jxr_keyword">int</strong> wrapLength) {
-<a class="jxr_linenumber" name="L7762" href="#L7762">7762</a> <strong class="jxr_keyword">return</strong> wrap(str, wrapLength, <span class="jxr_string">"\n"</span>);
-<a class="jxr_linenumber" name="L7763" href="#L7763">7763</a> }
-<a class="jxr_linenumber" name="L7764" href="#L7764">7764</a>
-<a class="jxr_linenumber" name="L7765" href="#L7765">7765</a> <em class="jxr_javadoccomment">/**</em>
-<a class="jxr_linenumber" name="L7766" href="#L7766">7766</a> <em class="jxr_javadoccomment"> * Wraps text to a specified line length with a custom newline string.</em>
-<a class="jxr_linenumber" name="L7767" href="#L7767">7767</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7768" href="#L7768">7768</a> <em class="jxr_javadoccomment"> * <p></em>
-<a class="jxr_linenumber" name="L7769" href="#L7769">7769</a> <em class="jxr_javadoccomment"> * Wraps text by breaking at word boundaries (spaces). Words longer than the wrap length</em>
-<a class="jxr_linenumber" name="L7770" href="#L7770">7770</a> <em class="jxr_javadoccomment"> * will be broken at the wrap length. Existing newlines are preserved.</em>
-<a class="jxr_linenumber" name="L7771" href="#L7771">7771</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7772" href="#L7772">7772</a> <em class="jxr_javadoccomment"> * <h5 class='section'>Example:</h5></em>
-<a class="jxr_linenumber" name="L7773" href="#L7773">7773</a> <em class="jxr_javadoccomment"> * <p class='bjava'></em>
-<a class="jxr_linenumber" name="L7774" href="#L7774">7774</a> <em class="jxr_javadoccomment"> * wrap(<js>"hello world test"</js>, 10, <js>"<br>"</js>); <jc>// "hello world<br>test"</jc></em>
-<a class="jxr_linenumber" name="L7775" href="#L7775">7775</a> <em class="jxr_javadoccomment"> * wrap(<jk>null</jk>, 10, <js>"\n"</js>); <jc>// null</jc></em>
-<a class="jxr_linenumber" name="L7776" href="#L7776">7776</a> <em class="jxr_javadoccomment"> * </p></em>
-<a class="jxr_linenumber" name="L7777" href="#L7777">7777</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7778" href="#L7778">7778</a> <em class="jxr_javadoccomment"> * @param str The string to wrap.</em>
-<a class="jxr_linenumber" name="L7779" href="#L7779">7779</a> <em class="jxr_javadoccomment"> * @param wrapLength The maximum line length (must be &gt; 0).</em>
-<a class="jxr_linenumber" name="L7780" href="#L7780">7780</a> <em class="jxr_javadoccomment"> * @param newline The string to use as line separator.</em>
-<a class="jxr_linenumber" name="L7781" href="#L7781">7781</a> <em class="jxr_javadoccomment"> * @return The wrapped string, or <jk>null</jk> if input is <jk>null</jk>.</em>
-<a class="jxr_linenumber" name="L7782" href="#L7782">7782</a> <em class="jxr_javadoccomment"> * @throws IllegalArgumentException if wrapLength is &lt;= 0 or newline is <jk>null</jk>.</em>
-<a class="jxr_linenumber" name="L7783" href="#L7783">7783</a> <em class="jxr_javadoccomment"> */</em>
-<a class="jxr_linenumber" name="L7784" href="#L7784">7784</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> String wrap(String str, <strong class="jxr_keyword">int</strong> wrapLength, String newline) {
-<a class="jxr_linenumber" name="L7785" href="#L7785">7785</a> <strong class="jxr_keyword">if</strong> (str == <strong class="jxr_keyword">null</strong>)
-<a class="jxr_linenumber" name="L7786" href="#L7786">7786</a> <strong class="jxr_keyword">return</strong> <strong class="jxr_keyword">null</strong>;
-<a class="jxr_linenumber" name="L7787" href="#L7787">7787</a> <strong class="jxr_keyword">if</strong> (isEmpty(str))
-<a class="jxr_linenumber" name="L7788" href="#L7788">7788</a> <strong class="jxr_keyword">return</strong> str;
-<a class="jxr_linenumber" name="L7789" href="#L7789">7789</a> <strong class="jxr_keyword">if</strong> (wrapLength <= 0)
-<a class="jxr_linenumber" name="L7790" href="#L7790">7790</a> <strong class="jxr_keyword">throw</strong> illegalArg(<span class="jxr_string">"wrapLength must be > 0: {0}"</span>, wrapLength);
-<a class="jxr_linenumber" name="L7791" href="#L7791">7791</a> <strong class="jxr_keyword">if</strong> (newline == <strong class="jxr_keyword">null</strong>)
-<a class="jxr_linenumber" name="L7792" href="#L7792">7792</a> <strong class="jxr_keyword">throw</strong> illegalArg(<span class="jxr_string">"newline cannot be null"</span>);
+<a class="jxr_linenumber" name="L7740" href="#L7740">7740</a> <em class="jxr_javadoccomment">/**</em>
+<a class="jxr_linenumber" name="L7741" href="#L7741">7741</a> <em class="jxr_javadoccomment"> * Wraps text to a specified line length.</em>
+<a class="jxr_linenumber" name="L7742" href="#L7742">7742</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7743" href="#L7743">7743</a> <em class="jxr_javadoccomment"> * <p></em>
+<a class="jxr_linenumber" name="L7744" href="#L7744">7744</a> <em class="jxr_javadoccomment"> * Wraps text by breaking at word boundaries (spaces). Words longer than the wrap length</em>
+<a class="jxr_linenumber" name="L7745" href="#L7745">7745</a> <em class="jxr_javadoccomment"> * will be broken at the wrap length. Existing newlines are preserved.</em>
+<a class="jxr_linenumber" name="L7746" href="#L7746">7746</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7747" href="#L7747">7747</a> <em class="jxr_javadoccomment"> * <h5 class='section'>Example:</h5></em>
+<a class="jxr_linenumber" name="L7748" href="#L7748">7748</a> <em class="jxr_javadoccomment"> * <p class='bjava'></em>
+<a class="jxr_linenumber" name="L7749" href="#L7749">7749</a> <em class="jxr_javadoccomment"> * wrap(<js>"hello world test"</js>, 10); <jc>// "hello world\ntest"</jc></em>
+<a class="jxr_linenumber" name="L7750" href="#L7750">7750</a> <em class="jxr_javadoccomment"> * wrap(<jk>null</jk>, 10); <jc>// null</jc></em>
+<a class="jxr_linenumber" name="L7751" href="#L7751">7751</a> <em class="jxr_javadoccomment"> * </p></em>
+<a class="jxr_linenumber" name="L7752" href="#L7752">7752</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7753" href="#L7753">7753</a> <em class="jxr_javadoccomment"> * @param str The string to wrap.</em>
+<a class="jxr_linenumber" name="L7754" href="#L7754">7754</a> <em class="jxr_javadoccomment"> * @param wrapLength The maximum line length (must be &gt; 0).</em>
+<a class="jxr_linenumber" name="L7755" href="#L7755">7755</a> <em class="jxr_javadoccomment"> * @return The wrapped string, or <jk>null</jk> if input is <jk>null</jk>.</em>
+<a class="jxr_linenumber" name="L7756" href="#L7756">7756</a> <em class="jxr_javadoccomment"> * @throws IllegalArgumentException if wrapLength is &lt;= 0.</em>
+<a class="jxr_linenumber" name="L7757" href="#L7757">7757</a> <em class="jxr_javadoccomment"> */</em>
+<a class="jxr_linenumber" name="L7758" href="#L7758">7758</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> String wrap(String str, <strong class="jxr_keyword">int</strong> wrapLength) {
+<a class="jxr_linenumber" name="L7759" href="#L7759">7759</a> <strong class="jxr_keyword">return</strong> wrap(str, wrapLength, <span class="jxr_string">"\n"</span>);
+<a class="jxr_linenumber" name="L7760" href="#L7760">7760</a> }
+<a class="jxr_linenumber" name="L7761" href="#L7761">7761</a>
+<a class="jxr_linenumber" name="L7762" href="#L7762">7762</a> <em class="jxr_javadoccomment">/**</em>
+<a class="jxr_linenumber" name="L7763" href="#L7763">7763</a> <em class="jxr_javadoccomment"> * Wraps text to a specified line length with a custom newline string.</em>
+<a class="jxr_linenumber" name="L7764" href="#L7764">7764</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7765" href="#L7765">7765</a> <em class="jxr_javadoccomment"> * <p></em>
+<a class="jxr_linenumber" name="L7766" href="#L7766">7766</a> <em class="jxr_javadoccomment"> * Wraps text by breaking at word boundaries (spaces). Words longer than the wrap length</em>
+<a class="jxr_linenumber" name="L7767" href="#L7767">7767</a> <em class="jxr_javadoccomment"> * will be broken at the wrap length. Existing newlines are preserved.</em>
+<a class="jxr_linenumber" name="L7768" href="#L7768">7768</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7769" href="#L7769">7769</a> <em class="jxr_javadoccomment"> * <h5 class='section'>Example:</h5></em>
+<a class="jxr_linenumber" name="L7770" href="#L7770">7770</a> <em class="jxr_javadoccomment"> * <p class='bjava'></em>
+<a class="jxr_linenumber" name="L7771" href="#L7771">7771</a> <em class="jxr_javadoccomment"> * wrap(<js>"hello world test"</js>, 10, <js>"<br>"</js>); <jc>// "hello world<br>test"</jc></em>
+<a class="jxr_linenumber" name="L7772" href="#L7772">7772</a> <em class="jxr_javadoccomment"> * wrap(<jk>null</jk>, 10, <js>"\n"</js>); <jc>// null</jc></em>
+<a class="jxr_linenumber" name="L7773" href="#L7773">7773</a> <em class="jxr_javadoccomment"> * </p></em>
+<a class="jxr_linenumber" name="L7774" href="#L7774">7774</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7775" href="#L7775">7775</a> <em class="jxr_javadoccomment"> * @param str The string to wrap.</em>
+<a class="jxr_linenumber" name="L7776" href="#L7776">7776</a> <em class="jxr_javadoccomment"> * @param wrapLength The maximum line length (must be &gt; 0).</em>
+<a class="jxr_linenumber" name="L7777" href="#L7777">7777</a> <em class="jxr_javadoccomment"> * @param newline The string to use as line separator.</em>
+<a class="jxr_linenumber" name="L7778" href="#L7778">7778</a> <em class="jxr_javadoccomment"> * @return The wrapped string, or <jk>null</jk> if input is <jk>null</jk>.</em>
+<a class="jxr_linenumber" name="L7779" href="#L7779">7779</a> <em class="jxr_javadoccomment"> * @throws IllegalArgumentException if wrapLength is &lt;= 0 or newline is <jk>null</jk>.</em>
+<a class="jxr_linenumber" name="L7780" href="#L7780">7780</a> <em class="jxr_javadoccomment"> */</em>
+<a class="jxr_linenumber" name="L7781" href="#L7781">7781</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> String wrap(String str, <strong class="jxr_keyword">int</strong> wrapLength, String newline) {
+<a class="jxr_linenumber" name="L7782" href="#L7782">7782</a> <strong class="jxr_keyword">if</strong> (str == <strong class="jxr_keyword">null</strong>)
+<a class="jxr_linenumber" name="L7783" href="#L7783">7783</a> <strong class="jxr_keyword">return</strong> <strong class="jxr_keyword">null</strong>;
+<a class="jxr_linenumber" name="L7784" href="#L7784">7784</a> <strong class="jxr_keyword">if</strong> (isEmpty(str))
+<a class="jxr_linenumber" name="L7785" href="#L7785">7785</a> <strong class="jxr_keyword">return</strong> str;
+<a class="jxr_linenumber" name="L7786" href="#L7786">7786</a> <strong class="jxr_keyword">if</strong> (wrapLength <= 0)
+<a class="jxr_linenumber" name="L7787" href="#L7787">7787</a> <strong class="jxr_keyword">throw</strong> illegalArg(<span class="jxr_string">"wrapLength must be > 0: {0}"</span>, wrapLength);
+<a class="jxr_linenumber" name="L7788" href="#L7788">7788</a> <strong class="jxr_keyword">if</strong> (newline == <strong class="jxr_keyword">null</strong>)
+<a class="jxr_linenumber" name="L7789" href="#L7789">7789</a> <strong class="jxr_keyword">throw</strong> illegalArg(<span class="jxr_string">"newline cannot be null"</span>);
+<a class="jxr_linenumber" name="L7790" href="#L7790">7790</a>
+<a class="jxr_linenumber" name="L7791" href="#L7791">7791</a> <strong class="jxr_keyword">var</strong> result = <strong class="jxr_keyword">new</strong> StringBuilder();
+<a class="jxr_linenumber" name="L7792" href="#L7792">7792</a> <strong class="jxr_keyword">var</strong> lines = str.split(<span class="jxr_string">"\r?\n"</span>, -1); <em class="jxr_comment">// Preserve empty lines</em>
<a class="jxr_linenumber" name="L7793" href="#L7793">7793</a>
-<a class="jxr_linenumber" name="L7794" href="#L7794">7794</a> <strong class="jxr_keyword">var</strong> result = <strong class="jxr_keyword">new</strong> StringBuilder();
-<a class="jxr_linenumber" name="L7795" href="#L7795">7795</a> <strong class="jxr_keyword">var</strong> lines = str.split(<span class="jxr_string">"\r?\n"</span>, -1); <em class="jxr_comment">// Preserve empty lines</em>
-<a class="jxr_linenumber" name="L7796" href="#L7796">7796</a>
-<a class="jxr_linenumber" name="L7797" href="#L7797">7797</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> lineIdx = 0; lineIdx < lines.length; lineIdx++) {
-<a class="jxr_linenumber" name="L7798" href="#L7798">7798</a> <strong class="jxr_keyword">var</strong> line = lines[lineIdx];
-<a class="jxr_linenumber" name="L7799" href="#L7799">7799</a> <strong class="jxr_keyword">if</strong> (line.isEmpty()) {
-<a class="jxr_linenumber" name="L7800" href="#L7800">7800</a> <strong class="jxr_keyword">if</strong> (lineIdx < lines.length - 1)
-<a class="jxr_linenumber" name="L7801" href="#L7801">7801</a> result.append(newline);
-<a class="jxr_linenumber" name="L7802" href="#L7802">7802</a> <strong class="jxr_keyword">continue</strong>;
-<a class="jxr_linenumber" name="L7803" href="#L7803">7803</a> }
-<a class="jxr_linenumber" name="L7804" href="#L7804">7804</a>
-<a class="jxr_linenumber" name="L7805" href="#L7805">7805</a> <em class="jxr_comment">// Split into words first, then combine words that fit</em>
-<a class="jxr_linenumber" name="L7806" href="#L7806">7806</a> <strong class="jxr_keyword">var</strong> words = line.split(<span class="jxr_string">" +"</span>); <em class="jxr_comment">// Split on one or more spaces</em>
-<a class="jxr_linenumber" name="L7807" href="#L7807">7807</a> <strong class="jxr_keyword">var</strong> currentLine = <strong class="jxr_keyword">new</strong> StringBuilder();
-<a class="jxr_linenumber" name="L7808" href="#L7808">7808</a>
-<a class="jxr_linenumber" name="L7809" href="#L7809">7809</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> word : words) {
-<a class="jxr_linenumber" name="L7810" href="#L7810">7810</a> <strong class="jxr_keyword">if</strong> (word.isEmpty())
-<a class="jxr_linenumber" name="L7811" href="#L7811">7811</a> <strong class="jxr_keyword">continue</strong>;
+<a class="jxr_linenumber" name="L7794" href="#L7794">7794</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> lineIdx = 0; lineIdx < lines.length; lineIdx++) {
+<a class="jxr_linenumber" name="L7795" href="#L7795">7795</a> <strong class="jxr_keyword">var</strong> line = lines[lineIdx];
+<a class="jxr_linenumber" name="L7796" href="#L7796">7796</a> <strong class="jxr_keyword">if</strong> (line.isEmpty()) {
+<a class="jxr_linenumber" name="L7797" href="#L7797">7797</a> <strong class="jxr_keyword">if</strong> (lineIdx < lines.length - 1)
+<a class="jxr_linenumber" name="L7798" href="#L7798">7798</a> result.append(newline);
+<a class="jxr_linenumber" name="L7799" href="#L7799">7799</a> <strong class="jxr_keyword">continue</strong>;
+<a class="jxr_linenumber" name="L7800" href="#L7800">7800</a> }
+<a class="jxr_linenumber" name="L7801" href="#L7801">7801</a>
+<a class="jxr_linenumber" name="L7802" href="#L7802">7802</a> <em class="jxr_comment">// Split into words first, then combine words that fit</em>
+<a class="jxr_linenumber" name="L7803" href="#L7803">7803</a> <strong class="jxr_keyword">var</strong> words = line.split(<span class="jxr_string">" +"</span>); <em class="jxr_comment">// Split on one or more spaces</em>
+<a class="jxr_linenumber" name="L7804" href="#L7804">7804</a> <strong class="jxr_keyword">var</strong> currentLine = <strong class="jxr_keyword">new</strong> StringBuilder();
+<a class="jxr_linenumber" name="L7805" href="#L7805">7805</a>
+<a class="jxr_linenumber" name="L7806" href="#L7806">7806</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> word : words) {
+<a class="jxr_linenumber" name="L7807" href="#L7807">7807</a> <strong class="jxr_keyword">if</strong> (word.isEmpty())
+<a class="jxr_linenumber" name="L7808" href="#L7808">7808</a> <strong class="jxr_keyword">continue</strong>;
+<a class="jxr_linenumber" name="L7809" href="#L7809">7809</a>
+<a class="jxr_linenumber" name="L7810" href="#L7810">7810</a> <strong class="jxr_keyword">var</strong> wordLength = word.length();
+<a class="jxr_linenumber" name="L7811" href="#L7811">7811</a> <strong class="jxr_keyword">var</strong> currentLength = currentLine.length();
<a class="jxr_linenumber" name="L7812" href="#L7812">7812</a>
-<a class="jxr_linenumber" name="L7813" href="#L7813">7813</a> <strong class="jxr_keyword">var</strong> wordLength = word.length();
-<a class="jxr_linenumber" name="L7814" href="#L7814">7814</a> <strong class="jxr_keyword">var</strong> currentLength = currentLine.length();
-<a class="jxr_linenumber" name="L7815" href="#L7815">7815</a>
-<a class="jxr_linenumber" name="L7816" href="#L7816">7816</a> <strong class="jxr_keyword">if</strong> (currentLength == 0) {
-<a class="jxr_linenumber" name="L7817" href="#L7817">7817</a> <em class="jxr_comment">// First word on line</em>
-<a class="jxr_linenumber" name="L7818" href="#L7818">7818</a> <em class="jxr_comment">// Only break single words if there are multiple words in the input</em>
-<a class="jxr_linenumber" name="L7819" href="#L7819">7819</a> <em class="jxr_comment">// (single long words should not be broken for readability)</em>
-<a class="jxr_linenumber" name="L7820" href="#L7820">7820</a> <strong class="jxr_keyword">if</strong> (wordLength > wrapLength && words.length > 1) {
-<a class="jxr_linenumber" name="L7821" href="#L7821">7821</a> <em class="jxr_comment">// Word is too long and there are other words, break it</em>
-<a class="jxr_linenumber" name="L7822" href="#L7822">7822</a> <strong class="jxr_keyword">if</strong> (result.length() > 0)
-<a class="jxr_linenumber" name="L7823" href="#L7823">7823</a> result.append(newline);
-<a class="jxr_linenumber" name="L7824" href="#L7824">7824</a> <strong class="jxr_keyword">var</strong> wordPos = 0;
-<a class="jxr_linenumber" name="L7825" href="#L7825">7825</a> <strong class="jxr_keyword">while</strong> (wordPos < wordLength) {
-<a class="jxr_linenumber" name="L7826" href="#L7826">7826</a> <strong class="jxr_keyword">if</strong> (wordPos > 0)
-<a class="jxr_linenumber" name="L7827" href="#L7827">7827</a> result.append(newline);
-<a class="jxr_linenumber" name="L7828" href="#L7828">7828</a> <strong class="jxr_keyword">var</strong> remaining = wordLength - wordPos;
-<a class="jxr_linenumber" name="L7829" href="#L7829">7829</a> <strong class="jxr_keyword">if</strong> (remaining <= wrapLength) {
-<a class="jxr_linenumber" name="L7830" href="#L7830">7830</a> result.append(word.substring(wordPos));
-<a class="jxr_linenumber" name="L7831" href="#L7831">7831</a> <strong class="jxr_keyword">break</strong>;
-<a class="jxr_linenumber" name="L7832" href="#L7832">7832</a> }
-<a class="jxr_linenumber" name="L7833" href="#L7833">7833</a> result.append(word.substring(wordPos, wordPos + wrapLength));
-<a class="jxr_linenumber" name="L7834" href="#L7834">7834</a> wordPos += wrapLength;
-<a class="jxr_linenumber" name="L7835" href="#L7835">7835</a> }
-<a class="jxr_linenumber" name="L7836" href="#L7836">7836</a> } <strong class="jxr_keyword">else</strong> {
-<a class="jxr_linenumber" name="L7837" href="#L7837">7837</a> currentLine.append(word);
-<a class="jxr_linenumber" name="L7838" href="#L7838">7838</a> }
-<a class="jxr_linenumber" name="L7839" href="#L7839">7839</a> } <strong class="jxr_keyword">else</strong> {
-<a class="jxr_linenumber" name="L7840" href="#L7840">7840</a> <em class="jxr_comment">// Check if we can add this word to current line</em>
-<a class="jxr_linenumber" name="L7841" href="#L7841">7841</a> <strong class="jxr_keyword">var</strong> neededLength = currentLength + 1 + wordLength; <em class="jxr_comment">// current + space + word</em>
-<a class="jxr_linenumber" name="L7842" href="#L7842">7842</a> <em class="jxr_comment">// Break if it would fit exactly or exceed - prefer breaking for readability</em>
-<a class="jxr_linenumber" name="L7843" href="#L7843">7843</a> <strong class="jxr_keyword">if</strong> (neededLength < wrapLength) {
-<a class="jxr_linenumber" name="L7844" href="#L7844">7844</a> <em class="jxr_comment">// Fits with room to spare</em>
-<a class="jxr_linenumber" name="L7845" href="#L7845">7845</a> currentLine.append(' ').append(word);
-<a class="jxr_linenumber" name="L7846" href="#L7846">7846</a> } <strong class="jxr_keyword">else</strong> {
-<a class="jxr_linenumber" name="L7847" href="#L7847">7847</a> <em class="jxr_comment">// Doesn't fit or fits exactly - start new line</em>
-<a class="jxr_linenumber" name="L7848" href="#L7848">7848</a> <strong class="jxr_keyword">if</strong> (result.length() > 0)
-<a class="jxr_linenumber" name="L7849" href="#L7849">7849</a> result.append(newline);
-<a class="jxr_linenumber" name="L7850" href="#L7850">7850</a> result.append(currentLine);
-<a class="jxr_linenumber" name="L7851" href="#L7851">7851</a> currentLine.setLength(0);
-<a class="jxr_linenumber" name="L7852" href="#L7852">7852</a> <strong class="jxr_keyword">if</strong> (wordLength > wrapLength && words.length > 1) {
-<a class="jxr_linenumber" name="L7853" href="#L7853">7853</a> <em class="jxr_comment">// Word is too long and there are other words, break it</em>
-<a class="jxr_linenumber" name="L7854" href="#L7854">7854</a> result.append(newline);
-<a class="jxr_linenumber" name="L7855" href="#L7855">7855</a> <strong class="jxr_keyword">var</strong> wordPos = 0;
-<a class="jxr_linenumber" name="L7856" href="#L7856">7856</a> <strong class="jxr_keyword">while</strong> (wordPos < wordLength) {
-<a class="jxr_linenumber" name="L7857" href="#L7857">7857</a> <strong class="jxr_keyword">if</strong> (wordPos > 0)
-<a class="jxr_linenumber" name="L7858" href="#L7858">7858</a> result.append(newline);
-<a class="jxr_linenumber" name="L7859" href="#L7859">7859</a> <strong class="jxr_keyword">var</strong> remaining = wordLength - wordPos;
-<a class="jxr_linenumber" name="L7860" href="#L7860">7860</a> <strong class="jxr_keyword">if</strong> (remaining <= wrapLength) {
-<a class="jxr_linenumber" name="L7861" href="#L7861">7861</a> result.append(word.substring(wordPos));
-<a class="jxr_linenumber" name="L7862" href="#L7862">7862</a> <strong class="jxr_keyword">break</strong>;
-<a class="jxr_linenumber" name="L7863" href="#L7863">7863</a> }
-<a class="jxr_linenumber" name="L7864" href="#L7864">7864</a> result.append(word.substring(wordPos, wordPos + wrapLength));
-<a class="jxr_linenumber" name="L7865" href="#L7865">7865</a> wordPos += wrapLength;
-<a class="jxr_linenumber" name="L7866" href="#L7866">7866</a> }
-<a class="jxr_linenumber" name="L7867" href="#L7867">7867</a> } <strong class="jxr_keyword">else</strong> {
-<a class="jxr_linenumber" name="L7868" href="#L7868">7868</a> currentLine.append(word);
-<a class="jxr_linenumber" name="L7869" href="#L7869">7869</a> }
-<a class="jxr_linenumber" name="L7870" href="#L7870">7870</a> }
-<a class="jxr_linenumber" name="L7871" href="#L7871">7871</a> }
-<a class="jxr_linenumber" name="L7872" href="#L7872">7872</a> }
-<a class="jxr_linenumber" name="L7873" href="#L7873">7873</a>
-<a class="jxr_linenumber" name="L7874" href="#L7874">7874</a> <em class="jxr_comment">// Append any remaining line</em>
-<a class="jxr_linenumber" name="L7875" href="#L7875">7875</a> <strong class="jxr_keyword">if</strong> (currentLine.length() > 0) {
-<a class="jxr_linenumber" name="L7876" href="#L7876">7876</a> <strong class="jxr_keyword">if</strong> (result.length() > 0)
-<a class="jxr_linenumber" name="L7877" href="#L7877">7877</a> result.append(newline);
-<a class="jxr_linenumber" name="L7878" href="#L7878">7878</a> result.append(currentLine);
-<a class="jxr_linenumber" name="L7879" href="#L7879">7879</a> }
-<a class="jxr_linenumber" name="L7880" href="#L7880">7880</a> }
+<a class="jxr_linenumber" name="L7813" href="#L7813">7813</a> <strong class="jxr_keyword">if</strong> (currentLength == 0) {
+<a class="jxr_linenumber" name="L7814" href="#L7814">7814</a> <em class="jxr_comment">// First word on line</em>
+<a class="jxr_linenumber" name="L7815" href="#L7815">7815</a> <em class="jxr_comment">// Only break single words if there are multiple words in the input</em>
+<a class="jxr_linenumber" name="L7816" href="#L7816">7816</a> <em class="jxr_comment">// (single long words should not be broken for readability)</em>
+<a class="jxr_linenumber" name="L7817" href="#L7817">7817</a> <strong class="jxr_keyword">if</strong> (wordLength > wrapLength && words.length > 1) {
+<a class="jxr_linenumber" name="L7818" href="#L7818">7818</a> <em class="jxr_comment">// Word is too long and there are other words, break it</em>
+<a class="jxr_linenumber" name="L7819" href="#L7819">7819</a> <strong class="jxr_keyword">if</strong> (result.length() > 0)
+<a class="jxr_linenumber" name="L7820" href="#L7820">7820</a> result.append(newline);
+<a class="jxr_linenumber" name="L7821" href="#L7821">7821</a> <strong class="jxr_keyword">var</strong> wordPos = 0;
+<a class="jxr_linenumber" name="L7822" href="#L7822">7822</a> <strong class="jxr_keyword">while</strong> (wordPos < wordLength) {
+<a class="jxr_linenumber" name="L7823" href="#L7823">7823</a> <strong class="jxr_keyword">if</strong> (wordPos > 0)
+<a class="jxr_linenumber" name="L7824" href="#L7824">7824</a> result.append(newline);
+<a class="jxr_linenumber" name="L7825" href="#L7825">7825</a> <strong class="jxr_keyword">var</strong> remaining = wordLength - wordPos;
+<a class="jxr_linenumber" name="L7826" href="#L7826">7826</a> <strong class="jxr_keyword">if</strong> (remaining <= wrapLength) {
+<a class="jxr_linenumber" name="L7827" href="#L7827">7827</a> result.append(word.substring(wordPos));
+<a class="jxr_linenumber" name="L7828" href="#L7828">7828</a> <strong class="jxr_keyword">break</strong>;
+<a class="jxr_linenumber" name="L7829" href="#L7829">7829</a> }
+<a class="jxr_linenumber" name="L7830" href="#L7830">7830</a> result.append(word.substring(wordPos, wordPos + wrapLength));
+<a class="jxr_linenumber" name="L7831" href="#L7831">7831</a> wordPos += wrapLength;
+<a class="jxr_linenumber" name="L7832" href="#L7832">7832</a> }
+<a class="jxr_linenumber" name="L7833" href="#L7833">7833</a> } <strong class="jxr_keyword">else</strong> {
+<a class="jxr_linenumber" name="L7834" href="#L7834">7834</a> currentLine.append(word);
+<a class="jxr_linenumber" name="L7835" href="#L7835">7835</a> }
+<a class="jxr_linenumber" name="L7836" href="#L7836">7836</a> } <strong class="jxr_keyword">else</strong> {
+<a class="jxr_linenumber" name="L7837" href="#L7837">7837</a> <em class="jxr_comment">// Check if we can add this word to current line</em>
+<a class="jxr_linenumber" name="L7838" href="#L7838">7838</a> <strong class="jxr_keyword">var</strong> neededLength = currentLength + 1 + wordLength; <em class="jxr_comment">// current + space + word</em>
+<a class="jxr_linenumber" name="L7839" href="#L7839">7839</a> <em class="jxr_comment">// Break if it would fit exactly or exceed - prefer breaking for readability</em>
+<a class="jxr_linenumber" name="L7840" href="#L7840">7840</a> <strong class="jxr_keyword">if</strong> (neededLength < wrapLength) {
+<a class="jxr_linenumber" name="L7841" href="#L7841">7841</a> <em class="jxr_comment">// Fits with room to spare</em>
+<a class="jxr_linenumber" name="L7842" href="#L7842">7842</a> currentLine.append(' ').append(word);
+<a class="jxr_linenumber" name="L7843" href="#L7843">7843</a> } <strong class="jxr_keyword">else</strong> {
+<a class="jxr_linenumber" name="L7844" href="#L7844">7844</a> <em class="jxr_comment">// Doesn't fit or fits exactly - start new line</em>
+<a class="jxr_linenumber" name="L7845" href="#L7845">7845</a> <strong class="jxr_keyword">if</strong> (result.length() > 0)
+<a class="jxr_linenumber" name="L7846" href="#L7846">7846</a> result.append(newline);
+<a class="jxr_linenumber" name="L7847" href="#L7847">7847</a> result.append(currentLine);
+<a class="jxr_linenumber" name="L7848" href="#L7848">7848</a> currentLine.setLength(0);
+<a class="jxr_linenumber" name="L7849" href="#L7849">7849</a> <strong class="jxr_keyword">if</strong> (wordLength > wrapLength && words.length > 1) {
+<a class="jxr_linenumber" name="L7850" href="#L7850">7850</a> <em class="jxr_comment">// Word is too long and there are other words, break it</em>
+<a class="jxr_linenumber" name="L7851" href="#L7851">7851</a> result.append(newline);
+<a class="jxr_linenumber" name="L7852" href="#L7852">7852</a> <strong class="jxr_keyword">var</strong> wordPos = 0;
+<a class="jxr_linenumber" name="L7853" href="#L7853">7853</a> <strong class="jxr_keyword">while</strong> (wordPos < wordLength) {
+<a class="jxr_linenumber" name="L7854" href="#L7854">7854</a> <strong class="jxr_keyword">if</strong> (wordPos > 0)
+<a class="jxr_linenumber" name="L7855" href="#L7855">7855</a> result.append(newline);
+<a class="jxr_linenumber" name="L7856" href="#L7856">7856</a> <strong class="jxr_keyword">var</strong> remaining = wordLength - wordPos;
+<a class="jxr_linenumber" name="L7857" href="#L7857">7857</a> <strong class="jxr_keyword">if</strong> (remaining <= wrapLength) {
+<a class="jxr_linenumber" name="L7858" href="#L7858">7858</a> result.append(word.substring(wordPos));
+<a class="jxr_linenumber" name="L7859" href="#L7859">7859</a> <strong class="jxr_keyword">break</strong>;
+<a class="jxr_linenumber" name="L7860" href="#L7860">7860</a> }
+<a class="jxr_linenumber" name="L7861" href="#L7861">7861</a> result.append(word.substring(wordPos, wordPos + wrapLength));
+<a class="jxr_linenumber" name="L7862" href="#L7862">7862</a> wordPos += wrapLength;
+<a class="jxr_linenumber" name="L7863" href="#L7863">7863</a> }
+<a class="jxr_linenumber" name="L7864" href="#L7864">7864</a> } <strong class="jxr_keyword">else</strong> {
+<a class="jxr_linenumber" name="L7865" href="#L7865">7865</a> currentLine.append(word);
+<a class="jxr_linenumber" name="L7866" href="#L7866">7866</a> }
+<a class="jxr_linenumber" name="L7867" href="#L7867">7867</a> }
+<a class="jxr_linenumber" name="L7868" href="#L7868">7868</a> }
+<a class="jxr_linenumber" name="L7869" href="#L7869">7869</a> }
+<a class="jxr_linenumber" name="L7870" href="#L7870">7870</a>
+<a class="jxr_linenumber" name="L7871" href="#L7871">7871</a> <em class="jxr_comment">// Append any remaining line</em>
+<a class="jxr_linenumber" name="L7872" href="#L7872">7872</a> <strong class="jxr_keyword">if</strong> (currentLine.length() > 0) {
+<a class="jxr_linenumber" name="L7873" href="#L7873">7873</a> <strong class="jxr_keyword">if</strong> (result.length() > 0)
+<a class="jxr_linenumber" name="L7874" href="#L7874">7874</a> result.append(newline);
+<a class="jxr_linenumber" name="L7875" href="#L7875">7875</a> result.append(currentLine);
+<a class="jxr_linenumber" name="L7876" href="#L7876">7876</a> }
+<a class="jxr_linenumber" name="L7877" href="#L7877">7877</a> }
+<a class="jxr_linenumber" name="L7878" href="#L7878">7878</a>
+<a class="jxr_linenumber" name="L7879" href="#L7879">7879</a> <strong class="jxr_keyword">return</strong> result.toString();
+<a class="jxr_linenumber" name="L7880" href="#L7880">7880</a> }
<a class="jxr_linenumber" name="L7881" href="#L7881">7881</a>
-<a class="jxr_linenumber" name="L7882" href="#L7882">7882</a> <strong class="jxr_keyword">return</strong> result.toString();
-<a class="jxr_linenumber" name="L7883" href="#L7883">7883</a> }
-<a class="jxr_linenumber" name="L7884" href="#L7884">7884</a>
-<a class="jxr_linenumber" name="L7885" href="#L7885">7885</a> <em class="jxr_javadoccomment">/**</em>
-<a class="jxr_linenumber" name="L7886" href="#L7886">7886</a> <em class="jxr_javadoccomment"> * Helper method to estimate the number of syllables in a word.</em>
-<a class="jxr_linenumber" name="L7887" href="#L7887">7887</a> <em class="jxr_javadoccomment"> */</em>
-<a class="jxr_linenumber" name="L7888" href="#L7888">7888</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">static</strong> <strong class="jxr_keyword">int</strong> estimateSyllables(String word) {
-<a class="jxr_linenumber" name="L7889" href="#L7889">7889</a>
-<a class="jxr_linenumber" name="L7890" href="#L7890">7890</a> <strong class="jxr_keyword">var</strong> lower = word.toLowerCase();
-<a class="jxr_linenumber" name="L7891" href="#L7891">7891</a> <strong class="jxr_keyword">var</strong> count = 0;
-<a class="jxr_linenumber" name="L7892" href="#L7892">7892</a> <strong class="jxr_keyword">var</strong> prevWasVowel = false;
-<a class="jxr_linenumber" name="L7893" href="#L7893">7893</a>
-<a class="jxr_linenumber" name="L7894" href="#L7894">7894</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> i = 0; i < lower.length(); i++) {
-<a class="jxr_linenumber" name="L7895" href="#L7895">7895</a> <strong class="jxr_keyword">var</strong> c = lower.charAt(i);
-<a class="jxr_linenumber" name="L7896" href="#L7896">7896</a> <strong class="jxr_keyword">var</strong> isVowel = (VOWEL.contains(c) || c == 'y');
-<a class="jxr_linenumber" name="L7897" href="#L7897">7897</a>
-<a class="jxr_linenumber" name="L7898" href="#L7898">7898</a> <strong class="jxr_keyword">if</strong> (isVowel && ! prevWasVowel) {
-<a class="jxr_linenumber" name="L7899" href="#L7899">7899</a> count++;
-<a class="jxr_linenumber" name="L7900" href="#L7900">7900</a> }
-<a class="jxr_linenumber" name="L7901" href="#L7901">7901</a> prevWasVowel = isVowel;
-<a class="jxr_linenumber" name="L7902" href="#L7902">7902</a> }
-<a class="jxr_linenumber" name="L7903" href="#L7903">7903</a>
-<a class="jxr_linenumber" name="L7904" href="#L7904">7904</a> <em class="jxr_comment">// Handle silent 'e' at the end</em>
-<a class="jxr_linenumber" name="L7905" href="#L7905">7905</a> <strong class="jxr_keyword">if</strong> (lower.endsWith(<span class="jxr_string">"e"</span>) && count > 1) {
-<a class="jxr_linenumber" name="L7906" href="#L7906">7906</a> count--;
-<a class="jxr_linenumber" name="L7907" href="#L7907">7907</a> }
-<a class="jxr_linenumber" name="L7908" href="#L7908">7908</a>
-<a class="jxr_linenumber" name="L7909" href="#L7909">7909</a> <em class="jxr_comment">// At least one syllable</em>
-<a class="jxr_linenumber" name="L7910" href="#L7910">7910</a> <strong class="jxr_keyword">return</strong> Math.max(1, count);
-<a class="jxr_linenumber" name="L7911" href="#L7911">7911</a> }
-<a class="jxr_linenumber" name="L7912" href="#L7912">7912</a>
-<a class="jxr_linenumber" name="L7913" href="#L7913">7913</a> <em class="jxr_javadoccomment">/**</em>
-<a class="jxr_linenumber" name="L7914" href="#L7914">7914</a> <em class="jxr_javadoccomment"> * Finds the first non-whitespace, non-comment character in a string.</em>
-<a class="jxr_linenumber" name="L7915" href="#L7915">7915</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7916" href="#L7916">7916</a> <em class="jxr_javadoccomment"> * @param s The string to analyze.</em>
-<a class="jxr_linenumber" name="L7917" href="#L7917">7917</a> <em class="jxr_javadoccomment"> * @return The first real character, or <c>-1</c> if none found.</em>
-<a class="jxr_linenumber" name="L7918" href="#L7918">7918</a> <em class="jxr_javadoccomment"> */</em>
-<a class="jxr_linenumber" name="L7919" href="#L7919">7919</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">static</strong> <strong class="jxr_keyword">int</strong> firstRealCharacter(String s) {
-<a class="jxr_linenumber" name="L7920" href="#L7920">7920</a> <strong class="jxr_keyword">return</strong> safe(()-> {
-<a class="jxr_linenumber" name="L7921" href="#L7921">7921</a> <strong class="jxr_keyword">var</strong> r = <strong class="jxr_keyword">new</strong> StringReader(s);
-<a class="jxr_linenumber" name="L7922" href="#L7922">7922</a> <strong class="jxr_keyword">var</strong> c = 0;
-<a class="jxr_linenumber" name="L7923" href="#L7923">7923</a> <strong class="jxr_keyword">while</strong> ((c = r.read()) != -1) {
-<a class="jxr_linenumber" name="L7924" href="#L7924">7924</a> <strong class="jxr_keyword">if</strong> (! isWhitespace(c)) {
-<a class="jxr_linenumber" name="L7925" href="#L7925">7925</a> <strong class="jxr_keyword">if</strong> (c == '/') {
-<a class="jxr_linenumber" name="L7926" href="#L7926">7926</a> skipComments(r);
-<a class="jxr_linenumber" name="L7927" href="#L7927">7927</a> } <strong class="jxr_keyword">else</strong> {
-<a class="jxr_linenumber" name="L7928" href="#L7928">7928</a> <strong class="jxr_keyword">return</strong> c;
-<a class="jxr_linenumber" name="L7929" href="#L7929">7929</a> }
-<a class="jxr_linenumber" name="L7930" href="#L7930">7930</a> }
-<a class="jxr_linenumber" name="L7931" href="#L7931">7931</a> }
-<a class="jxr_linenumber" name="L7932" href="#L7932">7932</a> <strong class="jxr_keyword">return</strong> -1;
-<a class="jxr_linenumber" name="L7933" href="#L7933">7933</a> });
-<a class="jxr_linenumber" name="L7934" href="#L7934">7934</a> }
-<a class="jxr_linenumber" name="L7935" href="#L7935">7935</a>
-<a class="jxr_linenumber" name="L7936" href="#L7936">7936</a> <em class="jxr_javadoccomment">/**</em>
-<a class="jxr_linenumber" name="L7937" href="#L7937">7937</a> <em class="jxr_javadoccomment"> * Helper method to get Soundex code for a character.</em>
-<a class="jxr_linenumber" name="L7938" href="#L7938">7938</a> <em class="jxr_javadoccomment"> */</em>
-<a class="jxr_linenumber" name="L7939" href="#L7939">7939</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">static</strong> <strong class="jxr_keyword">char</strong> getSoundexCode(<strong class="jxr_keyword">char</strong> c) {
-<a class="jxr_linenumber" name="L7940" href="#L7940">7940</a> <strong class="jxr_keyword">if</strong> (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U' || c == 'H' || c == 'W' || c == 'Y')
-<a class="jxr_linenumber" name="L7941" href="#L7941">7941</a> <strong class="jxr_keyword">return</strong> '0';
-<a class="jxr_linenumber" name="L7942" href="#L7942">7942</a> <strong class="jxr_keyword">if</strong> (c == 'B' || c == 'F' || c == 'P' || c == 'V')
-<a class="jxr_linenumber" name="L7943" href="#L7943">7943</a> <strong class="jxr_keyword">return</strong> '1';
-<a class="jxr_linenumber" name="L7944" href="#L7944">7944</a> <strong class="jxr_keyword">if</strong> (c == 'C' || c == 'G' || c == 'J' || c == 'K' || c == 'Q' || c == 'S' || c == 'X' || c == 'Z')
-<a class="jxr_linenumber" name="L7945" href="#L7945">7945</a> <strong class="jxr_keyword">return</strong> '2';
-<a class="jxr_linenumber" name="L7946" href="#L7946">7946</a> <strong class="jxr_keyword">if</strong> (c == 'D' || c == 'T')
-<a class="jxr_linenumber" name="L7947" href="#L7947">7947</a> <strong class="jxr_keyword">return</strong> '3';
-<a class="jxr_linenumber" name="L7948" href="#L7948">7948</a> <strong class="jxr_keyword">if</strong> (c == 'L')
-<a class="jxr_linenumber" name="L7949" href="#L7949">7949</a> <strong class="jxr_keyword">return</strong> '4';
-<a class="jxr_linenumber" name="L7950" href="#L7950">7950</a> <strong class="jxr_keyword">if</strong> (c == 'M' || c == 'N')
-<a class="jxr_linenumber" name="L7951" href="#L7951">7951</a> <strong class="jxr_keyword">return</strong> '5';
-<a class="jxr_linenumber" name="L7952" href="#L7952">7952</a> <strong class="jxr_keyword">if</strong> (c == 'R')
-<a class="jxr_linenumber" name="L7953" href="#L7953">7953</a> <strong class="jxr_keyword">return</strong> '6';
-<a class="jxr_linenumber" name="L7954" href="#L7954">7954</a> <strong class="jxr_keyword">return</strong> '0'; <em class="jxr_comment">// Non-letter characters</em>
-<a class="jxr_linenumber" name="L7955" href="#L7955">7955</a> }
-<a class="jxr_linenumber" name="L7956" href="#L7956">7956</a>
-<a class="jxr_linenumber" name="L7957" href="#L7957">7957</a> <em class="jxr_javadoccomment">/**</em>
-<a class="jxr_linenumber" name="L7958" href="#L7958">7958</a> <em class="jxr_javadoccomment"> * Validates if a string is a valid IPv6 address format (without network operations).</em>
-<a class="jxr_linenumber" name="L7959" href="#L7959">7959</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7960" href="#L7960">7960</a> <em class="jxr_javadoccomment"> * <p></em>
-<a class="jxr_linenumber" name="L7961" href="#L7961">7961</a> <em class="jxr_javadoccomment"> * This method performs pure string-based validation and does not perform any DNS lookups</em>
-<a class="jxr_linenumber" name="L7962" href="#L7962">7962</a> <em class="jxr_javadoccomment"> * or network operations, making it fast and suitable for validation purposes.</em>
-<a class="jxr_linenumber" name="L7963" href="#L7963">7963</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L7964" href="#L7964">7964</a> <em class="jxr_javadoccomment"> * @param ip The IPv6 address string to validate.</em>
-<a class="jxr_linenumber" name="L7965" href="#L7965">7965</a> <em class="jxr_javadoccomment"> * @return <jk>true</jk> if the string is a valid IPv6 address format, <jk>false</jk> otherwise.</em>
-<a class="jxr_linenumber" name="L7966" href="#L7966">7966</a> <em class="jxr_javadoccomment"> */</em>
-<a class="jxr_linenumber" name="L7967" href="#L7967">7967</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> <strong class="jxr_keyword">boolean</strong> isValidIPv6Address(String ip) {
-<a class="jxr_linenumber" name="L7968" href="#L7968">7968</a> <strong class="jxr_keyword">if</strong> (ip == <strong class="jxr_keyword">null</strong> || ip.isEmpty())
-<a class="jxr_linenumber" name="L7969" href="#L7969">7969</a> <strong class="jxr_keyword">return</strong> false;
-<a class="jxr_linenumber" name="L7970" href="#L7970">7970</a>
-<a class="jxr_linenumber" name="L7971" href="#L7971">7971</a> <em class="jxr_comment">// IPv6 addresses can be:</em>
-<a class="jxr_linenumber" name="L7972" href="#L7972">7972</a> <em class="jxr_comment">// 1. Full format: 2001:0db8:85a3:0000:0000:8a2e:0370:7334 (8 groups of 4 hex digits)</em>
-<a class="jxr_linenumber" name="L7973" href="#L7973">7973</a> <em class="jxr_comment">// 2. Compressed format: 2001:db8::1 (uses :: to represent consecutive zeros)</em>
-<a class="jxr_linenumber" name="L7974" href="#L7974">7974</a> <em class="jxr_comment">// 3. IPv4-mapped: ::ffff:192.168.1.1 (last 32 bits as IPv4)</em>
-<a class="jxr_linenumber" name="L7975" href="#L7975">7975</a> <em class="jxr_comment">// 4. Loopback: ::1</em>
-<a class="jxr_linenumber" name="L7976" href="#L7976">7976</a> <em class="jxr_comment">// 5. Unspecified: ::</em>
-<a class="jxr_linenumber" name="L7977" href="#L7977">7977</a>
-<a class="jxr_linenumber" name="L7978" href="#L7978">7978</a> <em class="jxr_comment">// Cannot start or end with a single colon (except ::)</em>
-<a class="jxr_linenumber" name="L7979" href="#L7979">7979</a> <strong class="jxr_keyword">if</strong> (ip.startsWith(<span class="jxr_string">":"</span>) && !ip.startsWith(<span class="jxr_string">"::"</span>))
-<a class="jxr_linenumber" name="L7980" href="#L7980">7980</a> <strong class="jxr_keyword">return</strong> false;
-<a class="jxr_linenumber" name="L7981" href="#L7981">7981</a> <strong class="jxr_keyword">if</strong> (ip.endsWith(<span class="jxr_string">":"</span>) && !ip.endsWith(<span class="jxr_string">"::"</span>))
-<a class="jxr_linenumber" name="L7982" href="#L7982">7982</a> <strong class="jxr_keyword">return</strong> false;
-<a class="jxr_linenumber" name="L7983" href="#L7983">7983</a>
-<a class="jxr_linenumber" name="L7984" href="#L7984">7984</a> <em class="jxr_comment">// Check for IPv4-mapped format (contains both : and .)</em>
-<a class="jxr_linenumber" name="L7985" href="#L7985">7985</a> <strong class="jxr_keyword">if</strong> (ip.contains(<span class="jxr_string">"."</span>)) {
-<a class="jxr_linenumber" name="L7986" href="#L7986">7986</a> <em class="jxr_comment">// Must be in format ::ffff:x.x.x.x or similar</em>
-<a class="jxr_linenumber" name="L7987" href="#L7987">7987</a> <strong class="jxr_keyword">var</strong> lastColon = ip.lastIndexOf(<span class="jxr_string">":"</span>);
-<a class="jxr_linenumber" name="L7988" href="#L7988">7988</a> <strong class="jxr_keyword">if</strong> (lastColon < 0)
-<a class="jxr_linenumber" name="L7989" href="#L7989">7989</a> <strong class="jxr_keyword">return</strong> false;
-<a class="jxr_linenumber" name="L7990" href="#L7990">7990</a> <strong class="jxr_keyword">var</strong> ipv4Part = ip.substring(lastColon + 1);
-<a class="jxr_linenumber" name="L7991" href="#L7991">7991</a> <em class="jxr_comment">// Validate IPv4 part</em>
-<a class="jxr_linenumber" name="L7992" href="#L7992">7992</a> <strong class="jxr_keyword">var</strong> ipv4Parts = ipv4Part.split(<span class="jxr_string">"\\."</span>);
-<a class="jxr_linenumber" name="L7993" href="#L7993">7993</a> <strong class="jxr_keyword">if</strong> (ipv4Parts.length != 4)
-<a class="jxr_linenumber" name="L7994" href="#L7994">7994</a> <strong class="jxr_keyword">return</strong> false;
-<a class="jxr_linenumber" name="L7995" href="#L7995">7995</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> part : ipv4Parts) {
-<a class="jxr_linenumber" name="L7996" href="#L7996">7996</a> <strong class="jxr_keyword">try</strong> {
-<a class="jxr_linenumber" name="L7997" href="#L7997">7997</a> <strong class="jxr_keyword">var</strong> num = Integer.parseInt(part);
-<a class="jxr_linenumber" name="L7998" href="#L7998">7998</a> <strong class="jxr_keyword">if</strong> (num < 0 || num > 255)
-<a class="jxr_linenumber" name="L7999" href="#L7999">7999</a> <strong class="jxr_keyword">return</strong> false;
-<a class="jxr_linenumber" name="L8000" href="#L8000">8000</a> } <strong class="jxr_keyword">catch</strong> (@SuppressWarnings(<span class="jxr_string">"unused"</span>) NumberFormatException e) {
-<a class="jxr_linenumber" name="L8001" href="#L8001">8001</a> <strong class="jxr_keyword">return</strong> false;
-<a class="jxr_linenumber" name="L8002" href="#L8002">8002</a> }
-<a class="jxr_linenumber" name="L8003" href="#L8003">8003</a> }
-<a class="jxr_linenumber" name="L8004" href="#L8004">8004</a> <em class="jxr_comment">// Validate IPv6 part before the IPv4</em>
-<a class="jxr_linenumber" name="L8005" href="#L8005">8005</a> <strong class="jxr_keyword">var</strong> ipv6Part = ip.substring(0, lastColon);
-<a class="jxr_linenumber" name="L8006" href="#L8006">8006</a> <em class="jxr_comment">// Accept empty, ::, ::ffff, ::FFFF, or : (when string starts with ::)</em>
-<a class="jxr_linenumber" name="L8007" href="#L8007">8007</a> <strong class="jxr_keyword">if</strong> (ipv6Part.isEmpty() || ipv6Part.equals(<span class="jxr_string">"::"</span>) || ipv6Part.equals(<span class="jxr_string">"::ffff"</span>) || ipv6Part.equals(<span class="jxr_string">"::FFFF"</span>) || (ipv6Part.equals(<span class="jxr_string">":"</span>) && ip.startsWith(<span class="jxr_string">"::"</span>)))
-<a class="jxr_linenumber" name="L8008" href="#L8008">8008</a> <strong class="jxr_keyword">return</strong> <strong class="jxr_keyword">true</strong>;
-<a class="jxr_linenumber" name="L8009" href="#L8009">8009</a> <em class="jxr_comment">// More complex validation would be needed for other IPv4-mapped formats</em>
-<a class="jxr_linenumber" name="L8010" href="#L8010">8010</a> <em class="jxr_comment">// For now, accept common formats</em>
-<a class="jxr_linenumber" name="L8011" href="#L8011">8011</a> }
-<a class="jxr_linenumber" name="L8012" href="#L8012">8012</a>
-<a class="jxr_linenumber" name="L8013" href="#L8013">8013</a> <em class="jxr_comment">// Check for :: (compression) - only one allowed</em>
-<a class="jxr_linenumber" name="L8014" href="#L8014">8014</a> <strong class="jxr_keyword">var</strong> doubleColonCount = 0;
-<a class="jxr_linenumber" name="L8015" href="#L8015">8015</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> i = 1; i < ip.length(); i++) {
-<a class="jxr_linenumber" name="L8016" href="#L8016">8016</a> <strong class="jxr_keyword">if</strong> (ip.charAt(i) == ':' && ip.charAt(i - 1) == ':') {
-<a class="jxr_linenumber" name="L8017" href="#L8017">8017</a> doubleColonCount++;
-<a class="jxr_linenumber" name="L8018" href="#L8018">8018</a> <strong class="jxr_keyword">if</strong> (doubleColonCount > 1)
-<a class="jxr_linenumber" name="L8019" href="#L8019">8019</a> <strong class="jxr_keyword">return</strong> false; <em class="jxr_comment">// Only one :: allowed</em>
-<a class="jxr_linenumber" name="L8020" href="#L8020">8020</a> }
-<a class="jxr_linenumber" name="L8021" href="#L8021">8021</a> }
+<a class="jxr_linenumber" name="L7882" href="#L7882">7882</a> <em class="jxr_javadoccomment">/**</em>
+<a class="jxr_linenumber" name="L7883" href="#L7883">7883</a> <em class="jxr_javadoccomment"> * Helper method to estimate the number of syllables in a word.</em>
+<a class="jxr_linenumber" name="L7884" href="#L7884">7884</a> <em class="jxr_javadoccomment"> */</em>
+<a class="jxr_linenumber" name="L7885" href="#L7885">7885</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">static</strong> <strong class="jxr_keyword">int</strong> estimateSyllables(String word) {
+<a class="jxr_linenumber" name="L7886" href="#L7886">7886</a>
+<a class="jxr_linenumber" name="L7887" href="#L7887">7887</a> <strong class="jxr_keyword">var</strong> lower = word.toLowerCase();
+<a class="jxr_linenumber" name="L7888" href="#L7888">7888</a> <strong class="jxr_keyword">var</strong> count = 0;
+<a class="jxr_linenumber" name="L7889" href="#L7889">7889</a> <strong class="jxr_keyword">var</strong> prevWasVowel = false;
+<a class="jxr_linenumber" name="L7890" href="#L7890">7890</a>
+<a class="jxr_linenumber" name="L7891" href="#L7891">7891</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> i = 0; i < lower.length(); i++) {
+<a class="jxr_linenumber" name="L7892" href="#L7892">7892</a> <strong class="jxr_keyword">var</strong> c = lower.charAt(i);
+<a class="jxr_linenumber" name="L7893" href="#L7893">7893</a> <strong class="jxr_keyword">var</strong> isVowel = (VOWEL.contains(c) || c == 'y');
+<a class="jxr_linenumber" name="L7894" href="#L7894">7894</a>
+<a class="jxr_linenumber" name="L7895" href="#L7895">7895</a> <strong class="jxr_keyword">if</strong> (isVowel && ! prevWasVowel) {
+<a class="jxr_linenumber" name="L7896" href="#L7896">7896</a> count++;
+<a class="jxr_linenumber" name="L7897" href="#L7897">7897</a> }
+<a class="jxr_linenumber" name="L7898" href="#L7898">7898</a> prevWasVowel = isVowel;
+<a class="jxr_linenumber" name="L7899" href="#L7899">7899</a> }
+<a class="jxr_linenumber" name="L7900" href="#L7900">7900</a>
+<a class="jxr_linenumber" name="L7901" href="#L7901">7901</a> <em class="jxr_comment">// Handle silent 'e' at the end</em>
+<a class="jxr_linenumber" name="L7902" href="#L7902">7902</a> <strong class="jxr_keyword">if</strong> (lower.endsWith(<span class="jxr_string">"e"</span>) && count > 1) {
+<a class="jxr_linenumber" name="L7903" href="#L7903">7903</a> count--;
+<a class="jxr_linenumber" name="L7904" href="#L7904">7904</a> }
+<a class="jxr_linenumber" name="L7905" href="#L7905">7905</a>
+<a class="jxr_linenumber" name="L7906" href="#L7906">7906</a> <em class="jxr_comment">// At least one syllable</em>
+<a class="jxr_linenumber" name="L7907" href="#L7907">7907</a> <strong class="jxr_keyword">return</strong> Math.max(1, count);
+<a class="jxr_linenumber" name="L7908" href="#L7908">7908</a> }
+<a class="jxr_linenumber" name="L7909" href="#L7909">7909</a>
+<a class="jxr_linenumber" name="L7910" href="#L7910">7910</a> <em class="jxr_javadoccomment">/**</em>
+<a class="jxr_linenumber" name="L7911" href="#L7911">7911</a> <em class="jxr_javadoccomment"> * Finds the first non-whitespace, non-comment character in a string.</em>
+<a class="jxr_linenumber" name="L7912" href="#L7912">7912</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7913" href="#L7913">7913</a> <em class="jxr_javadoccomment"> * @param s The string to analyze.</em>
+<a class="jxr_linenumber" name="L7914" href="#L7914">7914</a> <em class="jxr_javadoccomment"> * @return The first real character, or <c>-1</c> if none found.</em>
+<a class="jxr_linenumber" name="L7915" href="#L7915">7915</a> <em class="jxr_javadoccomment"> */</em>
+<a class="jxr_linenumber" name="L7916" href="#L7916">7916</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">static</strong> <strong class="jxr_keyword">int</strong> firstRealCharacter(String s) {
+<a class="jxr_linenumber" name="L7917" href="#L7917">7917</a> <strong class="jxr_keyword">return</strong> safe(()-> {
+<a class="jxr_linenumber" name="L7918" href="#L7918">7918</a> <strong class="jxr_keyword">var</strong> r = <strong class="jxr_keyword">new</strong> StringReader(s);
+<a class="jxr_linenumber" name="L7919" href="#L7919">7919</a> <strong class="jxr_keyword">var</strong> c = 0;
+<a class="jxr_linenumber" name="L7920" href="#L7920">7920</a> <strong class="jxr_keyword">while</strong> ((c = r.read()) != -1) {
+<a class="jxr_linenumber" name="L7921" href="#L7921">7921</a> <strong class="jxr_keyword">if</strong> (! isWhitespace(c)) {
+<a class="jxr_linenumber" name="L7922" href="#L7922">7922</a> <strong class="jxr_keyword">if</strong> (c == '/') {
+<a class="jxr_linenumber" name="L7923" href="#L7923">7923</a> skipComments(r);
+<a class="jxr_linenumber" name="L7924" href="#L7924">7924</a> } <strong class="jxr_keyword">else</strong> {
+<a class="jxr_linenumber" name="L7925" href="#L7925">7925</a> <strong class="jxr_keyword">return</strong> c;
+<a class="jxr_linenumber" name="L7926" href="#L7926">7926</a> }
+<a class="jxr_linenumber" name="L7927" href="#L7927">7927</a> }
+<a class="jxr_linenumber" name="L7928" href="#L7928">7928</a> }
+<a class="jxr_linenumber" name="L7929" href="#L7929">7929</a> <strong class="jxr_keyword">return</strong> -1;
+<a class="jxr_linenumber" name="L7930" href="#L7930">7930</a> });
+<a class="jxr_linenumber" name="L7931" href="#L7931">7931</a> }
+<a class="jxr_linenumber" name="L7932" href="#L7932">7932</a>
+<a class="jxr_linenumber" name="L7933" href="#L7933">7933</a> <em class="jxr_javadoccomment">/**</em>
+<a class="jxr_linenumber" name="L7934" href="#L7934">7934</a> <em class="jxr_javadoccomment"> * Helper method to get Soundex code for a character.</em>
+<a class="jxr_linenumber" name="L7935" href="#L7935">7935</a> <em class="jxr_javadoccomment"> */</em>
+<a class="jxr_linenumber" name="L7936" href="#L7936">7936</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">static</strong> <strong class="jxr_keyword">char</strong> getSoundexCode(<strong class="jxr_keyword">char</strong> c) {
+<a class="jxr_linenumber" name="L7937" href="#L7937">7937</a> <strong class="jxr_keyword">if</strong> (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U' || c == 'H' || c == 'W' || c == 'Y')
+<a class="jxr_linenumber" name="L7938" href="#L7938">7938</a> <strong class="jxr_keyword">return</strong> '0';
+<a class="jxr_linenumber" name="L7939" href="#L7939">7939</a> <strong class="jxr_keyword">if</strong> (c == 'B' || c == 'F' || c == 'P' || c == 'V')
+<a class="jxr_linenumber" name="L7940" href="#L7940">7940</a> <strong class="jxr_keyword">return</strong> '1';
+<a class="jxr_linenumber" name="L7941" href="#L7941">7941</a> <strong class="jxr_keyword">if</strong> (c == 'C' || c == 'G' || c == 'J' || c == 'K' || c == 'Q' || c == 'S' || c == 'X' || c == 'Z')
+<a class="jxr_linenumber" name="L7942" href="#L7942">7942</a> <strong class="jxr_keyword">return</strong> '2';
+<a class="jxr_linenumber" name="L7943" href="#L7943">7943</a> <strong class="jxr_keyword">if</strong> (c == 'D' || c == 'T')
+<a class="jxr_linenumber" name="L7944" href="#L7944">7944</a> <strong class="jxr_keyword">return</strong> '3';
+<a class="jxr_linenumber" name="L7945" href="#L7945">7945</a> <strong class="jxr_keyword">if</strong> (c == 'L')
+<a class="jxr_linenumber" name="L7946" href="#L7946">7946</a> <strong class="jxr_keyword">return</strong> '4';
+<a class="jxr_linenumber" name="L7947" href="#L7947">7947</a> <strong class="jxr_keyword">if</strong> (c == 'M' || c == 'N')
+<a class="jxr_linenumber" name="L7948" href="#L7948">7948</a> <strong class="jxr_keyword">return</strong> '5';
+<a class="jxr_linenumber" name="L7949" href="#L7949">7949</a> <strong class="jxr_keyword">if</strong> (c == 'R')
+<a class="jxr_linenumber" name="L7950" href="#L7950">7950</a> <strong class="jxr_keyword">return</strong> '6';
+<a class="jxr_linenumber" name="L7951" href="#L7951">7951</a> <strong class="jxr_keyword">return</strong> '0'; <em class="jxr_comment">// Non-letter characters</em>
+<a class="jxr_linenumber" name="L7952" href="#L7952">7952</a> }
+<a class="jxr_linenumber" name="L7953" href="#L7953">7953</a>
+<a class="jxr_linenumber" name="L7954" href="#L7954">7954</a> <em class="jxr_javadoccomment">/**</em>
+<a class="jxr_linenumber" name="L7955" href="#L7955">7955</a> <em class="jxr_javadoccomment"> * Validates if a string is a valid IPv6 address format (without network operations).</em>
+<a class="jxr_linenumber" name="L7956" href="#L7956">7956</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7957" href="#L7957">7957</a> <em class="jxr_javadoccomment"> * <p></em>
+<a class="jxr_linenumber" name="L7958" href="#L7958">7958</a> <em class="jxr_javadoccomment"> * This method performs pure string-based validation and does not perform any DNS lookups</em>
+<a class="jxr_linenumber" name="L7959" href="#L7959">7959</a> <em class="jxr_javadoccomment"> * or network operations, making it fast and suitable for validation purposes.</em>
+<a class="jxr_linenumber" name="L7960" href="#L7960">7960</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L7961" href="#L7961">7961</a> <em class="jxr_javadoccomment"> * @param ip The IPv6 address string to validate.</em>
+<a class="jxr_linenumber" name="L7962" href="#L7962">7962</a> <em class="jxr_javadoccomment"> * @return <jk>true</jk> if the string is a valid IPv6 address format, <jk>false</jk> otherwise.</em>
+<a class="jxr_linenumber" name="L7963" href="#L7963">7963</a> <em class="jxr_javadoccomment"> */</em>
+<a class="jxr_linenumber" name="L7964" href="#L7964">7964</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> <strong class="jxr_keyword">boolean</strong> isValidIPv6Address(String ip) {
+<a class="jxr_linenumber" name="L7965" href="#L7965">7965</a> <strong class="jxr_keyword">if</strong> (ip == <strong class="jxr_keyword">null</strong> || ip.isEmpty())
+<a class="jxr_linenumber" name="L7966" href="#L7966">7966</a> <strong class="jxr_keyword">return</strong> false;
+<a class="jxr_linenumber" name="L7967" href="#L7967">7967</a>
+<a class="jxr_linenumber" name="L7968" href="#L7968">7968</a> <em class="jxr_comment">// IPv6 addresses can be:</em>
+<a class="jxr_linenumber" name="L7969" href="#L7969">7969</a> <em class="jxr_comment">// 1. Full format: 2001:0db8:85a3:0000:0000:8a2e:0370:7334 (8 groups of 4 hex digits)</em>
+<a class="jxr_linenumber" name="L7970" href="#L7970">7970</a> <em class="jxr_comment">// 2. Compressed format: 2001:db8::1 (uses :: to represent consecutive zeros)</em>
+<a class="jxr_linenumber" name="L7971" href="#L7971">7971</a> <em class="jxr_comment">// 3. IPv4-mapped: ::ffff:192.168.1.1 (last 32 bits as IPv4)</em>
+<a class="jxr_linenumber" name="L7972" href="#L7972">7972</a> <em class="jxr_comment">// 4. Loopback: ::1</em>
+<a class="jxr_linenumber" name="L7973" href="#L7973">7973</a> <em class="jxr_comment">// 5. Unspecified: ::</em>
+<a class="jxr_linenumber" name="L7974" href="#L7974">7974</a>
+<a class="jxr_linenumber" name="L7975" href="#L7975">7975</a> <em class="jxr_comment">// Cannot start or end with a single colon (except ::)</em>
+<a class="jxr_linenumber" name="L7976" href="#L7976">7976</a> <strong class="jxr_keyword">if</strong> (ip.startsWith(<span class="jxr_string">":"</span>) && !ip.startsWith(<span class="jxr_string">"::"</span>))
+<a class="jxr_linenumber" name="L7977" href="#L7977">7977</a> <strong class="jxr_keyword">return</strong> false;
+<a class="jxr_linenumber" name="L7978" href="#L7978">7978</a> <strong class="jxr_keyword">if</strong> (ip.endsWith(<span class="jxr_string">":"</span>) && !ip.endsWith(<span class="jxr_string">"::"</span>))
+<a class="jxr_linenumber" name="L7979" href="#L7979">7979</a> <strong class="jxr_keyword">return</strong> false;
+<a class="jxr_linenumber" name="L7980" href="#L7980">7980</a>
+<a class="jxr_linenumber" name="L7981" href="#L7981">7981</a> <em class="jxr_comment">// Check for IPv4-mapped format (contains both : and .)</em>
+<a class="jxr_linenumber" name="L7982" href="#L7982">7982</a> <strong class="jxr_keyword">if</strong> (ip.contains(<span class="jxr_string">"."</span>)) {
+<a class="jxr_linenumber" name="L7983" href="#L7983">7983</a> <em class="jxr_comment">// Must be in format ::ffff:x.x.x.x or similar</em>
+<a class="jxr_linenumber" name="L7984" href="#L7984">7984</a> <strong class="jxr_keyword">var</strong> lastColon = ip.lastIndexOf(<span class="jxr_string">":"</span>);
+<a class="jxr_linenumber" name="L7985" href="#L7985">7985</a> <strong class="jxr_keyword">if</strong> (lastColon < 0)
+<a class="jxr_linenumber" name="L7986" href="#L7986">7986</a> <strong class="jxr_keyword">return</strong> false;
+<a class="jxr_linenumber" name="L7987" href="#L7987">7987</a> <strong class="jxr_keyword">var</strong> ipv4Part = ip.substring(lastColon + 1);
+<a class="jxr_linenumber" name="L7988" href="#L7988">7988</a> <em class="jxr_comment">// Validate IPv4 part</em>
+<a class="jxr_linenumber" name="L7989" href="#L7989">7989</a> <strong class="jxr_keyword">var</strong> ipv4Parts = ipv4Part.split(<span class="jxr_string">"\\."</span>);
+<a class="jxr_linenumber" name="L7990" href="#L7990">7990</a> <strong class="jxr_keyword">if</strong> (ipv4Parts.length != 4)
+<a class="jxr_linenumber" name="L7991" href="#L7991">7991</a> <strong class="jxr_keyword">return</strong> false;
+<a class="jxr_linenumber" name="L7992" href="#L7992">7992</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> part : ipv4Parts) {
+<a class="jxr_linenumber" name="L7993" href="#L7993">7993</a> <strong class="jxr_keyword">try</strong> {
+<a class="jxr_linenumber" name="L7994" href="#L7994">7994</a> <strong class="jxr_keyword">var</strong> num = Integer.parseInt(part);
+<a class="jxr_linenumber" name="L7995" href="#L7995">7995</a> <strong class="jxr_keyword">if</strong> (num < 0 || num > 255)
+<a class="jxr_linenumber" name="L7996" href="#L7996">7996</a> <strong class="jxr_keyword">return</strong> false;
+<a class="jxr_linenumber" name="L7997" href="#L7997">7997</a> } <strong class="jxr_keyword">catch</strong> (@SuppressWarnings(<span class="jxr_string">"unused"</span>) NumberFormatException e) {
+<a class="jxr_linenumber" name="L7998" href="#L7998">7998</a> <strong class="jxr_keyword">return</strong> false;
+<a class="jxr_linenumber" name="L7999" href="#L7999">7999</a> }
+<a class="jxr_linenumber" name="L8000" href="#L8000">8000</a> }
+<a class="jxr_linenumber" name="L8001" href="#L8001">8001</a> <em class="jxr_comment">// Validate IPv6 part before the IPv4</em>
+<a class="jxr_linenumber" name="L8002" href="#L8002">8002</a> <strong class="jxr_keyword">var</strong> ipv6Part = ip.substring(0, lastColon);
+<a class="jxr_linenumber" name="L8003" href="#L8003">8003</a> <em class="jxr_comment">// Accept empty, ::, ::ffff, ::FFFF, or : (when string starts with ::)</em>
+<a class="jxr_linenumber" name="L8004" href="#L8004">8004</a> <strong class="jxr_keyword">if</strong> (ipv6Part.isEmpty() || ipv6Part.equals(<span class="jxr_string">"::"</span>) || ipv6Part.equals(<span class="jxr_string">"::ffff"</span>) || ipv6Part.equals(<span class="jxr_string">"::FFFF"</span>) || (ipv6Part.equals(<span class="jxr_string">":"</span>) && ip.startsWith(<span class="jxr_string">"::"</span>)))
+<a class="jxr_linenumber" name="L8005" href="#L8005">8005</a> <strong class="jxr_keyword">return</strong> <strong class="jxr_keyword">true</strong>;
+<a class="jxr_linenumber" name="L8006" href="#L8006">8006</a> <em class="jxr_comment">// More complex validation would be needed for other IPv4-mapped formats</em>
+<a class="jxr_linenumber" name="L8007" href="#L8007">8007</a> <em class="jxr_comment">// For now, accept common formats</em>
+<a class="jxr_linenumber" name="L8008" href="#L8008">8008</a> }
+<a class="jxr_linenumber" name="L8009" href="#L8009">8009</a>
+<a class="jxr_linenumber" name="L8010" href="#L8010">8010</a> <em class="jxr_comment">// Check for :: (compression) - only one allowed</em>
+<a class="jxr_linenumber" name="L8011" href="#L8011">8011</a> <strong class="jxr_keyword">var</strong> doubleColonCount = 0;
+<a class="jxr_linenumber" name="L8012" href="#L8012">8012</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> i = 1; i < ip.length(); i++) {
+<a class="jxr_linenumber" name="L8013" href="#L8013">8013</a> <strong class="jxr_keyword">if</strong> (ip.charAt(i) == ':' && ip.charAt(i - 1) == ':') {
+<a class="jxr_linenumber" name="L8014" href="#L8014">8014</a> doubleColonCount++;
+<a class="jxr_linenumber" name="L8015" href="#L8015">8015</a> <strong class="jxr_keyword">if</strong> (doubleColonCount > 1)
+<a class="jxr_linenumber" name="L8016" href="#L8016">8016</a> <strong class="jxr_keyword">return</strong> false; <em class="jxr_comment">// Only one :: allowed</em>
+<a class="jxr_linenumber" name="L8017" href="#L8017">8017</a> }
+<a class="jxr_linenumber" name="L8018" href="#L8018">8018</a> }
+<a class="jxr_linenumber" name="L8019" href="#L8019">8019</a>
+<a class="jxr_linenumber" name="L8020" href="#L8020">8020</a> <em class="jxr_comment">// Split by ::</em>
+<a class="jxr_linenumber" name="L8021" href="#L8021">8021</a> <strong class="jxr_keyword">var</strong> parts = ip.split(<span class="jxr_string">"::"</span>, -1);
<a class="jxr_linenumber" name="L8022" href="#L8022">8022</a>
-<a class="jxr_linenumber" name="L8023" href="#L8023">8023</a> <em class="jxr_comment">// Split by ::</em>
-<a class="jxr_linenumber" name="L8024" href="#L8024">8024</a> <strong class="jxr_keyword">var</strong> parts = ip.split(<span class="jxr_string">"::"</span>, -1);
-<a class="jxr_linenumber" name="L8025" href="#L8025">8025</a>
-<a class="jxr_linenumber" name="L8026" href="#L8026">8026</a> <strong class="jxr_keyword">if</strong> (parts.length == 2) {
-<a class="jxr_linenumber" name="L8027" href="#L8027">8027</a> <em class="jxr_comment">// Compressed format</em>
-<a class="jxr_linenumber" name="L8028" href="#L8028">8028</a> <strong class="jxr_keyword">var</strong> leftParts = parts[0].isEmpty() ? <strong class="jxr_keyword">new</strong> String[0] : parts[0].split(<span class="jxr_string">":"</span>);
-<a class="jxr_linenumber" name="L8029" href="#L8029">8029</a> <strong class="jxr_keyword">var</strong> rightParts = parts[1].isEmpty() ? <strong class="jxr_keyword">new</strong> String[0] : parts[1].split(<span class="jxr_string">":"</span>);
-<a class="jxr_linenumber" name="L8030" href="#L8030">8030</a> <strong class="jxr_keyword">var</strong> totalParts = leftParts.length + rightParts.length;
-<a class="jxr_linenumber" name="L8031" href="#L8031">8031</a> <strong class="jxr_keyword">if</strong> (totalParts > 7)
-<a class="jxr_linenumber" name="L8032" href="#L8032">8032</a> <strong class="jxr_keyword">return</strong> false; <em class="jxr_comment">// Too many groups (max 8, but :: counts as one or more)</em>
-<a class="jxr_linenumber" name="L8033" href="#L8033">8033</a> } <strong class="jxr_keyword">else</strong> {
-<a class="jxr_linenumber" name="L8034" href="#L8034">8034</a> <em class="jxr_comment">// Full format (no compression)</em>
-<a class="jxr_linenumber" name="L8035" href="#L8035">8035</a> <strong class="jxr_keyword">var</strong> groups = ip.split(<span class="jxr_string">":"</span>);
-<a class="jxr_linenumber" name="L8036" href="#L8036">8036</a> <strong class="jxr_keyword">if</strong> (groups.length != 8)
-<a class="jxr_linenumber" name="L8037" href="#L8037">8037</a> <strong class="jxr_keyword">return</strong> false;
-<a class="jxr_linenumber" name="L8038" href="#L8038">8038</a> }
-<a class="jxr_linenumber" name="L8039" href="#L8039">8039</a>
-<a class="jxr_linenumber" name="L8040" href="#L8040">8040</a> <em class="jxr_comment">// Validate each hex group</em>
-<a class="jxr_linenumber" name="L8041" href="#L8041">8041</a> <strong class="jxr_keyword">var</strong> groups = ip.split(<span class="jxr_string">"::"</span>);
-<a class="jxr_linenumber" name="L8042" href="#L8042">8042</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> groupSection : groups) {
-<a class="jxr_linenumber" name="L8043" href="#L8043">8043</a> <strong class="jxr_keyword">if</strong> (groupSection.isEmpty())
-<a class="jxr_linenumber" name="L8044" href="#L8044">8044</a> <strong class="jxr_keyword">continue</strong>; <em class="jxr_comment">// Skip empty section from ::</em>
-<a class="jxr_linenumber" name="L8045" href="#L8045">8045</a> <strong class="jxr_keyword">var</strong> groupParts = groupSection.split(<span class="jxr_string">":"</span>);
-<a class="jxr_linenumber" name="L8046" href="#L8046">8046</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> group : groupParts) {
-<a class="jxr_linenumber" name="L8047" href="#L8047">8047</a> <strong class="jxr_keyword">if</strong> (group.length() > 4)
-<a class="jxr_linenumber" name="L8048" href="#L8048">8048</a> <strong class="jxr_keyword">return</strong> false; <em class="jxr_comment">// Each group is max 4 hex digits</em>
-<a class="jxr_linenumber" name="L8049" href="#L8049">8049</a> <em class="jxr_comment">// Validate hex digits</em>
-<a class="jxr_linenumber" name="L8050" href="#L8050">8050</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> i = 0; i < group.length(); i++) {
-<a class="jxr_linenumber" name="L8051" href="#L8051">8051</a> <strong class="jxr_keyword">var</strong> c = group.charAt(i);
-<a class="jxr_linenumber" name="L8052" href="#L8052">8052</a> <strong class="jxr_keyword">if</strong> (! HEXADECIMAL_CHARS.contains(c))
-<a class="jxr_linenumber" name="L8053" href="#L8053">8053</a> <strong class="jxr_keyword">return</strong> false;
-<a class="jxr_linenumber" name="L8054" href="#L8054">8054</a> }
-<a class="jxr_linenumber" name="L8055" href="#L8055">8055</a> }
-<a class="jxr_linenumber" name="L8056" href="#L8056">8056</a> }
+<a class="jxr_linenumber" name="L8023" href="#L8023">8023</a> <strong class="jxr_keyword">if</strong> (parts.length == 2) {
+<a class="jxr_linenumber" name="L8024" href="#L8024">8024</a> <em class="jxr_comment">// Compressed format</em>
+<a class="jxr_linenumber" name="L8025" href="#L8025">8025</a> <strong class="jxr_keyword">var</strong> leftParts = parts[0].isEmpty() ? <strong class="jxr_keyword">new</strong> String[0] : parts[0].split(<span class="jxr_string">":"</span>);
+<a class="jxr_linenumber" name="L8026" href="#L8026">8026</a> <strong class="jxr_keyword">var</strong> rightParts = parts[1].isEmpty() ? <strong class="jxr_keyword">new</strong> String[0] : parts[1].split(<span class="jxr_string">":"</span>);
+<a class="jxr_linenumber" name="L8027" href="#L8027">8027</a> <strong class="jxr_keyword">var</strong> totalParts = leftParts.length + rightParts.length;
+<a class="jxr_linenumber" name="L8028" href="#L8028">8028</a> <strong class="jxr_keyword">if</strong> (totalParts > 7)
+<a class="jxr_linenumber" name="L8029" href="#L8029">8029</a> <strong class="jxr_keyword">return</strong> false; <em class="jxr_comment">// Too many groups (max 8, but :: counts as one or more)</em>
+<a class="jxr_linenumber" name="L8030" href="#L8030">8030</a> } <strong class="jxr_keyword">else</strong> {
+<a class="jxr_linenumber" name="L8031" href="#L8031">8031</a> <em class="jxr_comment">// Full format (no compression)</em>
+<a class="jxr_linenumber" name="L8032" href="#L8032">8032</a> <strong class="jxr_keyword">var</strong> groups = ip.split(<span class="jxr_string">":"</span>);
+<a class="jxr_linenumber" name="L8033" href="#L8033">8033</a> <strong class="jxr_keyword">if</strong> (groups.length != 8)
+<a class="jxr_linenumber" name="L8034" href="#L8034">8034</a> <strong class="jxr_keyword">return</strong> false;
+<a class="jxr_linenumber" name="L8035" href="#L8035">8035</a> }
+<a class="jxr_linenumber" name="L8036" href="#L8036">8036</a>
+<a class="jxr_linenumber" name="L8037" href="#L8037">8037</a> <em class="jxr_comment">// Validate each hex group</em>
+<a class="jxr_linenumber" name="L8038" href="#L8038">8038</a> <strong class="jxr_keyword">var</strong> groups = ip.split(<span class="jxr_string">"::"</span>);
+<a class="jxr_linenumber" name="L8039" href="#L8039">8039</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> groupSection : groups) {
+<a class="jxr_linenumber" name="L8040" href="#L8040">8040</a> <strong class="jxr_keyword">if</strong> (groupSection.isEmpty())
+<a class="jxr_linenumber" name="L8041" href="#L8041">8041</a> <strong class="jxr_keyword">continue</strong>; <em class="jxr_comment">// Skip empty section from ::</em>
+<a class="jxr_linenumber" name="L8042" href="#L8042">8042</a> <strong class="jxr_keyword">var</strong> groupParts = groupSection.split(<span class="jxr_string">":"</span>);
+<a class="jxr_linenumber" name="L8043" href="#L8043">8043</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> group : groupParts) {
+<a class="jxr_linenumber" name="L8044" href="#L8044">8044</a> <strong class="jxr_keyword">if</strong> (group.length() > 4)
+<a class="jxr_linenumber" name="L8045" href="#L8045">8045</a> <strong class="jxr_keyword">return</strong> false; <em class="jxr_comment">// Each group is max 4 hex digits</em>
+<a class="jxr_linenumber" name="L8046" href="#L8046">8046</a> <em class="jxr_comment">// Validate hex digits</em>
+<a class="jxr_linenumber" name="L8047" href="#L8047">8047</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> i = 0; i < group.length(); i++) {
+<a class="jxr_linenumber" name="L8048" href="#L8048">8048</a> <strong class="jxr_keyword">var</strong> c = group.charAt(i);
+<a class="jxr_linenumber" name="L8049" href="#L8049">8049</a> <strong class="jxr_keyword">if</strong> (! HEXADECIMAL_CHARS.contains(c))
+<a class="jxr_linenumber" name="L8050" href="#L8050">8050</a> <strong class="jxr_keyword">return</strong> false;
+<a class="jxr_linenumber" name="L8051" href="#L8051">8051</a> }
+<a class="jxr_linenumber" name="L8052" href="#L8052">8052</a> }
+<a class="jxr_linenumber" name="L8053" href="#L8053">8053</a> }
+<a class="jxr_linenumber" name="L8054" href="#L8054">8054</a>
+<a class="jxr_linenumber" name="L8055" href="#L8055">8055</a> <strong class="jxr_keyword">return</strong> <strong class="jxr_keyword">true</strong>;
+<a class="jxr_linenumber" name="L8056" href="#L8056">8056</a> }
<a class="jxr_linenumber" name="L8057" href="#L8057">8057</a>
-<a class="jxr_linenumber" name="L8058" href="#L8058">8058</a> <strong class="jxr_keyword">return</strong> <strong class="jxr_keyword">true</strong>;
-<a class="jxr_linenumber" name="L8059" href="#L8059">8059</a> }
-<a class="jxr_linenumber" name="L8060" href="#L8060">8060</a>
-<a class="jxr_linenumber" name="L8061" href="#L8061">8061</a>
-<a class="jxr_linenumber" name="L8062" href="#L8062">8062</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">static</strong> <strong class="jxr_keyword">class</strong> Readifier {
-<a class="jxr_linenumber" name="L8063" href="#L8063">8063</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">final</strong> Class<?> type;
-<a class="jxr_linenumber" name="L8064" href="#L8064">8064</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">final</strong> Function<Object,String> bridge;
-<a class="jxr_linenumber" name="L8065" href="#L8065">8065</a>
-<a class="jxr_linenumber" name="L8066" href="#L8066">8066</a> <strong class="jxr_keyword">private</strong> <T> Readifier(Class<T> type, Function<? <strong class="jxr_keyword">super</strong> T,String> converter) {
-<a class="jxr_linenumber" name="L8067" href="#L8067">8067</a> <strong class="jxr_keyword">this</strong>.type = type;
-<a class="jxr_linenumber" name="L8068" href="#L8068">8068</a> <strong class="jxr_keyword">this</strong>.bridge = o -> converter.apply(type.<strong class="jxr_keyword">cast</strong>(o));
-<a class="jxr_linenumber" name="L8069" href="#L8069">8069</a> }
-<a class="jxr_linenumber" name="L8070" href="#L8070">8070</a>
-<a class="jxr_linenumber" name="L8071" href="#L8071">8071</a> Class<?> forClass() {
-<a class="jxr_linenumber" name="L8072" href="#L8072">8072</a> <strong class="jxr_keyword">return</strong> type;
-<a class="jxr_linenumber" name="L8073" href="#L8073">8073</a> }
-<a class="jxr_linenumber" name="L8074" href="#L8074">8074</a>
-<a class="jxr_linenumber" name="L8075" href="#L8075">8075</a> Function<Object,String> toFunction() {
-<a class="jxr_linenumber" name="L8076" href="#L8076">8076</a> <strong class="jxr_keyword">return</strong> bridge;
-<a class="jxr_linenumber" name="L8077" href="#L8077">8077</a> }
-<a class="jxr_linenumber" name="L8078" href="#L8078">8078</a> }
-<a class="jxr_linenumber" name="L8079" href="#L8079">8079</a>
-<a class="jxr_linenumber" name="L8080" href="#L8080">8080</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">static</strong> <T> Readifier readifier(Class<T> type, Function<? <strong class="jxr_keyword">super</strong> T,String> converter) {
-<a class="jxr_linenumber" name="L8081" href="#L8081">8081</a> <strong class="jxr_keyword">return</strong> <strong class="jxr_keyword">new</strong> Readifier(type, converter);
-<a class="jxr_linenumber" name="L8082" href="#L8082">8082</a> }
+<a class="jxr_linenumber" name="L8058" href="#L8058">8058</a>
+<a class="jxr_linenumber" name="L8059" href="#L8059">8059</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">static</strong> <strong class="jxr_keyword">class</strong> Readifier {
+<a class="jxr_linenumber" name="L8060" href="#L8060">8060</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">final</strong> Class<?> type;
+<a class="jxr_linenumber" name="L8061" href="#L8061">8061</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">final</strong> Function<Object,String> bridge;
+<a class="jxr_linenumber" name="L8062" href="#L8062">8062</a>
+<a class="jxr_linenumber" name="L8063" href="#L8063">8063</a> <strong class="jxr_keyword">private</strong> <T> Readifier(Class<T> type, Function<? <strong class="jxr_keyword">super</strong> T,String> converter) {
+<a class="jxr_linenumber" name="L8064" href="#L8064">8064</a> <strong class="jxr_keyword">this</strong>.type = type;
+<a class="jxr_linenumber" name="L8065" href="#L8065">8065</a> <strong class="jxr_keyword">this</strong>.bridge = o -> converter.apply(type.<strong class="jxr_keyword">cast</strong>(o));
+<a class="jxr_linenumber" name="L8066" href="#L8066">8066</a> }
+<a class="jxr_linenumber" name="L8067" href="#L8067">8067</a>
+<a class="jxr_linenumber" name="L8068" href="#L8068">8068</a> Class<?> forClass() {
+<a class="jxr_linenumber" name="L8069" href="#L8069">8069</a> <strong class="jxr_keyword">return</strong> type;
+<a class="jxr_linenumber" name="L8070" href="#L8070">8070</a> }
+<a class="jxr_linenumber" name="L8071" href="#L8071">8071</a>
+<a class="jxr_linenumber" name="L8072" href="#L8072">8072</a> Function<Object,String> toFunction() {
+<a class="jxr_linenumber" name="L8073" href="#L8073">8073</a> <strong class="jxr_keyword">return</strong> bridge;
+<a class="jxr_linenumber" name="L8074" href="#L8074">8074</a> }
+<a class="jxr_linenumber" name="L8075" href="#L8075">8075</a> }
+<a class="jxr_linenumber" name="L8076" href="#L8076">8076</a>
+<a class="jxr_linenumber" name="L8077" href="#L8077">8077</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">static</strong> <T> Readifier readifier(Class<T> type, Function<? <strong class="jxr_keyword">super</strong> T,String> converter) {
+<a class="jxr_linenumber" name="L8078" href="#L8078">8078</a> <strong class="jxr_keyword">return</strong> <strong class="jxr_keyword">new</strong> Readifier(type, converter);
+<a class="jxr_linenumber" name="L8079" href="#L8079">8079</a> }
+<a class="jxr_linenumber" name="L8080" href="#L8080">8080</a>
+<a class="jxr_linenumber" name="L8081" href="#L8081">8081</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">static</strong> List<Readifier> loadReadifiers() {
+<a class="jxr_linenumber" name="L8082" href="#L8082">8082</a> <strong class="jxr_keyword">var</strong> list = <strong class="jxr_keyword">new</strong> ArrayList<Readifier>();
<a class="jxr_linenumber" name="L8083" href="#L8083">8083</a>
-<a class="jxr_linenumber" name="L8084" href="#L8084">8084</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">static</strong> List<Readifier> loadReadifiers() {
-<a class="jxr_linenumber" name="L8085" href="#L8085">8085</a> <strong class="jxr_keyword">var</strong> list = <strong class="jxr_keyword">new</strong> ArrayList<Readifier>();
-<a class="jxr_linenumber" name="L8086" href="#L8086">8086</a>
-<a class="jxr_linenumber" name="L8087" href="#L8087">8087</a> <em class="jxr_comment">// More specific types first - order matters!</em>
-<a class="jxr_linenumber" name="L8088" href="#L8088">8088</a> list.add(readifier(Map.Entry.<strong class="jxr_keyword">class</strong>, x -> readable(x.getKey()) + '=' + readable(x.getValue())));
-<a class="jxr_linenumber" name="L8089" href="#L8089">8089</a> list.add(readifier(Collection.<strong class="jxr_keyword">class</strong>, x -> ((Collection<?>)x).stream().map(StringUtils::readable).collect(joining(<span class="jxr_string">","</span>, <span class="jxr_string">"["</span>, <span class="jxr_string">"]"</span>))));
-<a class="jxr_linenumber" name="L8090" href="#L8090">8090</a> list.add(readifier(Map.<strong class="jxr_keyword">class</strong>, x -> ((Map<?,?>)x).entrySet().stream().map(StringUtils::readable).collect(joining(<span class="jxr_string">","</span>, <span class="jxr_string">"{"</span>, <span class="jxr_string">"}"</span>))));
-<a class="jxr_linenumber" name="L8091" href="#L8091">8091</a> list.add(readifier(Iterable.<strong class="jxr_keyword">class</strong>, x -> readable(toList(x))));
-<a class="jxr_linenumber" name="L8092" href="#L8092">8092</a> list.add(readifier(Iterator.<strong class="jxr_keyword">class</strong>, x -> readable(toList(x))));
-<a class="jxr_linenumber" name="L8093" href="#L8093">8093</a> list.add(readifier(Enumeration.<strong class="jxr_keyword">class</strong>, x -> readable(toList(x))));
-<a class="jxr_linenumber" name="L8094" href="#L8094">8094</a> list.add(readifier(Optional.<strong class="jxr_keyword">class</strong>, x -> readable(((Optional<?>)x).orElse(<strong class="jxr_keyword">null</strong>))));
-<a class="jxr_linenumber" name="L8095" href="#L8095">8095</a> list.add(readifier(GregorianCalendar.<strong class="jxr_keyword">class</strong>, x -> x.toZonedDateTime().format(DateTimeFormatter.ISO_INSTANT)));
-<a class="jxr_linenumber" name="L8096" href="#L8096">8096</a> list.add(readifier(Date.<strong class="jxr_keyword">class</strong>, x -> x.toInstant().toString()));
-<a class="jxr_linenumber" name="L8097" href="#L8097">8097</a> list.add(readifier(InputStream.<strong class="jxr_keyword">class</strong>, x -> toHex(x)));
-<a class="jxr_linenumber" name="L8098" href="#L8098">8098</a> list.add(readifier(Reader.<strong class="jxr_keyword">class</strong>, (Reader x) -> safe(() -> read(x))));
-<a class="jxr_linenumber" name="L8099" href="#L8099">8099</a> list.add(readifier(File.<strong class="jxr_keyword">class</strong>, (File x) -> safe(() -> read(x))));
-<a class="jxr_linenumber" name="L8100" href="#L8100">8100</a> list.add(readifier(byte[].<strong class="jxr_keyword">class</strong>, x -> toHex(x)));
-<a class="jxr_linenumber" name="L8101" href="#L8101">8101</a> list.add(readifier(Enum.<strong class="jxr_keyword">class</strong>, x -> ((Enum<?>)x).name()));
-<a class="jxr_linenumber" name="L8102" href="#L8102">8102</a> list.add(readifier(Class.<strong class="jxr_keyword">class</strong>, x -> cns(x)));
-<a class="jxr_linenumber" name="L8103" href="#L8103">8103</a> list.add(readifier(Constructor.<strong class="jxr_keyword">class</strong>, x -> ConstructorInfo.of(x).getFullName()));
-<a class="jxr_linenumber" name="L8104" href="#L8104">8104</a> list.add(readifier(Method.<strong class="jxr_keyword">class</strong>, x -> MethodInfo.of(x).getFullName()));
-<a class="jxr_linenumber" name="L8105" href="#L8105">8105</a> list.add(readifier(Field.<strong class="jxr_keyword">class</strong>, x -> FieldInfo.of(x).toString()));
-<a class="jxr_linenumber" name="L8106" href="#L8106">8106</a> list.add(readifier(Parameter.<strong class="jxr_keyword">class</strong>, x -> ParameterInfo.of(x).toString()));
-<a class="jxr_linenumber" name="L8107" href="#L8107">8107</a> list.add(readifier(ClassInfo.<strong class="jxr_keyword">class</strong>, ClassInfo::toString));
-<a class="jxr_linenumber" name="L8108" href="#L8108">8108</a> list.add(readifier(MethodInfo.<strong class="jxr_keyword">class</strong>, MethodInfo::toString));
-<a class="jxr_linenumber" name="L8109" href="#L8109">8109</a> list.add(readifier(ConstructorInfo.<strong class="jxr_keyword">class</strong>, ConstructorInfo::toString));
-<a class="jxr_linenumber" name="L8110" href="#L8110">8110</a> list.add(readifier(FieldInfo.<strong class="jxr_keyword">class</strong>, FieldInfo::toString));
-<a class="jxr_linenumber" name="L8111" href="#L8111">8111</a> list.add(readifier(ParameterInfo.<strong class="jxr_keyword">class</strong>, ParameterInfo::toString));
+<a class="jxr_linenumber" name="L8084" href="#L8084">8084</a> <em class="jxr_comment">// More specific types first - order matters!</em>
+<a class="jxr_linenumber" name="L8085" href="#L8085">8085</a> list.add(readifier(Map.Entry.<strong class="jxr_keyword">class</strong>, x -> readable(x.getKey()) + '=' + readable(x.getValue())));
+<a class="jxr_linenumber" name="L8086" href="#L8086">8086</a> list.add(readifier(Collection.<strong class="jxr_keyword">class</strong>, x -> ((Collection<?>)x).stream().map(StringUtils::readable).collect(joining(<span class="jxr_string">","</span>, <span class="jxr_string">"["</span>, <span class="jxr_string">"]"</span>))));
+<a class="jxr_linenumber" name="L8087" href="#L8087">8087</a> list.add(readifier(Map.<strong class="jxr_keyword">class</strong>, x -> ((Map<?,?>)x).entrySet().stream().map(StringUtils::readable).collect(joining(<span class="jxr_string">","</span>, <span class="jxr_string">"{"</span>, <span class="jxr_string">"}"</span>))));
+<a class="jxr_linenumber" name="L8088" href="#L8088">8088</a> list.add(readifier(Iterable.<strong class="jxr_keyword">class</strong>, x -> readable(toList(x))));
+<a class="jxr_linenumber" name="L8089" href="#L8089">8089</a> list.add(readifier(Iterator.<strong class="jxr_keyword">class</strong>, x -> readable(toList(x))));
+<a class="jxr_linenumber" name="L8090" href="#L8090">8090</a> list.add(readifier(Enumeration.<strong class="jxr_keyword">class</strong>, x -> readable(toList(x))));
+<a class="jxr_linenumber" name="L8091" href="#L8091">8091</a> list.add(readifier(Optional.<strong class="jxr_keyword">class</strong>, x -> readable(((Optional<?>)x).orElse(<strong class="jxr_keyword">null</strong>))));
+<a class="jxr_linenumber" name="L8092" href="#L8092">8092</a> list.add(readifier(GregorianCalendar.<strong class="jxr_keyword">class</strong>, x -> x.toZonedDateTime().format(DateTimeFormatter.ISO_INSTANT)));
+<a class="jxr_linenumber" name="L8093" href="#L8093">8093</a> list.add(readifier(Date.<strong class="jxr_keyword">class</strong>, x -> x.toInstant().toString()));
+<a class="jxr_linenumber" name="L8094" href="#L8094">8094</a> list.add(readifier(InputStream.<strong class="jxr_keyword">class</strong>, x -> toHex(x)));
+<a class="jxr_linenumber" name="L8095" href="#L8095">8095</a> list.add(readifier(Reader.<strong class="jxr_keyword">class</strong>, (Reader x) -> safe(() -> read(x))));
+<a class="jxr_linenumber" name="L8096" href="#L8096">8096</a> list.add(readifier(File.<strong class="jxr_keyword">class</strong>, (File x) -> safe(() -> read(x))));
+<a class="jxr_linenumber" name="L8097" href="#L8097">8097</a> list.add(readifier(byte[].<strong class="jxr_keyword">class</strong>, x -> toHex(x)));
+<a class="jxr_linenumber" name="L8098" href="#L8098">8098</a> list.add(readifier(Enum.<strong class="jxr_keyword">class</strong>, x -> ((Enum<?>)x).name()));
+<a class="jxr_linenumber" name="L8099" href="#L8099">8099</a> list.add(readifier(Class.<strong class="jxr_keyword">class</strong>, x -> cns(x)));
+<a class="jxr_linenumber" name="L8100" href="#L8100">8100</a> list.add(readifier(Constructor.<strong class="jxr_keyword">class</strong>, x -> ConstructorInfo.of(x).getFullName()));
+<a class="jxr_linenumber" name="L8101" href="#L8101">8101</a> list.add(readifier(Method.<strong class="jxr_keyword">class</strong>, x -> MethodInfo.of(x).getFullName()));
+<a class="jxr_linenumber" name="L8102" href="#L8102">8102</a> list.add(readifier(Field.<strong class="jxr_keyword">class</strong>, x -> FieldInfo.of(x).toString()));
+<a class="jxr_linenumber" name="L8103" href="#L8103">8103</a> list.add(readifier(Parameter.<strong class="jxr_keyword">class</strong>, x -> ParameterInfo.of(x).toString()));
+<a class="jxr_linenumber" name="L8104" href="#L8104">8104</a> list.add(readifier(ClassInfo.<strong class="jxr_keyword">class</strong>, ClassInfo::toString));
+<a class="jxr_linenumber" name="L8105" href="#L8105">8105</a> list.add(readifier(MethodInfo.<strong class="jxr_keyword">class</strong>, MethodInfo::toString));
+<a class="jxr_linenumber" name="L8106" href="#L8106">8106</a> list.add(readifier(ConstructorInfo.<strong class="jxr_keyword">class</strong>, ConstructorInfo::toString));
+<a class="jxr_linenumber" name="L8107" href="#L8107">8107</a> list.add(readifier(FieldInfo.<strong class="jxr_keyword">class</strong>, FieldInfo::toString));
+<a class="jxr_linenumber" name="L8108" href="#L8108">8108</a> list.add(readifier(ParameterInfo.<strong class="jxr_keyword">class</strong>, ParameterInfo::toString));
+<a class="jxr_linenumber" name="L8109" href="#L8109">8109</a>
+<a class="jxr_linenumber" name="L8110" href="#L8110">8110</a> <strong class="jxr_keyword">return</strong> Collections.unmodifiableList(list);
+<a class="jxr_linenumber" name="L8111" href="#L8111">8111</a> }
<a class="jxr_linenumber" name="L8112" href="#L8112">8112</a>
-<a class="jxr_linenumber" name="L8113" href="#L8113">8113</a> <strong class="jxr_keyword">return</strong> Collections.unmodifiableList(list);
-<a class="jxr_linenumber" name="L8114" href="#L8114">8114</a> }
-<a class="jxr_linenumber" name="L8115" href="#L8115">8115</a>
-<a class="jxr_linenumber" name="L8116" href="#L8116">8116</a> <em class="jxr_javadoccomment">/**</em>
-<a class="jxr_linenumber" name="L8117" href="#L8117">8117</a> <em class="jxr_javadoccomment"> * Determines the multiplier value based on the suffix character in a string.</em>
-<a class="jxr_linenumber" name="L8118" href="#L8118">8118</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L8119" href="#L8119">8119</a> <em class="jxr_javadoccomment"> * @param s The string to analyze for multiplier suffix.</em>
-<a class="jxr_linenumber" name="L8120" href="#L8120">8120</a> <em class="jxr_javadoccomment"> * @return The multiplier value (1 if no valid suffix found).</em>
-<a class="jxr_linenumber" name="L8121" href="#L8121">8121</a> <em class="jxr_javadoccomment"> */</em>
-<a class="jxr_linenumber" name="L8122" href="#L8122">8122</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">static</strong> <strong class="jxr_keyword">int</strong> multiplierInt(String s) {
-<a class="jxr_linenumber" name="L8123" href="#L8123">8123</a> <strong class="jxr_keyword">var</strong> c = isEmpty(s) ? 'z' : s.charAt(s.length() - 1);
-<a class="jxr_linenumber" name="L8124" href="#L8124">8124</a> <strong class="jxr_keyword">if</strong> (c == 'G')
-<a class="jxr_linenumber" name="L8125" href="#L8125">8125</a> <strong class="jxr_keyword">return</strong> 1024 * 1024 * 1024;
-<a class="jxr_linenumber" name="L8126" href="#L8126">8126</a> <strong class="jxr_keyword">if</strong> (c == 'M')
-<a class="jxr_linenumber" name="L8127" href="#L8127">8127</a> <strong class="jxr_keyword">return</strong> 1024 * 1024;
-<a class="jxr_linenumber" name="L8128" href="#L8128">8128</a> <strong class="jxr_keyword">if</strong> (c == 'K')
-<a class="jxr_linenumber" name="L8129" href="#L8129">8129</a> <strong class="jxr_keyword">return</strong> 1024;
-<a class="jxr_linenumber" name="L8130" href="#L8130">8130</a> <strong class="jxr_keyword">if</strong> (c == 'g')
-<a class="jxr_linenumber" name="L8131" href="#L8131">8131</a> <strong class="jxr_keyword">return</strong> 1000 * 1000 * 1000;
-<a class="jxr_linenumber" name="L8132" href="#L8132">8132</a> <strong class="jxr_keyword">if</strong> (c == 'm')
-<a class="jxr_linenumber" name="L8133" href="#L8133">8133</a> <strong class="jxr_keyword">return</strong> 1000 * 1000;
-<a class="jxr_linenumber" name="L8134" href="#L8134">8134</a> <strong class="jxr_keyword">if</strong> (c == 'k')
-<a class="jxr_linenumber" name="L8135" href="#L8135">8135</a> <strong class="jxr_keyword">return</strong> 1000;
-<a class="jxr_linenumber" name="L8136" href="#L8136">8136</a> <strong class="jxr_keyword">return</strong> 1;
-<a class="jxr_linenumber" name="L8137" href="#L8137">8137</a> }
-<a class="jxr_linenumber" name="L8138" href="#L8138">8138</a>
-<a class="jxr_linenumber" name="L8139" href="#L8139">8139</a> <em class="jxr_javadoccomment">/**</em>
-<a class="jxr_linenumber" name="L8140" href="#L8140">8140</a> <em class="jxr_javadoccomment"> * Determines the long multiplier value based on the suffix character in a string.</em>
-<a class="jxr_linenumber" name="L8141" href="#L8141">8141</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L8142" href="#L8142">8142</a> <em class="jxr_javadoccomment"> * @param s The string to analyze for multiplier suffix.</em>
-<a class="jxr_linenumber" name="L8143" href="#L8143">8143</a> <em class="jxr_javadoccomment"> * @return The multiplier value (1 if no valid suffix found).</em>
-<a class="jxr_linenumber" name="L8144" href="#L8144">8144</a> <em class="jxr_javadoccomment"> */</em>
-<a class="jxr_linenumber" name="L8145" href="#L8145">8145</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">static</strong> <strong class="jxr_keyword">long</strong> multiplierLong(String s) {
-<a class="jxr_linenumber" name="L8146" href="#L8146">8146</a> <strong class="jxr_keyword">if</strong> (isEmpty(s))
-<a class="jxr_linenumber" name="L8147" href="#L8147">8147</a> <strong class="jxr_keyword">return</strong> 1;
-<a class="jxr_linenumber" name="L8148" href="#L8148">8148</a> <strong class="jxr_keyword">var</strong> c = s.charAt(s.length() - 1);
-<a class="jxr_linenumber" name="L8149" href="#L8149">8149</a> <strong class="jxr_keyword">if</strong> (c == 'P')
-<a class="jxr_linenumber" name="L8150" href="#L8150">8150</a> <strong class="jxr_keyword">return</strong> 1125899906842624L; <em class="jxr_comment">// 1024^5</em>
-<a class="jxr_linenumber" name="L8151" href="#L8151">8151</a> <strong class="jxr_keyword">if</strong> (c == 'T')
-<a class="jxr_linenumber" name="L8152" href="#L8152">8152</a> <strong class="jxr_keyword">return</strong> 1099511627776L; <em class="jxr_comment">// 1024^4</em>
-<a class="jxr_linenumber" name="L8153" href="#L8153">8153</a> <strong class="jxr_keyword">if</strong> (c == 'G')
-<a class="jxr_linenumber" name="L8154" href="#L8154">8154</a> <strong class="jxr_keyword">return</strong> 1073741824L; <em class="jxr_comment">// 1024^3</em>
-<a class="jxr_linenumber" name="L8155" href="#L8155">8155</a> <strong class="jxr_keyword">if</strong> (c == 'M')
-<a class="jxr_linenumber" name="L8156" href="#L8156">8156</a> <strong class="jxr_keyword">return</strong> 1048576L; <em class="jxr_comment">// 1024^2</em>
-<a class="jxr_linenumber" name="L8157" href="#L8157">8157</a> <strong class="jxr_keyword">if</strong> (c == 'K')
-<a class="jxr_linenumber" name="L8158" href="#L8158">8158</a> <strong class="jxr_keyword">return</strong> 1024L;
-<a class="jxr_linenumber" name="L8159" href="#L8159">8159</a> <strong class="jxr_keyword">if</strong> (c == 'p')
-<a class="jxr_linenumber" name="L8160" href="#L8160">8160</a> <strong class="jxr_keyword">return</strong> 1000000000000000L; <em class="jxr_comment">// 1000^5</em>
-<a class="jxr_linenumber" name="L8161" href="#L8161">8161</a> <strong class="jxr_keyword">if</strong> (c == 't')
-<a class="jxr_linenumber" name="L8162" href="#L8162">8162</a> <strong class="jxr_keyword">return</strong> 1000000000000L; <em class="jxr_comment">// 1000^4</em>
-<a class="jxr_linenumber" name="L8163" href="#L8163">8163</a> <strong class="jxr_keyword">if</strong> (c == 'g')
-<a class="jxr_linenumber" name="L8164" href="#L8164">8164</a> <strong class="jxr_keyword">return</strong> 1000000000L; <em class="jxr_comment">// 1000^3</em>
-<a class="jxr_linenumber" name="L8165" href="#L8165">8165</a> <strong class="jxr_keyword">if</strong> (c == 'm')
-<a class="jxr_linenumber" name="L8166" href="#L8166">8166</a> <strong class="jxr_keyword">return</strong> 1000000L; <em class="jxr_comment">// 1000^2</em>
-<a class="jxr_linenumber" name="L8167" href="#L8167">8167</a> <strong class="jxr_keyword">if</strong> (c == 'k')
-<a class="jxr_linenumber" name="L8168" href="#L8168">8168</a> <strong class="jxr_keyword">return</strong> 1000L;
-<a class="jxr_linenumber" name="L8169" href="#L8169">8169</a> <strong class="jxr_keyword">return</strong> 1;
-<a class="jxr_linenumber" name="L8170" href="#L8170">8170</a> }
-<a class="jxr_linenumber" name="L8171" href="#L8171">8171</a>
-<a class="jxr_linenumber" name="L8172" href="#L8172">8172</a> <em class="jxr_javadoccomment">/**</em>
-<a class="jxr_linenumber" name="L8173" href="#L8173">8173</a> <em class="jxr_javadoccomment"> * Parses a unit string and converts the value to milliseconds.</em>
-<a class="jxr_linenumber" name="L8174" href="#L8174">8174</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L8175" href="#L8175">8175</a> <em class="jxr_javadoccomment"> * @param unit The unit string (case-insensitive, already lowercased).</em>
-<a class="jxr_linenumber" name="L8176" href="#L8176">8176</a> <em class="jxr_javadoccomment"> * @param value The numeric value.</em>
-<a class="jxr_linenumber" name="L8177" href="#L8177">8177</a> <em class="jxr_javadoccomment"> * @return The value in milliseconds, or <c>-1</c> if the unit is invalid.</em>
-<a class="jxr_linenumber" name="L8178" href="#L8178">8178</a> <em class="jxr_javadoccomment"> */</em>
-<a class="jxr_linenumber" name="L8179" href="#L8179">8179</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">static</strong> <strong class="jxr_keyword">long</strong> parseUnit(String unit, <strong class="jxr_keyword">double</strong> value) {
-<a class="jxr_linenumber" name="L8180" href="#L8180">8180</a> <strong class="jxr_keyword">if</strong> (isEmpty(unit)) {
-<a class="jxr_linenumber" name="L8181" href="#L8181">8181</a> <em class="jxr_comment">// No unit means milliseconds</em>
-<a class="jxr_linenumber" name="L8182" href="#L8182">8182</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)value;
-<a class="jxr_linenumber" name="L8183" href="#L8183">8183</a> }
-<a class="jxr_linenumber" name="L8184" href="#L8184">8184</a>
-<a class="jxr_linenumber" name="L8185" href="#L8185">8185</a> <em class="jxr_comment">// Check milliseconds first (before minutes) - must check exact "ms" before checking "m"</em>
-<a class="jxr_linenumber" name="L8186" href="#L8186">8186</a> <strong class="jxr_keyword">if</strong> (unit.equals(<span class="jxr_string">"ms"</span>) || unit.equals(<span class="jxr_string">"millis"</span>) || unit.equals(<span class="jxr_string">"milliseconds"</span>))
-<a class="jxr_linenumber" name="L8187" href="#L8187">8187</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)value;
-<a class="jxr_linenumber" name="L8188" href="#L8188">8188</a>
-<a class="jxr_linenumber" name="L8189" href="#L8189">8189</a> <em class="jxr_comment">// Seconds</em>
-<a class="jxr_linenumber" name="L8190" href="#L8190">8190</a> <strong class="jxr_keyword">if</strong> (unit.startsWith(<span class="jxr_string">"s"</span>) && !unit.startsWith(<span class="jxr_string">"sec"</span>))
-<a class="jxr_linenumber" name="L8191" href="#L8191">8191</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)(value * 1000);
-<a class="jxr_linenumber" name="L8192" href="#L8192">8192</a> <strong class="jxr_keyword">if</strong> (unit.startsWith(<span class="jxr_string">"sec"</span>) || unit.startsWith(<span class="jxr_string">"second"</span>))
-<a class="jxr_linenumber" name="L8193" href="#L8193">8193</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)(value * 1000);
-<a class="jxr_linenumber" name="L8194" href="#L8194">8194</a>
-<a class="jxr_linenumber" name="L8195" href="#L8195">8195</a> <em class="jxr_comment">// Minutes (must check after milliseconds and months)</em>
-<a class="jxr_linenumber" name="L8196" href="#L8196">8196</a> <strong class="jxr_keyword">if</strong> (unit.startsWith(<span class="jxr_string">"m"</span>) && !unit.startsWith(<span class="jxr_string">"mo"</span>) && !unit.startsWith(<span class="jxr_string">"mill"</span>) && !unit.startsWith(<span class="jxr_string">"ms"</span>))
-<a class="jxr_linenumber" name="L8197" href="#L8197">8197</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)(value * 1000 * 60);
-<a class="jxr_linenumber" name="L8198" href="#L8198">8198</a> <strong class="jxr_keyword">if</strong> (unit.startsWith(<span class="jxr_string">"min"</span>) || unit.startsWith(<span class="jxr_string">"minute"</span>))
-<a class="jxr_linenumber" name="L8199" href="#L8199">8199</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)(value * 1000 * 60);
-<a class="jxr_linenumber" name="L8200" href="#L8200">8200</a>
-<a class="jxr_linenumber" name="L8201" href="#L8201">8201</a> <em class="jxr_comment">// Hours</em>
-<a class="jxr_linenumber" name="L8202" href="#L8202">8202</a> <strong class="jxr_keyword">if</strong> (unit.startsWith(<span class="jxr_string">"h"</span>) || unit.startsWith(<span class="jxr_string">"hour"</span>))
-<a class="jxr_linenumber" name="L8203" href="#L8203">8203</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)(value * 1000 * 60 * 60);
-<a class="jxr_linenumber" name="L8204" href="#L8204">8204</a>
-<a class="jxr_linenumber" name="L8205" href="#L8205">8205</a> <em class="jxr_comment">// Days</em>
-<a class="jxr_linenumber" name="L8206" href="#L8206">8206</a> <strong class="jxr_keyword">if</strong> (unit.startsWith(<span class="jxr_string">"d"</span>) && !unit.startsWith(<span class="jxr_string">"da"</span>))
-<a class="jxr_linenumber" name="L8207" href="#L8207">8207</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)(value * 1000 * 60 * 60 * 24);
-<a class="jxr_linenumber" name="L8208" href="#L8208">8208</a> <strong class="jxr_keyword">if</strong> (unit.startsWith(<span class="jxr_string">"day"</span>))
-<a class="jxr_linenumber" name="L8209" href="#L8209">8209</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)(value * 1000 * 60 * 60 * 24);
-<a class="jxr_linenumber" name="L8210" href="#L8210">8210</a>
-<a class="jxr_linenumber" name="L8211" href="#L8211">8211</a> <em class="jxr_comment">// Weeks</em>
-<a class="jxr_linenumber" name="L8212" href="#L8212">8212</a> <strong class="jxr_keyword">if</strong> (unit.startsWith(<span class="jxr_string">"w"</span>) || unit.startsWith(<span class="jxr_string">"week"</span>))
-<a class="jxr_linenumber" name="L8213" href="#L8213">8213</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)(value * 1000 * 60 * 60 * 24 * 7);
-<a class="jxr_linenumber" name="L8214" href="#L8214">8214</a>
-<a class="jxr_linenumber" name="L8215" href="#L8215">8215</a> <em class="jxr_comment">// Months (30 days)</em>
-<a class="jxr_linenumber" name="L8216" href="#L8216">8216</a> <strong class="jxr_keyword">if</strong> (unit.startsWith(<span class="jxr_string">"mo"</span>) || unit.startsWith(<span class="jxr_string">"month"</span>))
-<a class="jxr_linenumber" name="L8217" href="#L8217">8217</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)(value * 1000 * 60 * 60 * 24 * 30);
-<a class="jxr_linenumber" name="L8218" href="#L8218">8218</a>
-<a class="jxr_linenumber" name="L8219" href="#L8219">8219</a> <em class="jxr_comment">// Years (365 days)</em>
-<a class="jxr_linenumber" name="L8220" href="#L8220">8220</a> <strong class="jxr_keyword">if</strong> (unit.startsWith(<span class="jxr_string">"y"</span>) && !unit.startsWith(<span class="jxr_string">"yr"</span>))
-<a class="jxr_linenumber" name="L8221" href="#L8221">8221</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)(value * 1000 * 60 * 60 * 24 * 365);
-<a class="jxr_linenumber" name="L8222" href="#L8222">8222</a> <strong class="jxr_keyword">if</strong> (unit.startsWith(<span class="jxr_string">"yr"</span>) || unit.startsWith(<span class="jxr_string">"year"</span>))
-<a class="jxr_linenumber" name="L8223" href="#L8223">8223</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)(value * 1000 * 60 * 60 * 24 * 365);
-<a class="jxr_linenumber" name="L8224" href="#L8224">8224</a>
-<a class="jxr_linenumber" name="L8225" href="#L8225">8225</a> <em class="jxr_comment">// Unknown unit</em>
-<a class="jxr_linenumber" name="L8226" href="#L8226">8226</a> <strong class="jxr_keyword">return</strong> -1;
-<a class="jxr_linenumber" name="L8227" href="#L8227">8227</a> }
-<a class="jxr_linenumber" name="L8228" href="#L8228">8228</a>
-<a class="jxr_linenumber" name="L8229" href="#L8229">8229</a> <em class="jxr_javadoccomment">/**</em>
-<a class="jxr_linenumber" name="L8230" href="#L8230">8230</a> <em class="jxr_javadoccomment"> * Skips over a single comment sequence in a StringReader.</em>
-<a class="jxr_linenumber" name="L8231" href="#L8231">8231</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L8232" href="#L8232">8232</a> <em class="jxr_javadoccomment"> * <p></em>
-<a class="jxr_linenumber" name="L8233" href="#L8233">8233</a> <em class="jxr_javadoccomment"> * The reader must be positioned at the first <js>'/'</js> character of a comment.</em>
-<a class="jxr_linenumber" name="L8234" href="#L8234">8234</a> <em class="jxr_javadoccomment"> * This method will skip only the comment it's currently positioned on, not all comments in the reader.</em>
+<a class="jxr_linenumber" name="L8113" href="#L8113">8113</a> <em class="jxr_javadoccomment">/**</em>
+<a class="jxr_linenumber" name="L8114" href="#L8114">8114</a> <em class="jxr_javadoccomment"> * Determines the multiplier value based on the suffix character in a string.</em>
+<a class="jxr_linenumber" name="L8115" href="#L8115">8115</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L8116" href="#L8116">8116</a> <em class="jxr_javadoccomment"> * @param s The string to analyze for multiplier suffix.</em>
+<a class="jxr_linenumber" name="L8117" href="#L8117">8117</a> <em class="jxr_javadoccomment"> * @return The multiplier value (1 if no valid suffix found).</em>
+<a class="jxr_linenumber" name="L8118" href="#L8118">8118</a> <em class="jxr_javadoccomment"> */</em>
+<a class="jxr_linenumber" name="L8119" href="#L8119">8119</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">static</strong> <strong class="jxr_keyword">int</strong> multiplierInt(String s) {
+<a class="jxr_linenumber" name="L8120" href="#L8120">8120</a> <strong class="jxr_keyword">var</strong> c = isEmpty(s) ? 'z' : s.charAt(s.length() - 1);
+<a class="jxr_linenumber" name="L8121" href="#L8121">8121</a> <strong class="jxr_keyword">if</strong> (c == 'G')
+<a class="jxr_linenumber" name="L8122" href="#L8122">8122</a> <strong class="jxr_keyword">return</strong> 1024 * 1024 * 1024;
+<a class="jxr_linenumber" name="L8123" href="#L8123">8123</a> <strong class="jxr_keyword">if</strong> (c == 'M')
+<a class="jxr_linenumber" name="L8124" href="#L8124">8124</a> <strong class="jxr_keyword">return</strong> 1024 * 1024;
+<a class="jxr_linenumber" name="L8125" href="#L8125">8125</a> <strong class="jxr_keyword">if</strong> (c == 'K')
+<a class="jxr_linenumber" name="L8126" href="#L8126">8126</a> <strong class="jxr_keyword">return</strong> 1024;
+<a class="jxr_linenumber" name="L8127" href="#L8127">8127</a> <strong class="jxr_keyword">if</strong> (c == 'g')
+<a class="jxr_linenumber" name="L8128" href="#L8128">8128</a> <strong class="jxr_keyword">return</strong> 1000 * 1000 * 1000;
+<a class="jxr_linenumber" name="L8129" href="#L8129">8129</a> <strong class="jxr_keyword">if</strong> (c == 'm')
+<a class="jxr_linenumber" name="L8130" href="#L8130">8130</a> <strong class="jxr_keyword">return</strong> 1000 * 1000;
+<a class="jxr_linenumber" name="L8131" href="#L8131">8131</a> <strong class="jxr_keyword">if</strong> (c == 'k')
+<a class="jxr_linenumber" name="L8132" href="#L8132">8132</a> <strong class="jxr_keyword">return</strong> 1000;
+<a class="jxr_linenumber" name="L8133" href="#L8133">8133</a> <strong class="jxr_keyword">return</strong> 1;
+<a class="jxr_linenumber" name="L8134" href="#L8134">8134</a> }
+<a class="jxr_linenumber" name="L8135" href="#L8135">8135</a>
+<a class="jxr_linenumber" name="L8136" href="#L8136">8136</a> <em class="jxr_javadoccomment">/**</em>
+<a class="jxr_linenumber" name="L8137" href="#L8137">8137</a> <em class="jxr_javadoccomment"> * Determines the long multiplier value based on the suffix character in a string.</em>
+<a class="jxr_linenumber" name="L8138" href="#L8138">8138</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L8139" href="#L8139">8139</a> <em class="jxr_javadoccomment"> * @param s The string to analyze for multiplier suffix.</em>
+<a class="jxr_linenumber" name="L8140" href="#L8140">8140</a> <em class="jxr_javadoccomment"> * @return The multiplier value (1 if no valid suffix found).</em>
+<a class="jxr_linenumber" name="L8141" href="#L8141">8141</a> <em class="jxr_javadoccomment"> */</em>
+<a class="jxr_linenumber" name="L8142" href="#L8142">8142</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">static</strong> <strong class="jxr_keyword">long</strong> multiplierLong(String s) {
+<a class="jxr_linenumber" name="L8143" href="#L8143">8143</a> <strong class="jxr_keyword">if</strong> (isEmpty(s))
+<a class="jxr_linenumber" name="L8144" href="#L8144">8144</a> <strong class="jxr_keyword">return</strong> 1;
+<a class="jxr_linenumber" name="L8145" href="#L8145">8145</a> <strong class="jxr_keyword">var</strong> c = s.charAt(s.length() - 1);
+<a class="jxr_linenumber" name="L8146" href="#L8146">8146</a> <strong class="jxr_keyword">if</strong> (c == 'P')
+<a class="jxr_linenumber" name="L8147" href="#L8147">8147</a> <strong class="jxr_keyword">return</strong> 1125899906842624L; <em class="jxr_comment">// 1024^5</em>
+<a class="jxr_linenumber" name="L8148" href="#L8148">8148</a> <strong class="jxr_keyword">if</strong> (c == 'T')
+<a class="jxr_linenumber" name="L8149" href="#L8149">8149</a> <strong class="jxr_keyword">return</strong> 1099511627776L; <em class="jxr_comment">// 1024^4</em>
+<a class="jxr_linenumber" name="L8150" href="#L8150">8150</a> <strong class="jxr_keyword">if</strong> (c == 'G')
+<a class="jxr_linenumber" name="L8151" href="#L8151">8151</a> <strong class="jxr_keyword">return</strong> 1073741824L; <em class="jxr_comment">// 1024^3</em>
+<a class="jxr_linenumber" name="L8152" href="#L8152">8152</a> <strong class="jxr_keyword">if</strong> (c == 'M')
+<a class="jxr_linenumber" name="L8153" href="#L8153">8153</a> <strong class="jxr_keyword">return</strong> 1048576L; <em class="jxr_comment">// 1024^2</em>
+<a class="jxr_linenumber" name="L8154" href="#L8154">8154</a> <strong class="jxr_keyword">if</strong> (c == 'K')
+<a class="jxr_linenumber" name="L8155" href="#L8155">8155</a> <strong class="jxr_keyword">return</strong> 1024L;
+<a class="jxr_linenumber" name="L8156" href="#L8156">8156</a> <strong class="jxr_keyword">if</strong> (c == 'p')
+<a class="jxr_linenumber" name="L8157" href="#L8157">8157</a> <strong class="jxr_keyword">return</strong> 1000000000000000L; <em class="jxr_comment">// 1000^5</em>
+<a class="jxr_linenumber" name="L8158" href="#L8158">8158</a> <strong class="jxr_keyword">if</strong> (c == 't')
+<a class="jxr_linenumber" name="L8159" href="#L8159">8159</a> <strong class="jxr_keyword">return</strong> 1000000000000L; <em class="jxr_comment">// 1000^4</em>
+<a class="jxr_linenumber" name="L8160" href="#L8160">8160</a> <strong class="jxr_keyword">if</strong> (c == 'g')
+<a class="jxr_linenumber" name="L8161" href="#L8161">8161</a> <strong class="jxr_keyword">return</strong> 1000000000L; <em class="jxr_comment">// 1000^3</em>
+<a class="jxr_linenumber" name="L8162" href="#L8162">8162</a> <strong class="jxr_keyword">if</strong> (c == 'm')
+<a class="jxr_linenumber" name="L8163" href="#L8163">8163</a> <strong class="jxr_keyword">return</strong> 1000000L; <em class="jxr_comment">// 1000^2</em>
+<a class="jxr_linenumber" name="L8164" href="#L8164">8164</a> <strong class="jxr_keyword">if</strong> (c == 'k')
+<a class="jxr_linenumber" name="L8165" href="#L8165">8165</a> <strong class="jxr_keyword">return</strong> 1000L;
+<a class="jxr_linenumber" name="L8166" href="#L8166">8166</a> <strong class="jxr_keyword">return</strong> 1;
+<a class="jxr_linenumber" name="L8167" href="#L8167">8167</a> }
+<a class="jxr_linenumber" name="L8168" href="#L8168">8168</a>
+<a class="jxr_linenumber" name="L8169" href="#L8169">8169</a> <em class="jxr_javadoccomment">/**</em>
+<a class="jxr_linenumber" name="L8170" href="#L8170">8170</a> <em class="jxr_javadoccomment"> * Parses a unit string and converts the value to milliseconds.</em>
+<a class="jxr_linenumber" name="L8171" href="#L8171">8171</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L8172" href="#L8172">8172</a> <em class="jxr_javadoccomment"> * @param unit The unit string (case-insensitive, already lowercased).</em>
+<a class="jxr_linenumber" name="L8173" href="#L8173">8173</a> <em class="jxr_javadoccomment"> * @param value The numeric value.</em>
+<a class="jxr_linenumber" name="L8174" href="#L8174">8174</a> <em class="jxr_javadoccomment"> * @return The value in milliseconds, or <c>-1</c> if the unit is invalid.</em>
+<a class="jxr_linenumber" name="L8175" href="#L8175">8175</a> <em class="jxr_javadoccomment"> */</em>
+<a class="jxr_linenumber" name="L8176" href="#L8176">8176</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">static</strong> <strong class="jxr_keyword">long</strong> parseUnit(String unit, <strong class="jxr_keyword">double</strong> value) {
+<a class="jxr_linenumber" name="L8177" href="#L8177">8177</a> <strong class="jxr_keyword">if</strong> (isEmpty(unit)) {
+<a class="jxr_linenumber" name="L8178" href="#L8178">8178</a> <em class="jxr_comment">// No unit means milliseconds</em>
+<a class="jxr_linenumber" name="L8179" href="#L8179">8179</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)value;
+<a class="jxr_linenumber" name="L8180" href="#L8180">8180</a> }
+<a class="jxr_linenumber" name="L8181" href="#L8181">8181</a>
+<a class="jxr_linenumber" name="L8182" href="#L8182">8182</a> <em class="jxr_comment">// Check milliseconds first (before minutes) - must check exact "ms" before checking "m"</em>
+<a class="jxr_linenumber" name="L8183" href="#L8183">8183</a> <strong class="jxr_keyword">if</strong> (unit.equals(<span class="jxr_string">"ms"</span>) || unit.equals(<span class="jxr_string">"millis"</span>) || unit.equals(<span class="jxr_string">"milliseconds"</span>))
+<a class="jxr_linenumber" name="L8184" href="#L8184">8184</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)value;
+<a class="jxr_linenumber" name="L8185" href="#L8185">8185</a>
+<a class="jxr_linenumber" name="L8186" href="#L8186">8186</a> <em class="jxr_comment">// Seconds</em>
+<a class="jxr_linenumber" name="L8187" href="#L8187">8187</a> <strong class="jxr_keyword">if</strong> (unit.startsWith(<span class="jxr_string">"s"</span>) && !unit.startsWith(<span class="jxr_string">"sec"</span>))
+<a class="jxr_linenumber" name="L8188" href="#L8188">8188</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)(value * 1000);
+<a class="jxr_linenumber" name="L8189" href="#L8189">8189</a> <strong class="jxr_keyword">if</strong> (unit.startsWith(<span class="jxr_string">"sec"</span>) || unit.startsWith(<span class="jxr_string">"second"</span>))
+<a class="jxr_linenumber" name="L8190" href="#L8190">8190</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)(value * 1000);
+<a class="jxr_linenumber" name="L8191" href="#L8191">8191</a>
+<a class="jxr_linenumber" name="L8192" href="#L8192">8192</a> <em class="jxr_comment">// Minutes (must check after milliseconds and months)</em>
+<a class="jxr_linenumber" name="L8193" href="#L8193">8193</a> <strong class="jxr_keyword">if</strong> (unit.startsWith(<span class="jxr_string">"m"</span>) && !unit.startsWith(<span class="jxr_string">"mo"</span>) && !unit.startsWith(<span class="jxr_string">"mill"</span>) && !unit.startsWith(<span class="jxr_string">"ms"</span>))
+<a class="jxr_linenumber" name="L8194" href="#L8194">8194</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)(value * 1000 * 60);
+<a class="jxr_linenumber" name="L8195" href="#L8195">8195</a> <strong class="jxr_keyword">if</strong> (unit.startsWith(<span class="jxr_string">"min"</span>) || unit.startsWith(<span class="jxr_string">"minute"</span>))
+<a class="jxr_linenumber" name="L8196" href="#L8196">8196</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)(value * 1000 * 60);
+<a class="jxr_linenumber" name="L8197" href="#L8197">8197</a>
+<a class="jxr_linenumber" name="L8198" href="#L8198">8198</a> <em class="jxr_comment">// Hours</em>
+<a class="jxr_linenumber" name="L8199" href="#L8199">8199</a> <strong class="jxr_keyword">if</strong> (unit.startsWith(<span class="jxr_string">"h"</span>) || unit.startsWith(<span class="jxr_string">"hour"</span>))
+<a class="jxr_linenumber" name="L8200" href="#L8200">8200</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)(value * 1000 * 60 * 60);
+<a class="jxr_linenumber" name="L8201" href="#L8201">8201</a>
+<a class="jxr_linenumber" name="L8202" href="#L8202">8202</a> <em class="jxr_comment">// Days</em>
+<a class="jxr_linenumber" name="L8203" href="#L8203">8203</a> <strong class="jxr_keyword">if</strong> (unit.startsWith(<span class="jxr_string">"d"</span>) && !unit.startsWith(<span class="jxr_string">"da"</span>))
+<a class="jxr_linenumber" name="L8204" href="#L8204">8204</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)(value * 1000 * 60 * 60 * 24);
+<a class="jxr_linenumber" name="L8205" href="#L8205">8205</a> <strong class="jxr_keyword">if</strong> (unit.startsWith(<span class="jxr_string">"day"</span>))
+<a class="jxr_linenumber" name="L8206" href="#L8206">8206</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)(value * 1000 * 60 * 60 * 24);
+<a class="jxr_linenumber" name="L8207" href="#L8207">8207</a>
+<a class="jxr_linenumber" name="L8208" href="#L8208">8208</a> <em class="jxr_comment">// Weeks</em>
+<a class="jxr_linenumber" name="L8209" href="#L8209">8209</a> <strong class="jxr_keyword">if</strong> (unit.startsWith(<span class="jxr_string">"w"</span>) || unit.startsWith(<span class="jxr_string">"week"</span>))
+<a class="jxr_linenumber" name="L8210" href="#L8210">8210</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)(value * 1000 * 60 * 60 * 24 * 7);
+<a class="jxr_linenumber" name="L8211" href="#L8211">8211</a>
+<a class="jxr_linenumber" name="L8212" href="#L8212">8212</a> <em class="jxr_comment">// Months (30 days)</em>
+<a class="jxr_linenumber" name="L8213" href="#L8213">8213</a> <strong class="jxr_keyword">if</strong> (unit.startsWith(<span class="jxr_string">"mo"</span>) || unit.startsWith(<span class="jxr_string">"month"</span>))
+<a class="jxr_linenumber" name="L8214" href="#L8214">8214</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)(value * 1000 * 60 * 60 * 24 * 30);
+<a class="jxr_linenumber" name="L8215" href="#L8215">8215</a>
+<a class="jxr_linenumber" name="L8216" href="#L8216">8216</a> <em class="jxr_comment">// Years (365 days)</em>
+<a class="jxr_linenumber" name="L8217" href="#L8217">8217</a> <strong class="jxr_keyword">if</strong> (unit.startsWith(<span class="jxr_string">"y"</span>) && !unit.startsWith(<span class="jxr_string">"yr"</span>))
+<a class="jxr_linenumber" name="L8218" href="#L8218">8218</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)(value * 1000 * 60 * 60 * 24 * 365);
+<a class="jxr_linenumber" name="L8219" href="#L8219">8219</a> <strong class="jxr_keyword">if</strong> (unit.startsWith(<span class="jxr_string">"yr"</span>) || unit.startsWith(<span class="jxr_string">"year"</span>))
+<a class="jxr_linenumber" name="L8220" href="#L8220">8220</a> <strong class="jxr_keyword">return</strong> (<strong class="jxr_keyword">long</strong>)(value * 1000 * 60 * 60 * 24 * 365);
+<a class="jxr_linenumber" name="L8221" href="#L8221">8221</a>
+<a class="jxr_linenumber" name="L8222" href="#L8222">8222</a> <em class="jxr_comment">// Unknown unit</em>
+<a class="jxr_linenumber" name="L8223" href="#L8223">8223</a> <strong class="jxr_keyword">return</strong> -1;
+<a class="jxr_linenumber" name="L8224" href="#L8224">8224</a> }
+<a class="jxr_linenumber" name="L8225" href="#L8225">8225</a>
+<a class="jxr_linenumber" name="L8226" href="#L8226">8226</a> <em class="jxr_javadoccomment">/**</em>
+<a class="jxr_linenumber" name="L8227" href="#L8227">8227</a> <em class="jxr_javadoccomment"> * Skips over a single comment sequence in a StringReader.</em>
+<a class="jxr_linenumber" name="L8228" href="#L8228">8228</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L8229" href="#L8229">8229</a> <em class="jxr_javadoccomment"> * <p></em>
+<a class="jxr_linenumber" name="L8230" href="#L8230">8230</a> <em class="jxr_javadoccomment"> * The reader must be positioned at the first <js>'/'</js> character of a comment.</em>
+<a class="jxr_linenumber" name="L8231" href="#L8231">8231</a> <em class="jxr_javadoccomment"> * This method will skip only the comment it's currently positioned on, not all comments in the reader.</em>
+<a class="jxr_linenumber" name="L8232" href="#L8232">8232</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L8233" href="#L8233">8233</a> <em class="jxr_javadoccomment"> * <p></em>
+<a class="jxr_linenumber" name="L8234" href="#L8234">8234</a> <em class="jxr_javadoccomment"> * Supports both <js>"/* * /"</js> style block comments and <js>"//"</js> style line comments.</em>
<a class="jxr_linenumber" name="L8235" href="#L8235">8235</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L8236" href="#L8236">8236</a> <em class="jxr_javadoccomment"> * <p></em>
-<a class="jxr_linenumber" name="L8237" href="#L8237">8237</a> <em class="jxr_javadoccomment"> * Supports both <js>"/* * /"</js> style block comments and <js>"//"</js> style line comments.</em>
-<a class="jxr_linenumber" name="L8238" href="#L8238">8238</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L8239" href="#L8239">8239</a> <em class="jxr_javadoccomment"> * @param r The StringReader positioned at the start of a comment (at the first <js>'/'</js>).</em>
-<a class="jxr_linenumber" name="L8240" href="#L8240">8240</a> <em class="jxr_javadoccomment"> * @throws IOException If an I/O error occurs.</em>
-<a class="jxr_linenumber" name="L8241" href="#L8241">8241</a> <em class="jxr_javadoccomment"> */</em>
-<a class="jxr_linenumber" name="L8242" href="#L8242">8242</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> <strong class="jxr_keyword">void</strong> skipComments(StringReader r) <strong class="jxr_keyword">throws</strong> IOException {
-<a class="jxr_linenumber" name="L8243" href="#L8243">8243</a> <strong class="jxr_keyword">var</strong> c = r.read();
-<a class="jxr_linenumber" name="L8244" href="#L8244">8244</a> <em class="jxr_comment">// "/* */" style comments</em>
-<a class="jxr_linenumber" name="L8245" href="#L8245">8245</a> <strong class="jxr_keyword">if</strong> (c == '*') {
-<a class="jxr_linenumber" name="L8246" href="#L8246">8246</a> c = r.read();
-<a class="jxr_linenumber" name="L8247" href="#L8247">8247</a> <strong class="jxr_keyword">while</strong> (c != -1) {
-<a class="jxr_linenumber" name="L8248" href="#L8248">8248</a> <strong class="jxr_keyword">if</strong> (c == '*') {
-<a class="jxr_linenumber" name="L8249" href="#L8249">8249</a> c = r.read();
-<a class="jxr_linenumber" name="L8250" href="#L8250">8250</a> <strong class="jxr_keyword">if</strong> (c == '/')
-<a class="jxr_linenumber" name="L8251" href="#L8251">8251</a> <strong class="jxr_keyword">return</strong>;
-<a class="jxr_linenumber" name="L8252" href="#L8252">8252</a> <em class="jxr_comment">// If not '/', continue checking from this character</em>
-<a class="jxr_linenumber" name="L8253" href="#L8253">8253</a> <em class="jxr_comment">// Don't read again, just continue the loop</em>
-<a class="jxr_linenumber" name="L8254" href="#L8254">8254</a> } <strong class="jxr_keyword">else</strong> {
-<a class="jxr_linenumber" name="L8255" href="#L8255">8255</a> c = r.read();
-<a class="jxr_linenumber" name="L8256" href="#L8256">8256</a> }
-<a class="jxr_linenumber" name="L8257" href="#L8257">8257</a> }
-<a class="jxr_linenumber" name="L8258" href="#L8258">8258</a> <em class="jxr_comment">// "//" style comments</em>
-<a class="jxr_linenumber" name="L8259" href="#L8259">8259</a> } <strong class="jxr_keyword">else</strong> <strong class="jxr_keyword">if</strong> (c == '/') {
-<a class="jxr_linenumber" name="L8260" href="#L8260">8260</a> <strong class="jxr_keyword">while</strong> ((c = r.read()) != -1) {
-<a class="jxr_linenumber" name="L8261" href="#L8261">8261</a> <strong class="jxr_keyword">if</strong> (c == '\n')
-<a class="jxr_linenumber" name="L8262" href="#L8262">8262</a> <strong class="jxr_keyword">return</strong>;
-<a class="jxr_linenumber" name="L8263" href="#L8263">8263</a> }
-<a class="jxr_linenumber" name="L8264" href="#L8264">8264</a> }
-<a class="jxr_linenumber" name="L8265" href="#L8265">8265</a> }
-<a class="jxr_linenumber" name="L8266" href="#L8266">8266</a>
-<a class="jxr_linenumber" name="L8267" href="#L8267">8267</a> <em class="jxr_javadoccomment">/**</em>
-<a class="jxr_linenumber" name="L8268" href="#L8268">8268</a> <em class="jxr_javadoccomment"> * Gets or creates an AsciiSet for escaping the specified character.</em>
-<a class="jxr_linenumber" name="L8269" href="#L8269">8269</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L8270" href="#L8270">8270</a> <em class="jxr_javadoccomment"> * @param c The character to create an escape set for.</em>
-<a class="jxr_linenumber" name="L8271" href="#L8271">8271</a> <em class="jxr_javadoccomment"> * @return An AsciiSet containing the character and backslash.</em>
-<a class="jxr_linenumber" name="L8272" href="#L8272">8272</a> <em class="jxr_javadoccomment"> */</em>
-<a class="jxr_linenumber" name="L8273" href="#L8273">8273</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">static</strong> <a name="AsciiSet" href="../../../../../org/apache/juneau/commons/utils/AsciiSet.html#AsciiSet">AsciiSet</a> getEscapeSet(<strong class="jxr_keyword">char</strong> c) {
-<a class="jxr_linenumber" name="L8274" href="#L8274">8274</a> <strong class="jxr_keyword">return</strong> ESCAPE_SETS.computeIfAbsent(c, key -> AsciiSet.create().chars(key, '\\').build());
-<a class="jxr_linenumber" name="L8275" href="#L8275">8275</a> }
-<a class="jxr_linenumber" name="L8276" href="#L8276">8276</a>
-<a class="jxr_linenumber" name="L8277" href="#L8277">8277</a> <em class="jxr_javadoccomment">/**</em>
-<a class="jxr_linenumber" name="L8278" href="#L8278">8278</a> <em class="jxr_javadoccomment"> * Helper method to split a string into words.</em>
-<a class="jxr_linenumber" name="L8279" href="#L8279">8279</a> <em class="jxr_javadoccomment"> * Detects word boundaries from separators (spaces, underscores, hyphens) and case changes.</em>
-<a class="jxr_linenumber" name="L8280" href="#L8280">8280</a> <em class="jxr_javadoccomment"> *</em>
-<a class="jxr_linenumber" name="L8281" href="#L8281">8281</a> <em class="jxr_javadoccomment"> * @param str The string to split.</em>
-<a class="jxr_linenumber" name="L8282" href="#L8282">8282</a> <em class="jxr_javadoccomment"> * @return A list of words, or empty list if input is null or empty.</em>
-<a class="jxr_linenumber" name="L8283" href="#L8283">8283</a> <em class="jxr_javadoccomment"> */</em>
-<a class="jxr_linenumber" name="L8284" href="#L8284">8284</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">static</strong> List<String> splitWords(String str) {
-<a class="jxr_linenumber" name="L8285" href="#L8285">8285</a> <strong class="jxr_keyword">if</strong> (str == <strong class="jxr_keyword">null</strong> || isEmpty(str))
-<a class="jxr_linenumber" name="L8286" href="#L8286">8286</a> <strong class="jxr_keyword">return</strong> Collections.emptyList();
-<a class="jxr_linenumber" name="L8287" href="#L8287">8287</a>
-<a class="jxr_linenumber" name="L8288" href="#L8288">8288</a> <strong class="jxr_keyword">var</strong> words = <strong class="jxr_keyword">new</strong> ArrayList<String>();
-<a class="jxr_linenumber" name="L8289" href="#L8289">8289</a> <strong class="jxr_keyword">var</strong> sb = <strong class="jxr_keyword">new</strong> StringBuilder();
-<a class="jxr_linenumber" name="L8290" href="#L8290">8290</a> <strong class="jxr_keyword">var</strong> wasLowerCase = false;
-<a class="jxr_linenumber" name="L8291" href="#L8291">8291</a> <strong class="jxr_keyword">var</strong> wasUpperCase = false;
-<a class="jxr_linenumber" name="L8292" href="#L8292">8292</a> <strong class="jxr_keyword">var</strong> consecutiveUpperCount = 0;
-<a class="jxr_linenumber" name="L8293" href="#L8293">8293</a>
-<a class="jxr_linenumber" name="L8294" href="#L8294">8294</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> i = 0; i < str.length(); i++) {
-<a class="jxr_linenumber" name="L8295" href="#L8295">8295</a> <strong class="jxr_keyword">var</strong> c = str.charAt(i);
-<a class="jxr_linenumber" name="L8296" href="#L8296">8296</a> <strong class="jxr_keyword">var</strong> isSeparator = (c == ' ' || c == '_' || c == '-' || c == '\t');
-<a class="jxr_linenumber" name="L8297" href="#L8297">8297</a> <strong class="jxr_keyword">var</strong> isUpperCase = LETTER_UC.contains(c);
-<a class="jxr_linenumber" name="L8298" href="#L8298">8298</a> <strong class="jxr_keyword">var</strong> isLowerCase = LETTER_LC.contains(c);
-<a class="jxr_linenumber" name="L8299" href="#L8299">8299</a> <strong class="jxr_keyword">var</strong> isLetter = LETTER.contains(c);
-<a class="jxr_linenumber" name="L8300" href="#L8300">8300</a>
-<a class="jxr_linenumber" name="L8301" href="#L8301">8301</a> <strong class="jxr_keyword">if</strong> (isSeparator) {
-<a class="jxr_linenumber" name="L8302" href="#L8302">8302</a> <strong class="jxr_keyword">if</strong> (sb.length() > 0) {
-<a class="jxr_linenumber" name="L8303" href="#L8303">8303</a> words.add(sb.toString());
-<a class="jxr_linenumber" name="L8304" href="#L8304">8304</a> sb.setLength(0);
-<a class="jxr_linenumber" name="L8305" href="#L8305">8305</a> }
-<a class="jxr_linenumber" name="L8306" href="#L8306">8306</a> wasLowerCase = false;
-<a class="jxr_linenumber" name="L8307" href="#L8307">8307</a> wasUpperCase = false;
-<a class="jxr_linenumber" name="L8308" href="#L8308">8308</a> consecutiveUpperCount = 0;
-<a class="jxr_linenumber" name="L8309" href="#L8309">8309</a> } <strong class="jxr_keyword">else</strong> <strong class="jxr_keyword">if</strong> (isLetter) {
-<a class="jxr_linenumber" name="L8310" href="#L8310">8310</a> <em class="jxr_comment">// Detect word boundary:</em>
-<a class="jxr_linenumber" name="L8311" href="#L8311">8311</a> <em class="jxr_comment">// 1. Uppercase after lowercase (e.g., "helloWorld" → "hello", "World")</em>
-<a class="jxr_linenumber" name="L8312" href="#L8312">8312</a> <em class="jxr_comment">// 2. Uppercase after consecutive uppercase when next is lowercase (e.g., "XMLHttp" → "XML", "Http")</em>
-<a class="jxr_linenumber" name="L8313" href="#L8313">8313</a> <em class="jxr_comment">// 3. Lowercase after 2+ consecutive uppercase (e.g., "XMLHttp" → "XML", "Http")</em>
-<a class="jxr_linenumber" name="L8314" href="#L8314">8314</a> <strong class="jxr_keyword">if</strong> (sb.length() > 0) {
-<a class="jxr_linenumber" name="L8315" href="#L8315">8315</a> <strong class="jxr_keyword">if</strong> (isUpperCase && wasLowerCase) {
-<a class="jxr_linenumber" name="L8316" href="#L8316">8316</a> <em class="jxr_comment">// Case 1: uppercase after lowercase (e.g., "helloWorld" → "hello", "World")</em>
-<a class="jxr_linenumber" name="L8317" href="#L8317">8317</a> words.add(sb.toString());
-<a class="jxr_linenumber" name="L8318" href="#L8318">8318</a> sb.setLength(0);
-<a class="jxr_linenumber" name="L8319" href="#L8319">8319</a> consecutiveUpperCount = 0;
-<a class="jxr_linenumber" name="L8320" href="#L8320">8320</a> } <strong class="jxr_keyword">else</strong> <strong class="jxr_keyword">if</strong> (isUpperCase && wasUpperCase && consecutiveUpperCount >= 2) {
-<a class="jxr_linenumber" name="L8321" href="#L8321">8321</a> <em class="jxr_comment">// Case 2: uppercase after uppercase - check if this starts a new word</em>
-<a class="jxr_linenumber" name="L8322" href="#L8322">8322</a> <em class="jxr_comment">// Look ahead to see if next character is lowercase</em>
-<a class="jxr_linenumber" name="L8323" href="#L8323">8323</a> <em class="jxr_comment">// This handles "XMLHttp" where 'H' starts "Http"</em>
-<a class="jxr_linenumber" name="L8324" href="#L8324">8324</a> <em class="jxr_comment">// We need at least 2 consecutive uppercase letters before this one to split</em>
-<a class="jxr_linenumber" name="L8325" href="#L8325">8325</a> <strong class="jxr_keyword">if</strong> (i + 1 < str.length()) {
-<a class="jxr_linenumber" name="L8326" href="#L8326">8326</a> <strong class="jxr_keyword">var</strong> nextChar = str.charAt(i + 1);
-<a class="jxr_linenumber" name="L8327" href="#L8327">8327</a> <strong class="jxr_keyword">if</strong> (LETTER_LC.contains(nextChar)) {
-<a class="jxr_linenumber" name="L8328" href="#L8328">8328</a> <em class="jxr_comment">// This uppercase starts a new word, split before it</em>
-<a class="jxr_linenumber" name="L8329" href="#L8329">8329</a> words.add(sb.toString());
-<a class="jxr_linenumber" name="L8330" href="#L8330">8330</a> sb.setLength(0);
-<a class="jxr_linenumber" name="L8331" href="#L8331">8331</a> consecutiveUpperCount = 0;
-<a class="jxr_linenumber" name="L8332" href="#L8332">8332</a> }
-<a class="jxr_linenumber" name="L8333" href="#L8333">8333</a> }
-<a class="jxr_linenumber" name="L8334" href="#L8334">8334</a> } <strong class="jxr_keyword">else</strong> <strong class="jxr_keyword">if</strong> (isLowerCase && wasUpperCase && consecutiveUpperCount >= 2) {
-<a class="jxr_linenumber" name="L8335" href="#L8335">8335</a> <em class="jxr_comment">// Case 3: lowercase after 2+ consecutive uppercase</em>
-<a class="jxr_linenumber" name="L8336" href="#L8336">8336</a> <em class="jxr_comment">// Split all but the last uppercase (e.g., "XMLH" → "XML" + "H")</em>
-<a class="jxr_linenumber" name="L8337" href="#L8337">8337</a> <strong class="jxr_keyword">var</strong> splitPoint = sb.length() - 1;
-<a class="jxr_linenumber" name="L8338" href="#L8338">8338</a> words.add(sb.substring(0, splitPoint));
-<a class="jxr_linenumber" name="L8339" href="#L8339">8339</a> sb.delete(0, splitPoint);
-<a class="jxr_linenumber" name="L8340" href="#L8340">8340</a> consecutiveUpperCount = 0;
-<a class="jxr_linenumber" name="L8341" href="#L8341">8341</a> }
-<a class="jxr_linenumber" name="L8342" href="#L8342">8342</a> }
-<a class="jxr_linenumber" name="L8343" href="#L8343">8343</a> sb.append(c);
-<a class="jxr_linenumber" name="L8344" href="#L8344">8344</a> <em class="jxr_comment">// Update state AFTER appending</em>
-<a class="jxr_linenumber" name="L8345" href="#L8345">8345</a> wasLowerCase = isLowerCase;
-<a class="jxr_linenumber" name="L8346" href="#L8346">8346</a> wasUpperCase = isUpperCase;
-<a class="jxr_linenumber" name="L8347" href="#L8347">8347</a> <strong class="jxr_keyword">if</strong> (isUpperCase) {
-<a class="jxr_linenumber" name="L8348" href="#L8348">8348</a> consecutiveUpperCount++;
-<a class="jxr_linenumber" name="L8349" href="#L8349">8349</a> } <strong class="jxr_keyword">else</strong> {
-<a class="jxr_linenumber" name="L8350" href="#L8350">8350</a> consecutiveUpperCount = 0;
-<a class="jxr_linenumber" name="L8351" href="#L8351">8351</a> }
-<a class="jxr_linenumber" name="L8352" href="#L8352">8352</a> } <strong class="jxr_keyword">else</strong> {
-<a class="jxr_linenumber" name="L8353" href="#L8353">8353</a> <em class="jxr_comment">// Non-letter characters (digits, etc.) - treat as part of current word</em>
-<a class="jxr_linenumber" name="L8354" href="#L8354">8354</a> sb.append(c);
-<a class="jxr_linenumber" name="L8355" href="#L8355">8355</a> wasLowerCase = false;
-<a class="jxr_linenumber" name="L8356" href="#L8356">8356</a> wasUpperCase = false;
-<a class="jxr_linenumber" name="L8357" href="#L8357">8357</a> consecutiveUpperCount = 0;
-<a class="jxr_linenumber" name="L8358" href="#L8358">8358</a> }
-<a class="jxr_linenumber" name="L8359" href="#L8359">8359</a> }
+<a class="jxr_linenumber" name="L8236" href="#L8236">8236</a> <em class="jxr_javadoccomment"> * @param r The StringReader positioned at the start of a comment (at the first <js>'/'</js>).</em>
+<a class="jxr_linenumber" name="L8237" href="#L8237">8237</a> <em class="jxr_javadoccomment"> * @throws IOException If an I/O error occurs.</em>
+<a class="jxr_linenumber" name="L8238" href="#L8238">8238</a> <em class="jxr_javadoccomment"> */</em>
+<a class="jxr_linenumber" name="L8239" href="#L8239">8239</a> <strong class="jxr_keyword">public</strong> <strong class="jxr_keyword">static</strong> <strong class="jxr_keyword">void</strong> skipComments(StringReader r) <strong class="jxr_keyword">throws</strong> IOException {
+<a class="jxr_linenumber" name="L8240" href="#L8240">8240</a> <strong class="jxr_keyword">var</strong> c = r.read();
+<a class="jxr_linenumber" name="L8241" href="#L8241">8241</a> <em class="jxr_comment">// "/* */" style comments</em>
+<a class="jxr_linenumber" name="L8242" href="#L8242">8242</a> <strong class="jxr_keyword">if</strong> (c == '*') {
+<a class="jxr_linenumber" name="L8243" href="#L8243">8243</a> c = r.read();
+<a class="jxr_linenumber" name="L8244" href="#L8244">8244</a> <strong class="jxr_keyword">while</strong> (c != -1) {
+<a class="jxr_linenumber" name="L8245" href="#L8245">8245</a> <strong class="jxr_keyword">if</strong> (c == '*') {
+<a class="jxr_linenumber" name="L8246" href="#L8246">8246</a> c = r.read();
+<a class="jxr_linenumber" name="L8247" href="#L8247">8247</a> <strong class="jxr_keyword">if</strong> (c == '/')
+<a class="jxr_linenumber" name="L8248" href="#L8248">8248</a> <strong class="jxr_keyword">return</strong>;
+<a class="jxr_linenumber" name="L8249" href="#L8249">8249</a> <em class="jxr_comment">// If not '/', continue checking from this character</em>
+<a class="jxr_linenumber" name="L8250" href="#L8250">8250</a> <em class="jxr_comment">// Don't read again, just continue the loop</em>
+<a class="jxr_linenumber" name="L8251" href="#L8251">8251</a> } <strong class="jxr_keyword">else</strong> {
+<a class="jxr_linenumber" name="L8252" href="#L8252">8252</a> c = r.read();
+<a class="jxr_linenumber" name="L8253" href="#L8253">8253</a> }
+<a class="jxr_linenumber" name="L8254" href="#L8254">8254</a> }
+<a class="jxr_linenumber" name="L8255" href="#L8255">8255</a> <em class="jxr_comment">// "//" style comments</em>
+<a class="jxr_linenumber" name="L8256" href="#L8256">8256</a> } <strong class="jxr_keyword">else</strong> <strong class="jxr_keyword">if</strong> (c == '/') {
+<a class="jxr_linenumber" name="L8257" href="#L8257">8257</a> <strong class="jxr_keyword">while</strong> ((c = r.read()) != -1) {
+<a class="jxr_linenumber" name="L8258" href="#L8258">8258</a> <strong class="jxr_keyword">if</strong> (c == '\n')
+<a class="jxr_linenumber" name="L8259" href="#L8259">8259</a> <strong class="jxr_keyword">return</strong>;
+<a class="jxr_linenumber" name="L8260" href="#L8260">8260</a> }
+<a class="jxr_linenumber" name="L8261" href="#L8261">8261</a> }
+<a class="jxr_linenumber" name="L8262" href="#L8262">8262</a> }
+<a class="jxr_linenumber" name="L8263" href="#L8263">8263</a>
+<a class="jxr_linenumber" name="L8264" href="#L8264">8264</a> <em class="jxr_javadoccomment">/**</em>
+<a class="jxr_linenumber" name="L8265" href="#L8265">8265</a> <em class="jxr_javadoccomment"> * Gets or creates an AsciiSet for escaping the specified character.</em>
+<a class="jxr_linenumber" name="L8266" href="#L8266">8266</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L8267" href="#L8267">8267</a> <em class="jxr_javadoccomment"> * @param c The character to create an escape set for.</em>
+<a class="jxr_linenumber" name="L8268" href="#L8268">8268</a> <em class="jxr_javadoccomment"> * @return An AsciiSet containing the character and backslash.</em>
+<a class="jxr_linenumber" name="L8269" href="#L8269">8269</a> <em class="jxr_javadoccomment"> */</em>
+<a class="jxr_linenumber" name="L8270" href="#L8270">8270</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">static</strong> <a name="AsciiSet" href="../../../../../org/apache/juneau/commons/utils/AsciiSet.html#AsciiSet">AsciiSet</a> getEscapeSet(<strong class="jxr_keyword">char</strong> c) {
+<a class="jxr_linenumber" name="L8271" href="#L8271">8271</a> <strong class="jxr_keyword">return</strong> ESCAPE_SETS.computeIfAbsent(c, key -> AsciiSet.create().chars(key, '\\').build());
+<a class="jxr_linenumber" name="L8272" href="#L8272">8272</a> }
+<a class="jxr_linenumber" name="L8273" href="#L8273">8273</a>
+<a class="jxr_linenumber" name="L8274" href="#L8274">8274</a> <em class="jxr_javadoccomment">/**</em>
+<a class="jxr_linenumber" name="L8275" href="#L8275">8275</a> <em class="jxr_javadoccomment"> * Helper method to split a string into words.</em>
+<a class="jxr_linenumber" name="L8276" href="#L8276">8276</a> <em class="jxr_javadoccomment"> * Detects word boundaries from separators (spaces, underscores, hyphens) and case changes.</em>
+<a class="jxr_linenumber" name="L8277" href="#L8277">8277</a> <em class="jxr_javadoccomment"> *</em>
+<a class="jxr_linenumber" name="L8278" href="#L8278">8278</a> <em class="jxr_javadoccomment"> * @param str The string to split.</em>
+<a class="jxr_linenumber" name="L8279" href="#L8279">8279</a> <em class="jxr_javadoccomment"> * @return A list of words, or empty list if input is null or empty.</em>
+<a class="jxr_linenumber" name="L8280" href="#L8280">8280</a> <em class="jxr_javadoccomment"> */</em>
+<a class="jxr_linenumber" name="L8281" href="#L8281">8281</a> <strong class="jxr_keyword">private</strong> <strong class="jxr_keyword">static</strong> List<String> splitWords(String str) {
+<a class="jxr_linenumber" name="L8282" href="#L8282">8282</a> <strong class="jxr_keyword">if</strong> (str == <strong class="jxr_keyword">null</strong> || isEmpty(str))
+<a class="jxr_linenumber" name="L8283" href="#L8283">8283</a> <strong class="jxr_keyword">return</strong> Collections.emptyList();
+<a class="jxr_linenumber" name="L8284" href="#L8284">8284</a>
+<a class="jxr_linenumber" name="L8285" href="#L8285">8285</a> <strong class="jxr_keyword">var</strong> words = <strong class="jxr_keyword">new</strong> ArrayList<String>();
+<a class="jxr_linenumber" name="L8286" href="#L8286">8286</a> <strong class="jxr_keyword">var</strong> sb = <strong class="jxr_keyword">new</strong> StringBuilder();
+<a class="jxr_linenumber" name="L8287" href="#L8287">8287</a> <strong class="jxr_keyword">var</strong> wasLowerCase = false;
+<a class="jxr_linenumber" name="L8288" href="#L8288">8288</a> <strong class="jxr_keyword">var</strong> wasUpperCase = false;
+<a class="jxr_linenumber" name="L8289" href="#L8289">8289</a> <strong class="jxr_keyword">var</strong> consecutiveUpperCount = 0;
+<a class="jxr_linenumber" name="L8290" href="#L8290">8290</a>
+<a class="jxr_linenumber" name="L8291" href="#L8291">8291</a> <strong class="jxr_keyword">for</strong> (<strong class="jxr_keyword">var</strong> i = 0; i < str.length(); i++) {
+<a class="jxr_linenumber" name="L8292" href="#L8292">8292</a> <strong class="jxr_keyword">var</strong> c = str.charAt(i);
+<a class="jxr_linenumber" name="L8293" href="#L8293">8293</a> <strong class="jxr_keyword">var</strong> isSeparator = (c == ' ' || c == '_' || c == '-' || c == '\t');
+<a class="jxr_linenumber" name="L8294" href="#L8294">8294</a> <strong class="jxr_keyword">var</strong> isUpperCase = LETTER_UC.contains(c);
+<a class="jxr_linenumber" name="L8295" href="#L8295">8295</a> <strong class="jxr_keyword">var</strong> isLowerCase = LETTER_LC.contains(c);
+<a class="jxr_linenumber" name="L8296" href="#L8296">8296</a> <strong class="jxr_keyword">var</strong> isLetter = LETTER.contains(c);
+<a class="jxr_linenumber" name="L8297" href="#L8297">8297</a>
+<a class="jxr_linenumber" name="L8298" href="#L8298">8298</a> <strong class="jxr_keyword">if</strong> (isSeparator) {
+<a class="jxr_linenumber" name="L8299" href="#L8299">8299</a> <strong class="jxr_keyword">if</strong> (sb.length() > 0) {
+<a class="jxr_linenumber" name="L8300" href="#L8300">8300</a> words.add(sb.toString());
+<a class="jxr_linenumber" name="L8301" href="#L8301">8301</a> sb.setLength(0);
+<a class="jxr_linenumber" name="L8302" href="#L8302">8302</a> }
+<a class="jxr_linenumber" name="L8303" href="#L8303">8303</a> wasLowerCase = false;
+<a class="jxr_linenumber" name="L8304" href="#L8304">8304</a> wasUpperCase = false;
+<a class="jxr_linenumber" name="L8305" href="#L8305">8305</a> consecutiveUpperCount = 0;
+<a class="jxr_linenumber" name="L8306" href="#L8306">8306</a> } <strong class="jxr_keyword">else</strong> <strong class="jxr_keyword">if</strong> (isLetter) {
+<a class="jxr_linenumber" name="L8307" href="#L8307">8307</a> <em class="jxr_comment">// Detect word boundary:</em>
+<a class="jxr_linenumber" name="L8308" href="#L8308">8308</a> <em class="jxr_comment">// 1. Uppercase after lowercase (e.g., "helloWorld" → "hello", "World")</em>
+<a class="jxr_linenumber" name="L8309" href="#L8309">8309</a> <em class="jxr_comment">// 2. Uppercase after consecutive uppercase when next is lowercase (e.g., "XMLHttp" → "XML", "Http")</em>
+<a class="jxr_linenumber" name="L8310" href="#L8310">8310</a> <em class="jxr_comment">// 3. Lowercase after 2+ consecutive uppercase (e.g., "XMLHttp" → "XML", "Http")</em>
+<a class="jxr_linenumber" name="L8311" href="#L8311">8311</a> <strong class="jxr_keyword">if</strong> (sb.length() > 0) {
+<a class="jxr_linenumber" name="L8312" href="#L8312">8312</a> <strong class="jxr_keyword">if</strong> (isUpperCase && wasLowerCase) {
+<a class="jxr_linenumber" name="L8313" href="#L8313">8313</a> <em class="jxr_comment">// Case 1: uppercase after lowercase (e.g., "helloWorld" → "hello", "World")</em>
+<a class="jxr_linenumber" name="L8314" href="#L8314">8314</a> words.add(sb.toString());
+<a class="jxr_linenumber" name="L8315" href="#L8315">8315</a> sb.setLength(0);
+<a class="jxr_linenumber" name="L8316" href="#L8316">8316</a> consecutiveUpperCount = 0;
+<a class="jxr_linenumber" name="L8317" href="#L8317">8317</a> } <strong class="jxr_keyword">else</strong> <strong class="jxr_keyword">if</strong> (isUpperCase && wasUpperCase && consecutiveUpperCount >= 2) {
+<a class="jxr_linenumber" name="L8318" href="#L8318">8318</a> <em class="jxr_comment">// Case 2: uppercase after uppercase - check if this starts a new word</em>
+<a class="jxr_linenumber" name="L8319" href="#L8319">8319</a> <em class="jxr_comment">// Look ahead to see if next character is lowercase</em>
+<a class="jxr_linenumber" name="L8320" href="#L8320">8320</a> <em class="jxr_comment">// This handles "XMLHttp" where 'H' starts "Http"</em>
+<a class="jxr_linenumber" name="L8321" href="#L8321">8321</a> <em class="jxr_comment">// We need at least 2 consecutive uppercase letters before this one to split</em>
+<a class="jxr_linenumber" name="L8322" href="#L8322">8322</a> <strong class="jxr_keyword">if</strong> (i + 1 < str.length()) {
+<a class="jxr_linenumber" name="L8323" href="#L8323">8323</a> <strong class="jxr_keyword">var</strong> nextChar = str.charAt(i + 1);
+<a class="jxr_linenumber" name="L8324" href="#L8324">8324</a> <strong class="jxr_keyword">if</strong> (LETTER_LC.contains(nextChar)) {
+<a class="jxr_linenumber" name="L8325" href="#L8325">8325</a> <em class="jxr_comment">// This uppercase starts a new word, split before it</em>
+<a class="jxr_linenumber" name="L8326" href="#L8326">8326</a> words.add(sb.toString());
+<a class="jxr_linenumber" name="L8327" href="#L8327">8327</a> sb.setLength(0);
+<a class="jxr_linenumber" name="L8328" href="#L8328">8328</a> consecutiveUpperCount = 0;
+<a class="jxr_linenumber" name="L8329" href="#L8329">8329</a> }
+<a class="jxr_linenumber" name="L8330" href="#L8330">8330</a> }
+<a class="jxr_linenumber" name="L8331" href="#L8331">8331</a> } <strong class="jxr_keyword">else</strong> <strong class="jxr_keyword">if</strong> (isLowerCase && wasUpperCase && consecutiveUpperCount >= 2) {
+<a class="jxr_linenumber" name="L8332" href="#L8332">8332</a> <em class="jxr_comment">// Case 3: lowercase after 2+ consecutive uppercase</em>
+<a class="jxr_linenumber" name="L8333" href="#L8333">8333</a> <em class="jxr_comment">// Split all but the last uppercase (e.g., "XMLH" → "XML" + "H")</em>
+<a class="jxr_linenumber" name="L8334" href="#L8334">8334</a> <strong class="jxr_keyword">var</strong> splitPoint = sb.length() - 1;
+<a class="jxr_linenumber" name="L8335" href="#L8335">8335</a> words.add(sb.substring(0, splitPoint));
+<a class="jxr_linenumber" name="L8336" href="#L8336">8336</a> sb.delete(0, splitPoint);
+<a class="jxr_linenumber" name="L8337" href="#L8337">8337</a> consecutiveUpperCount = 0;
+<a class="jxr_linenumber" name="L8338" href="#L8338">8338</a> }
+<a class="jxr_linenumber" name="L8339" href="#L8339">8339</a> }
+<a class="jxr_linenumber" name="L8340" href="#L8340">8340</a> sb.append(c);
+<a class="jxr_linenumber" name="L8341" href="#L8341">8341</a> <em class="jxr_comment">// Update state AFTER appending</em>
+<a class="jxr_linenumber" name="L8342" href="#L8342">8342</a> wasLowerCase = isLowerCase;
+<a class="jxr_linenumber" name="L8343" href="#L8343">8343</a> wasUpperCase = isUpperCase;
+<a class="jxr_linenumber" name="L8344" href="#L8344">8344</a> <strong class="jxr_keyword">if</strong> (isUpperCase) {
+<a class="jxr_linenumber" name="L8345" href="#L8345">8345</a> consecutiveUpperCount++;
+<a class="jxr_linenumber" name="L8346" href="#L8346">8346</a> } <strong class="jxr_keyword">else</strong> {
+<a class="jxr_linenumber" name="L8347" href="#L8347">8347</a> consecutiveUpperCount = 0;
+<a class="jxr_linenumber" name="L8348" href="#L8348">8348</a> }
+<a class="jxr_linenumber" name="L8349" href="#L8349">8349</a> } <strong class="jxr_keyword">else</strong> {
+<a class="jxr_linenumber" name="L8350" href="#L8350">8350</a> <em class="jxr_comment">// Non-letter characters (digits, etc.) - treat as part of current word</em>
+<a class="jxr_linenumber" name="L8351" href="#L8351">8351</a> sb.append(c);
+<a class="jxr_linenumber" name="L8352" href="#L8352">8352</a> wasLowerCase = false;
+<a class="jxr_linenumber" name="L8353" href="#L8353">8353</a> wasUpperCase = false;
+<a class="jxr_linenumber" name="L8354" href="#L8354">8354</a> consecutiveUpperCount = 0;
+<a class="jxr_linenumber" name="L8355" href="#L8355">8355</a> }
+<a class="jxr_linenumber" name="L8356" href="#L8356">8356</a> }
+<a class="jxr_linenumber" name="L8357" href="#L8357">8357</a>
+<a class="jxr_linenumber" name="L8358" href="#L8358">8358</a> <strong class="jxr_keyword">if</strong> (sb.length() > 0)
+<a class="jxr_linenumber" name="L8359" href="#L8359">8359</a> words.add(sb.toString());
<a class="jxr_linenumber" name="L8360" href="#L8360">8360</a>
-<a class="jxr_linenumber" name="L8361" href="#L8361">8361</a> <strong class="jxr_keyword">if</strong> (sb.length() > 0)
-<a class="jxr_linenumber" name="L8362" href="#L8362">8362</a> words.add(sb.toString());
+<a class="jxr_linenumber" name="L8361" href="#L8361">8361</a> <strong class="jxr_keyword">return</strong> words;
+<a class="jxr_linenumber" name="L8362" href="#L8362">8362</a> }
<a class="jxr_linenumber" name="L8363" href="#L8363">8363</a>
-<a class="jxr_linenumber" name="L8364" href="#L8364">8364</a> <strong class="jxr_keyword">return</strong> words;
-<a class="jxr_linenumber" name="L8365" href="#L8365">8365</a> }
-<a class="jxr_linenumber" name="L8366" href="#L8366">8366</a>
-<a class="jxr_linenumber" name="L8367" href="#L8367">8367</a> <em class="jxr_javadoccomment">/**</em>
-<a class="jxr_linenumber" name="L8368" href="#L8368">8368</a> <em class="jxr_javadoccomment"> * Constructor.</em>
-<a class="jxr_linenumber" name="L8369" href="#L8369">8369</a> <em class="jxr_javadoccomment"> */</em>
-<a class="jxr_linenumber" name="L8370" href="#L8370">8370</a> <strong class="jxr_keyword">protected</strong> <a name="StringUtils" href="../../../../../org/apache/juneau/commons/utils/StringUtils.html#StringUtils">StringUtils</a>() {}
-<a class="jxr_linenumber" name="L8371" href="#L8371">8371</a> }
+<a class="jxr_linenumber" name="L8364" href="#L8364">8364</a> <em class="jxr_javadoccomment">/**</em>
+<a class="jxr_linenumber" name="L8365" href="#L8365">8365</a> <em class="jxr_javadoccomment"> * Constructor.</em>
+<a class="jxr_linenumber" name="L8366" href="#L8366">8366</a> <em class="jxr_javadoccomment"> */</em>
+<a class="jxr_linenumber" name="L8367" href="#L8367">8367</a> <strong class="jxr_keyword">protected</strong> <a name="StringUtils" href="../../../../../org/apache/juneau/commons/utils/StringUtils.html#StringUtils">StringUtils</a>() {}
+<a class="jxr_linenumber" name="L8368" href="#L8368">8368</a> }
</pre>
<hr/>
<div id="footer">© 2016–2025 <a href="https://www.apache.org/">The Apache Software Foundation</a></div>