dependabot[bot] opened a new pull request, #24460:
URL: https://github.com/apache/camel/pull/24460

   Bumps [com.cedarsoftware:java-util](https://github.com/jdereg/java-util) 
from 4.105.0 to 4.106.0.
   <details>
   <summary>Release notes</summary>
   <p><em>Sourced from <a 
href="https://github.com/jdereg/java-util/releases";>com.cedarsoftware:java-util's
 releases</a>.</em></p>
   <blockquote>
   <h2>4.106.0</h2>
   <h2>java-util 4.106.0</h2>
   <p>Maven Central: <code>com.cedarsoftware:java-util:4.106.0</code></p>
   <p>A broad, class-by-class hardening pass across the library — real 
correctness, security, and performance fixes in the core utilities, each pinned 
by new tests. Full details in <a 
href="https://github.com/jdereg/java-util/blob/master/changelog.md";>changelog.md</a>.</p>
   <h3>Highlights</h3>
   <p><strong>Security</strong></p>
   <ul>
   <li><strong>Turkish-locale defect class fixed</strong> across 
<code>DateUtilities</code>, <code>IOUtilities</code>, and 
<code>SystemUtilities</code> — default-locale case conversion (e.g. 
<code>&quot;Windows&quot;</code> → <code>&quot;wındows&quot;</code>, 
<code>&quot;FILE&quot;</code> → <code>&quot;fıle&quot;</code>) silently 
disabled Windows system-path checks and protocol allow-listing; all 
security-relevant conversions now use <code>Locale.ROOT</code>.</li>
   <li><strong>ReDoS timeout protection now actually stops runaway 
matches</strong> in <code>DateUtilities</code> and <code>RegexUtilities</code> 
— <code>java.util.regex</code> never checks interrupts, so timed-out matches 
previously kept burning pool threads (turning ReDoS into thread/CPU 
exhaustion). Matching now runs over an interrupt-checking 
<code>CharSequence</code>.</li>
   <li><code>IOUtilities</code> upload paths now get the same SSRF protocol 
validation as downloads; <code>ClassUtilities</code> blocked-supertype and 
ClassLoader-leak fixes.</li>
   </ul>
   <p><strong>Correctness</strong></p>
   <ul>
   <li><code>MultiKeyMap</code> — lock-free 
<code>size()</code>/<code>isEmpty()</code> no longer transiently collapse 
toward 0 during a resize.</li>
   <li><code>CaseInsensitiveMap</code>/<code>CaseInsensitiveSet</code> — 
serialization now works, and copy-constructors preserve the source's 
concurrency/ordering.</li>
   <li><code>SafeSimpleDateFormat</code> — <code>clone()</code> no longer 
entangles the copy with the original; serialization fixed.</li>
   <li><code>ConcurrentList</code> deadlock hazard, <code>IntervalSet</code> 
reader atomicity, <code>DeepEquals</code> large-value hash saturation, 
<code>Converter</code> user-override cache masking, and more.</li>
   </ul>
   <p><strong>Performance</strong></p>
   <ul>
   <li>Lock-free read fast paths for <code>ClassUtilities.forName</code> (~51× 
at 8 threads) and the <code>ReflectionUtils</code> caches (~3× at 8 
threads).</li>
   <li><code>CompactMap</code>/<code>CompactSet</code> back to a single 
instance field (memory) with faster <code>equals</code>/<code>hashCode</code>; 
<code>Converter</code> negative-result caching; widespread collection 
presizing.</li>
   </ul>
   <p><strong>API</strong></p>
   <ul>
   <li><code>UrlUtilities</code> is <strong>deprecated, scheduled for removal 
in 5.0</strong> — no ecosystem consumers; prefer 
<code>java.net.http.HttpClient</code> and <code>IOUtilities</code>.</li>
   </ul>
   <p><strong>JDK compatibility:</strong> 8+.</p>
   </blockquote>
   </details>
   <details>
   <summary>Changelog</summary>
   <p><em>Sourced from <a 
href="https://github.com/jdereg/java-util/blob/master/changelog.md";>com.cedarsoftware:java-util's
 changelog</a>.</em></p>
   <blockquote>
   <h4>4.106.0 - 2026-07-04</h4>
   <ul>
   <li><strong>API DEPRECATION</strong>: <strong><code>UrlUtilities</code> is 
deprecated and scheduled for removal in java-util 5.0.</strong> A 
GitHub/GitLab/web code-search sweep found no independent consumer: json-io and 
the rest of java-util do not use it, <code>jdereg/n-cube</code> already 
refactored off it, and the only remaining callers are a dormant 
<code>web-spider</code> (last touched 2019, pinned to java-util 1.34.0) and a 
stale collaborator fork of old n-cube. A dependency-bloat research corpus even 
flags the class as <em>unused</em> where java-util appears transitively. The 
class wraps the legacy <code>HttpURLConnection</code> stack with manual cookie 
stores, an all-trusting 
<code>TrustManager</code>/<code>HostnameVerifier</code>, and global mutable 
user-agent/referrer state. New code should use 
<code>java.net.http.HttpClient</code> (JDK 11+) for HTTP and 
<code>IOUtilities</code> for stream 
transfer/compression/<code>URLConnection</code> input; the naive-SSL and cookie 
he
 lpers have no planned replacement (they are unsafe for production). 
Class-level <code>@Deprecated</code> only in the 4.x line — behavior unchanged; 
the class remains present and functional through 4.x and will be deleted in the 
5.0 major release (removing a public class is a binary-breaking change reserved 
for a major bump).</li>
   <li><strong>DOC / PERFORMANCE</strong>: <code>Traverser</code>'s three 
<code>@deprecated</code> javadocs pointed callers at <code>{@link 
#traverse(Object, Set, Consumer)}</code> — a signature that resolves only to 
the <em>private</em> internal overload, so the suggested replacement was 
uncallable; they now point at the public <code>traverse(Object, Consumer, 
Set)</code>. <code>TrackingMap</code>'s <code>readKeys</code> tracking set is 
presized with load-factor headroom (<code>size/0.75 + 1</code>) so tracking 
every key of a fully-read map never rehashes (<code>new 
HashSet&lt;&gt;(size)</code> under-sizes the table and rehashes at 0.75×size). 
Reviewed <code>TypeUtilities</code> and <code>Unsafe</code> in the same pass — 
no defects found (the type-resolution cache tolerates null values, 
<code>getAllDeclaredFields</code>'s custom-filter path is cache-keyed by the 
stable singleton filter, and <code>Unsafe</code>'s 
ReflectionFactory→sun.misc.Unsafe fallback chain with per-class 
 constructor caching is correct). Note: 
<code>TypeUtilities.ParameterizedTypeImpl.getActualTypeArguments()</code> 
deliberately returns its internal array (documented perf choice; library 
consumers treat it read-only) — left as-is.</li>
   <li><strong>SECURITY</strong>: <strong><code>RegexUtilities</code> timeout 
protection now actually stops runaway matches.</strong> Same defect class fixed 
in <code>DateUtilities</code> earlier this release: 
<code>java.util.regex</code> never checks interrupts, so 
<code>Future.cancel(true)</code> left each timed-out match burning a pool 
thread's CPU until backtracking completed. <code>RegexUtilities</code>' 
executor is <em>bounded</em> (≤8 threads), so a handful of ReDoS inputs 
permanently saturated the pool — after which <strong>every</strong> 
<code>safe*</code> operation failed, including trivial ones (the 
&quot;protection&quot; converted ReDoS into a total regex outage). All five 
timeout-protected operations 
(<code>safeMatches</code>/<code>safeFind</code>/<code>safeReplaceFirst</code>/<code>safeReplaceAll</code>/<code>safeSplit</code>)
 now match over an interrupt-checking <code>CharSequence</code>, so 
cancellation aborts the match promptly and the thread returns to the pool.
  Pinned by a test that fires 10 catastrophic matches (more than the pool's 
thread count) and verifies trivial operations still work — note the attack 
pattern uses sequential unbounded quantifiers, since JDK 9+'s loop memoization 
defuses the classic <code>(a+)+$</code> form. Also fixed the &quot;rejected due 
timeout&quot; message typo.</li>
   <li><strong>BUG FIX</strong>: <strong><code>SafeSimpleDateFormat</code> — 
<code>clone()</code> no longer entangles the copy with the original, and 
serialization works.</strong> The inherited <code>DateFormat.clone()</code> 
made a shallow copy sharing the <code>AtomicReference</code> configuration 
state, so <code>clone.setTimeZone(...)</code> silently reconfigured the 
original (and vice versa); <code>clone()</code> now detaches the state. The 
class has always declared <code>serialVersionUID</code> (with 
<code>DateFormat</code> being <code>Serializable</code>), but its internal 
<code>State</code>/<code>NFSig</code> classes weren't — 
<code>writeObject</code> threw <code>NotSerializableException</code>; both are 
now <code>Serializable</code> and round-trip with pattern/timezone intact. Also 
<code>StreamGobbler._result</code> is now <code>volatile</code>: it's written 
by the gobbler thread and read by the launcher, and <code>Executor</code> joins 
with a <em>deadline</em> — a time
 d-out join read the field with no happens-before edge. And 
<code>SystemUtilities.OS_NAME</code> (public constant) now lowercases with 
<code>Locale.ROOT</code> — under a Turkish default locale, &quot;Windows&quot; 
lowercased to &quot;wındows&quot; (dotless ı), breaking any consumer's 
<code>contains(&quot;windows&quot;)</code> check. Reviewed 
<code>StringUtilities</code> in the same pass — no defects found (the 
equalsIgnoreCase/hashCodeIgnoreCase fold consistency, Levenshtein buffers, and 
repeat() overflow guards are all sound).</li>
   <li><strong>BUG FIX</strong>: 
<strong><code>MultiKeyMap.size()</code>/<code>isEmpty()</code>/<code>longSize()</code>
 no longer transiently collapse toward 0 during a resize.</strong> 
<code>resizeInternal</code> zeroed <code>atomicSize</code> and re-incremented 
it once per entry while rehashing under the all-stripes lock — but the size 
accessors are lock-free, so a concurrent reader could observe <code>isEmpty() 
== true</code> (or any partial count) on a fully populated map mid-resize. The 
entry count is invariant during a resize, so the counter is no longer touched — 
which also removes n atomic RMWs from the global-pause window. Pinned by an 
insert-only reader/writer test asserting size monotonicity across multiple 
resizes. Also fixed a wrong-variable bug in <code>compareObjectArrays</code>' 
large-Set (&gt;6 elements) cross-bucket fallback: it compared 
<code>elem1</code> (the SET_OPEN sentinel at that point) instead of the set 
element being matched, so the hash-collision fallb
 ack could never match (latent — value-aligned hashing keeps equal elements in 
the same bucket for all built-in types, and the sibling methods use the correct 
variable); and presized the 
<code>keySet()</code>/<code>values()</code>/<code>entrySet()</code> snapshot 
containers (previously default-sized, guaranteeing repeated rehash/grow on 
large maps).</li>
   <li><strong>DOC / PERFORMANCE</strong>: 
<code>MapUtilities.mapOf</code>/<code>mapOfEntries</code> javadoc claimed 
<code>NullPointerException</code> for null keys/values — LinkedHashMap 
semantics have always permitted them (java-util is deliberately null-friendly); 
docs now match behavior, pinned by tests. <code>mapOfEntries</code> backing map 
presized with load-factor headroom (was sized to entry count, guaranteeing a 
rehash for any input beyond 12 entries). 
<code>LoggingConfig.UniformFormatter</code> drops the per-log-record 
<code>String.format(&quot;%-5s&quot;, ...)</code> (format-string parse + 
varargs boxing on every record) for manual padding — output byte-identical, 
pinned by test. Reviewed <code>MathUtilities</code> in the same pass — no 
defects found (<code>parseToMinimalNumericType</code>'s mantissa/exponent 
scanning, security-limit caching, and permutation logic are all sound).</li>
   <li><strong>SECURITY / BUG FIX</strong>: <strong><code>IOUtilities</code> 
security checks no longer degrade on Turkish-locale JVMs, and uploads get the 
same SSRF validation as downloads.</strong> All security-relevant case 
conversions used default-locale <code>toLowerCase()</code>: under 
<code>tr-TR</code>, an <code>io.allowed.protocols</code> setting of 
&quot;FILE&quot; lowercased to &quot;fıle&quot; (dotless ı) and never matched a 
URL's &quot;file&quot; protocol (legitimate access blocked), and — worse — 
<code>os.name</code> &quot;Windows…&quot; lowercased to &quot;wındows…&quot;, 
silently disabling every Windows system-path security check 
(<code>system32</code>/<code>syswow64</code>/SAM detection) on Turkish-locale 
Windows machines. All conversions now use <code>Locale.ROOT</code> (same bug 
class fixed in <code>DateUtilities</code> earlier this release). Additionally: 
<code>transfer(File, URLConnection, cb)</code> and 
<code>transfer(URLConnection, byte[])</code> went
  straight to <code>getOutputStream()</code> with no protocol validation — the 
documented SSRF protection only covered the download path; both upload paths 
now validate first. <code>getInputStream</code> no longer leaks the underlying 
connection stream (socket) when the GZIP header read fails; 
<code>uncompressBytes(bytes, offset, len)</code> no longer misclassifies a 
<code>len &lt; 2</code> slice as gzip by reading past the caller's declared 
range (a 1-byte slice of a gzip array now round-trips instead of throwing); 
<code>compressBytes(byte[])</code>/<code>uncompressBytes(byte[])</code> fail 
fast with a clear message on null input instead of a bare NPE from 
<code>bytes.length</code>.</li>
   <li><strong>BUG FIX</strong>: <strong><code>IntervalSet</code> lock-free 
readers can no longer catch covered values transiently uncovered during 
merge/split.</strong> The class documents lock-free reads with writes guarded 
by an internal lock, but <code>addWithMerge</code> and 
<code>removeRangeWithSplitting</code> mutated remove-first: merging 
<code>[0,100)</code> with an overlapping add removed <code>[0,100)</code> from 
the skip-list before putting the merged interval back, so a concurrent 
<code>contains(10)</code> in that window returned <code>false</code> for a 
value covered both before and after the operation (same for the retained 
fragments of a range removal). Mutations now write replacements/fragments 
<em>before</em> removing what they absorb — retained coverage is visible in the 
map's entry union at every instant (in-place value extension for same-key 
merges; right-fragment-then-trim for splits). Final states are byte-identical 
to the old logic (all 141 existing Interval
 Set tests pass unchanged); a reader-vs-writer hammer test pins the 
guarantee.</li>
   <li><strong>BUG FIX / PERFORMANCE</strong>: <code>GraphComparator</code> 
resize/position deltas (<code>LIST_RESIZE</code>, <code>ARRAY_RESIZE</code>, 
<code>ARRAY_SET_ELEMENT</code>, <code>LIST_SET_ELEMENT</code>) truncated 
<code>Long</code>/<code>BigInteger</code> <code>optionalKey</code> values with 
<code>intValue()</code>: 2^32 silently became 0 — clearing the list/array 
instead of failing. Values must now be exactly representable as a non-negative 
<code>int</code>; out-of-range values produce the documented 
<code>DeltaError</code>. Also presized <code>compareSets</code>' two 
id-to-value maps with load-factor headroom (they were sized to element count, 
guaranteeing a rehash mid-comparison for sets over ~12 elements). Reviewed 
<code>IdentitySet</code> and <code>InetAddressUtilities</code> in the same pass 
— no defects found (IdentitySet's DELETED-sentinel probe chains, 
rehash-on-tombstone-buildup trigger, and iterator removal are correct; its 
identity-hash open addressing is 
 sound). — <code>json-io</code> 4.103.0 → 4.105.0 (always trails java-util by 
one release to avoid a dependency cycle); <code>jackson-databind</code> 2.22.0 
→ 2.21.4 — 2.22.0 is the single version covered by the 
<code>@JsonIgnoreProperties</code> case-insensitive-bypass advisory (Dependabot 
<a href="https://redirect.github.com/jdereg/java-util/issues/13";>#13</a>) and 
its fix (2.22.1) is not yet on Maven Central, so this steps back to the latest 
unaffected release; revisit once 2.22.1 ships. Test-scope only — no 
consumer-facing surface. Also <code>central-publishing-maven-plugin</code> 
0.10.0 → 0.11.0. All other dependencies/plugins verified current at their 
latest JDK 8-compatible versions (<code>agrona</code> and <code>mockito</code> 
intentionally pinned).</li>
   <li><strong>BUG FIX / DOC</strong>: Review pass over 
<code>ExceptionUtilities</code>, <code>Executor</code>, 
<code>EncryptionUtilities</code>, and the Fast I/O quartet 
(<code>FastByteArrayInputStream</code>/<code>FastByteArrayOutputStream</code>/<code>FastReader</code>/<code>FastWriter</code>).
 <code>ExceptionUtilities.safelyIgnoreException(Callable, T)</code>: a null 
callable was swallowed by the catch-all and silently returned the default — it 
now throws the documented <code>IllegalArgumentException</code>. 
<code>FastByteArrayOutputStream.write(byte[], off, len)</code>: an invalid 
offset with <code>len == 0</code> bypassed the bounds check via the early 
return; per the <code>OutputStream</code> contract it now throws 
<code>IndexOutOfBoundsException</code>. <code>Executor</code>: the 
<code>envp</code> javadoc (copied from <code>Runtime.exec</code>) claimed a 
non-null environment array replaces the child environment — the 
<code>ProcessBuilder</code>-based implementation has al
 ways <em>merged</em> it into the inherited environment; docs now state the 
merge semantics with an explicit warning not to rely on <code>envp</code> for 
environment isolation (behavior unchanged: strict replacement would break 
<code>PATH</code>-dependent shell resolution). 
<code>FastReader</code>/<code>FastWriter</code>/<code>FastByteArrayInputStream</code>/<code>EncryptionUtilities</code>
 reviewed with no defects found (EncryptionUtilities' weak spots — 
deterministic CBC IV, MD5 key derivation, unauthenticated legacy decrypt 
fallback — are all confined to <code>@Deprecated</code> backward-compatibility 
paths; the modern path is GCM + random salt/IV + PBKDF2).</li>
   <li><strong>BUG FIX</strong>: <strong><code>DateUtilities</code> no longer 
breaks on Turkish-locale JVMs.</strong> Month-name and timezone-abbreviation 
lookups used default-locale 
<code>toLowerCase()</code>/<code>toUpperCase()</code>: under 
<code>tr-TR</code>, &quot;APRIL&quot; lowercases to &quot;aprıl&quot; (dotless 
ı) and missed the month map — <code>parseDate(&quot;APRIL 21st, 
2024&quot;)</code> threw <code>NullPointerException</code> — and 
&quot;ist&quot; uppercased to &quot;İST&quot;, missing the abbreviation map. 
All case conversions now use <code>Locale.ROOT</code>; pinned by tests that run 
under a Turkish default locale.</li>
   <li><strong>SECURITY</strong>: <code>DateUtilities</code> opt-in ReDoS 
timeout protection now actually stops the runaway match: 
<code>java.util.regex</code> never checks interrupts, so 
<code>Future.cancel(true)</code> left each timed-out match burning a pool 
thread's CPU until backtracking completed (and the cached pool grows 
unboundedly under repeated attacks — the &quot;protection&quot; converted ReDoS 
into thread/CPU exhaustion). Matching now runs over an interrupt-checking 
<code>CharSequence</code>, so cancellation aborts the regex promptly; 
post-match <code>group()</code> reads bypass the check and are unaffected.</li>
   <li><strong>PERFORMANCE / BUG FIX</strong>: 
<strong><code>DeepEquals.deepHashCode</code> no longer collapses all large 
floats/doubles into one hash bucket.</strong> The epsilon-alignment 
quantization (<code>Math.round(value * scale)</code>) saturates at the integer 
max: every float above ~21,474 and every double above ~9.2e8 produced the 
identical hash (verified: 30000.0f, 99999.0f, and 1e30f all hashed alike), 
silently degrading unordered collection/map comparison to O(n²) pairwise 
deep-probes for such data. Large magnitudes now quantize relatively 
(mantissa-bit masking at the same ~1e-12/1e-6 relative granularity as 
<code>nearlyEqual</code>); near-equal pairs straddling a mask boundary are 
still matched by the existing cross-bucket fallback, preserving 
correctness.</li>
   <li><strong>BUG FIX</strong>: 
<code>DataGeneratorInputStream.withRandomStrings</code> with 
<code>minWordLen</code> 0 generated an empty word and threw 
<code>ArrayIndexOutOfBoundsException</code> on the first read; bounds are now 
validated up front (<code>minWordLen &gt;= 1</code>, <code>maxWordLen &gt;= 
minWordLen</code>).</li>
   <li><strong>BUG FIX</strong>: <code>ConcurrentList.remove(int)</code> threw 
<code>NoSuchElementException</code> instead of the contractual 
<code>IndexOutOfBoundsException</code> for <code>remove(0)</code> on an empty 
list (it routed through <code>removeFirst()</code>); out-of-range indexes for 
<code>remove(int)</code>/<code>add(int, E)</code> now fail fast with a proper 
bounds check before any delegation. Also <code>equals()</code> no longer 
iterates the other collection while holding this list's read lock — two 
<code>ConcurrentList</code>s comparing against each other while writers were 
queued on both could deadlock (each reader blocked behind the other list's 
queued writer); it now compares against a snapshot. 
<code>remove(Object)</code>/<code>removeLastOccurrence</code> use a single 
direct scan (<code>indexOf</code>/<code>lastIndexOf</code>) instead of 
re-acquiring the read lock per element via <code>get(i)</code>.</li>
   <li><strong>DOC</strong>: <code>ConcurrentList</code> javadoc no longer 
claims lock-free operation: every mutation takes the exclusive write lock and 
reads take the shared read lock (parallel among readers; 
<code>size()</code>/<code>isEmpty()</code> are genuinely lock-free). The 
performance table, advantages, and thread-safety sections now describe the 
actual <code>ReentrantReadWriteLock</code> design. Reviewed 
<code>ConcurrentSet</code> and <code>ConcurrentNavigableSetNullSafe</code> in 
the same pass — no defects found (sentinel handling, <code>toArray</code> race 
guard, and spliterator characteristics in <code>ConcurrentSet</code> are 
correct; <code>ConcurrentNavigableSetNullSafe</code>'s comparator wrapping is 
JDK-consistent).</li>
   <li><strong>MEMORY</strong>: <strong><code>CompactMap</code> is back to a 
single instance field.</strong> The <code>modCount</code> field added in 
February for fail-fast iteration violated the class's design axiom (one 
<code>val</code> field whose type encodes the state) and cost 8 bytes per 
instance after alignment — a 50% object-size overhead multiplied across every 
map json-io allocates. Fail-fast detection now rides on state the map already 
has: structural changes in the array/single/empty states always replace the 
<code>val</code> reference, so iterators identity-compare a snapshot (still 
catching add+remove sequences that leave the size unchanged — the case 
<code>modCount</code> was added for); in MAP state detection is inherited from 
the backing map's own fail-fast iterator, and MAP→array/EMPTY boundary 
transitions replace <code>val</code> and are caught by the snapshot. All six 
concurrent-modification detection tests pass unchanged. Semantics note: 
concurrent backing
  maps (e.g. <code>ConcurrentHashMap</code>) now give weakly-consistent 
MAP-state iteration instead of best-effort CME, matching the backing map's own 
contract.</li>
   <li><strong>BUG FIX / PERFORMANCE</strong>: 
<strong><code>CompactMap.builder().build()</code> is ~15x faster (7.2 → 0.49 
µs) and no longer rewrites live maps' configuration.</strong> Two compounding 
defects in the template-class machinery: (1) the generated-class lookup 
consulted the parent ClassLoader, which can never see classes defined in the 
private template loader — so <em>every</em> build (json-io's 
<code>CompactMap</code>/<code>CompactSet</code> factories build one per 
deserialized instance) constructed and swallowed two 
<code>ClassNotFoundException</code>s, re-cloned and re-patched the 2.7KB 
bytecode template, and re-ran the static-field injection on the already-defined 
class; (2) the config hash used for template-class identity omitted the inner 
map type, so two case-insensitive configs differing only in backing map (e.g. 
<code>HashMap</code> vs <code>ConcurrentHashMap</code>) shared one template 
class — and each rebuild retroactively rewrote the shared class's inj
 ected config, silently changing <code>getNewMap()</code> for all existing 
instances. Lookups now hit the template loader's own cache exception-free, the 
inner map type participates in the hash, and the template constructor is cached 
per class. Also: a non-String <code>singleValueKey</code> no longer crashes 
with a bare <code>ClassCastException</code> during class-name generation.</li>
   <li><strong>PERFORMANCE</strong>: 
<strong><code>CompactSet.equals()</code>/<code>hashCode()</code> no longer 
construct a backing map via reflection per call</strong> — the case-sensitivity 
check went through <code>map.getConfig()</code>, which builds a config map and 
instantiates a throwaway backing map (<code>Class.forName</code> + constructor 
scan for template classes) on every invocation; it now asks the map directly. 
Measured (10-element set): <code>hashCode</code> 227 → 14 ns (~16x), 
<code>equals</code> 312 → ~100 ns (~3x). Also <code>CompactMap</code> iterator 
creation on legacy subclasses (<code>CompactLinkedMap</code>, 
<code>CompactCIHashMap</code>, …) no longer instantiates a throwaway map via 
<code>getNewMap()</code> to decide whether iteration needs sorting — the 
decision is cached per class (single <code>ClassValueMap</code> probe, 
iteration measured at parity); and <code>CompactMap.putAll</code> javadoc 
corrected (null is tolerated as a no-op, not rejected w
 ith NPE as documented).</li>
   <li><strong>PERFORMANCE</strong>: 
<code>ClassValueSet.removeAll</code>/<code>retainAll</code> with a 
<code>ClassValueSet</code> argument probe the argument's backing set directly 
instead of its <code>ClassValue</code>-cached <code>contains()</code> — the 
cached path installed a negative membership entry (a synchronized write into 
the Class's ClassValue map) for every miss, polluting the argument set's cache 
as a side effect of a bulk read.</li>
   <li><strong>BUG FIX</strong>: <strong><code>CaseInsensitiveSet</code> 
serialization actually works now.</strong> The class has always declared 
<code>implements Serializable</code> (with a <code>serialVersionUID</code>), 
but its backing <code>CaseInsensitiveMap</code> never did — so 
<code>ObjectOutputStream.writeObject</code> threw 
<code>NotSerializableException</code> at runtime. 
<code>CaseInsensitiveMap</code> now implements <code>Serializable</code> (its 
cached-view fields were already marked <code>transient</code>, evidence of the 
original intent); both classes round-trip with case-insensitive semantics and 
original key case intact, pinned by tests. Serializability remains conditional 
on the chosen backing map, as with any collection wrapper.</li>
   <li><strong>PERFORMANCE</strong>: <code>CaseInsensitiveSet.addAll</code> 
from another <code>CaseInsensitiveSet</code> bulk-copies already-normalized 
keys through the <code>CaseInsensitiveMap.putAll</code> fast path (skipping 
per-element unwrap/re-wrap and hash recomputation), and the copy-constructor's 
default backing map is presized with load-factor headroom so population never 
rehashes. Also corrected constructor javadoc: null source collections are 
tolerated (create an empty set), not rejected with 
<code>NullPointerException</code> as documented.</li>
   <li><strong>PERFORMANCE</strong>: <strong><code>CaseInsensitiveMap</code> — 
<code>clear()</code>, <code>containsValue()</code>, and <code>values()</code> 
now delegate to the backing map</strong> instead of inheriting 
<code>AbstractMap</code>'s entrySet-routed implementations, which allocated a 
<code>CaseInsensitiveEntry</code> wrapper per element on every scan 
(<code>clear()</code> even removed entries one at a time through the iterator). 
Values are stored unchanged, so direct delegation is semantics-preserving; 
MultiKeyMap-backed instances keep the entrySet route (MultiKeyMap's values view 
has different semantics). Measured (10K entries): <code>containsValue</code> 
miss 34.6 → 21.4 µs (~1.6x), fill+clear cycle 28.3 → 21.5 µs. Also: 
<code>putAll</code> from another <code>CaseInsensitiveMap</code> bulk-copies 
already-normalized keys (skips per-key unwrap/re-wrap); backing maps created by 
the copy constructor/registry are presized with load-factor headroom so 
copy-constructi
 on never rehashes; the <code>copy()</code> bulk path no longer reaches into a 
MultiKeyMap-backed source's internal key representations; removed dead 
<code>convertKeys()</code> and orphaned javadoc blocks from previously-removed 
multi-key methods.</li>
   <li><strong>PERFORMANCE</strong>: 
<code>ByteUtilities.encode</code>/<code>decode</code> no longer read three 
system properties per call when security is disabled (the default) — a single 
master-switch read now gates the limit checks, mirroring the 
<code>ArrayUtilities</code> fix below. <code>encode</code> sits on the 
<code>EncryptionUtilities</code> hash path (every MD5/SHA hex conversion): 
measured 16-byte digest encode 18.8 → 17.0 ns/op single-threaded, 236 → 277 M 
ops/s at 8 threads (~17%); larger on JDK 8 where 
<code>System.getProperty</code> hits a synchronized <code>Hashtable</code>. 
Runtime toggling still honored; also removed the unused 
<code>isSecurityEnabled()</code> helper.</li>
   <li><strong>SECURITY</strong>: <code>ArrayUtilities</code> dangerous-class 
validation can no longer be bypassed with nested array types: 
<code>nullToEmpty(Runtime[].class, …)</code>/<code>toArray(Runtime[].class, 
…)</code> creates a <code>Runtime[][]</code> whose component name 
<code>[Ljava.lang.Runtime;</code> matched neither the exact nor the 
package-prefix patterns. Component types are now unwrapped to their leaf type 
before the pattern check. (Only affects the opt-in 
<code>arrayutilities.security.enabled</code> mode.)</li>
   <li><strong>PERFORMANCE</strong>: 
<code>ArrayUtilities.addAll</code>/<code>addItem</code>/<code>removeItem</code>/<code>toArray</code>/<code>nullToEmpty</code>
 no longer re-read up to 25 system properties per call. The security validators 
consulted three boolean accessors that each rebuilt the five-property config 
snapshot — with security <em>disabled</em> (the default). A single 
master-switch read now gates the validators (runtime toggling still honored): 
measured <code>addAll</code> 33.9 → 13.3 ns/op single-threaded (~2.5x), 167 → 
269 M ops/s at 8 threads; larger on JDK 8 where <code>System.getProperty</code> 
hits a synchronized <code>Hashtable</code>.</li>
   <li><strong>BUG FIX</strong>: 
<code>ArrayUtilities.setElement</code>/<code>setPrimitiveElement</code> on a 
<code>boolean[]</code> silently stored <code>false</code> for any non-Boolean 
element (e.g. <code>&quot;true&quot;</code>, <code>Integer 1</code>); every 
other primitive branch throws <code>IllegalArgumentException</code> for a type 
mismatch. Non-Boolean elements now throw. Also 
<code>addAll</code>/<code>addItem</code> now raise a descriptive 
<code>IllegalArgumentException</code> when the combined length exceeds the JVM 
array limit instead of a bare <code>NegativeArraySizeException</code> from 
<code>int</code> truncation (previously only checked when security was 
enabled), and <code>getArraySubset</code> documents the correct exception 
(<code>IllegalArgumentException</code>, not 
<code>ArrayIndexOutOfBoundsException</code>) for <code>start &gt; 
end</code>.</li>
   <li><strong>BUG FIX</strong>: 
<strong><code>ConcurrentNavigableMapNullSafe</code> — distinct non-Comparable 
keys whose identity hash codes collide no longer silently overwrite each 
other.</strong> With no comparator, same-class non-Comparable keys are ordered 
by <code>System.identityHashCode</code>; identity hashes are 31-bit, so at ~50K 
such keys a collision is more likely than not, and colliding keys compared 
equal — the second <code>put</code> replaced the first with no error. Colliding 
distinct keys now receive stable sequence numbers from a weak-keyed registry 
(Guava <code>Ordering.arbitrary()</code> approach) touched only on actual 
collision, so the common comparison paths are unchanged. Proven by a test that 
manufactures a real identity-hash collision via the birthday bound.</li>
   <li><strong>BUG FIX</strong>: 
<code>AbstractConcurrentNullSafeMap.equals()</code> (affects 
<code>ConcurrentHashMapNullSafe</code>, 
<code>ConcurrentNavigableMapNullSafe</code>) returned <code>true</code>/threw 
depending on the other map: comparing a map holding a <code>null</code> key 
against a null-hostile map (<code>ConcurrentHashMap</code>, 
<code>Hashtable</code>, <code>TreeMap</code>) threw 
<code>NullPointerException</code> from <code>other.get(null)</code> instead of 
returning <code>false</code>. Now guarded with the same 
<code>ClassCastException</code>/<code>NullPointerException</code> handling as 
<code>AbstractMap.equals</code>.</li>
   <li><strong>BUG FIX</strong>: 
<code>AbstractConcurrentNullSafeMap.computeIfAbsent</code> removed an existing 
<code>key → null</code> mapping when the mapping function returned null; JDK 
semantics (<code>HashMap</code>, <code>Map</code> default method) retain the 
entry — only new mappings are suppressed. <code>containsKey</code> no longer 
flips to <code>false</code>. Also <code>compute()</code> now fails fast on a 
null remapping function like its siblings, and the 
<code>ConcurrentHashMapNullSafe(Map)</code> copy constructor no longer 
double-compensates for the load factor (which could allocate a 2x-sized 
table).</li>
   <li><strong>API REMOVAL</strong>: <code>MapUtilities.cloneMapOfSets</code> 
and <code>MapUtilities.cloneMapOfMaps</code> removed. Despite the &quot;deep 
clone&quot; javadoc, the <code>immutable=true</code> variants returned 
unmodifiable <em>views</em> over the original inner collections — mutations to 
the source showed through the &quot;clone,&quot; making them a defensive-copy 
trap. No known consumers (json-io and the rest of the Cedar ecosystem never 
used them); <code>dupe()</code> remains and does copy-then-wrap correctly.</li>
   <li><strong>PERFORMANCE</strong>: <strong>Six of the seven 
<code>ReflectionUtils</code> caches switched from the LOCKING to the THREADED 
LRU strategy</strong> (method, field-name, constructor, sorted-constructors, 
class-annotation, method-annotation). These are populate-once and 
read-almost-always, yet the LOCKING strategy's <code>get()</code> takes the 
cache's exclusive <code>ReentrantLock</code> via <code>tryLock()</code> to 
reorder its LRU list on every hit; even non-blocking, that CAS on one shared 
lock word ping-pongs the cache line across cores, so concurrent reflection 
barely scaled (measured 8 threads ≈ 1 thread). THREADED <code>get()</code> is 
lock-free (<code>ConcurrentHashMap</code>-backed, sampled background eviction): 
<strong>~1.3x single-threaded and ~3x at 8 threads</strong> (35M → ~110M 
lookups/s on a 12-core box) for the shared 
<code>getMethod</code>/<code>getField</code> hot path json-io hammers during 
multi-threaded (de)serialization. (<code>FIELDS_CACHE</co
 de> intentionally stays on LOCKING — see below.) All THREADED caches share one 
daemon cleanup thread, so no per-cache threads are added.</li>
   <li><strong>CORRECTNESS</strong>: 
<strong><code>ThreadedLRUCacheStrategy</code> recency tracking was frozen — the 
&quot;LRU&quot; cache actually evicted FIFO.</strong> 
<code>Node.updateTimestamp()</code> gated its refresh on the node's own stored 
timestamp (<code>this.timestamp &amp; 0x7</code>), but once a node's timestamp 
landed on a non-multiple-of-8 value — 7/8 of the time, immediately — the gate 
was false forever and the timestamp never advanced again regardless of access. 
So recency was pinned at insertion time: a hot-but-old entry was evicted ahead 
of cold, recently-inserted ones (measured: a key accessed 50,000× survived 
sample-eviction in <strong>0/40</strong> trials). Fixed by gating on a 
per-access <code>ThreadLocalRandom</code> draw (contention-free), restoring 
true ~12.5%-sampled LRU (<strong>40/40</strong>). This is why the 
reflection-cache speedup above is ~3x rather than the ~10x an earlier build 
showed — that build's higher number came from this bug (froz
 en timestamps mean zero recency-write contention); correct LRU touches the 
shared recency clock on ~1/8 of hits, which is the right trade for an 
eviction-correct cache and still clears LOCKING by ~3x.</li>
   <li><strong>CORRECTNESS</strong>: <code>ReflectionUtils.FIELDS_CACHE</code> 
kept on the LOCKING strategy (the other six moved to THREADED). Its deep 
variant (<code>getAllDeclaredFields</code>) populates the cache from inside its 
own <code>computeIfAbsent</code> mapping by calling 
<code>getDeclaredFields</code>, which does <code>computeIfAbsent</code> on the 
<strong>same</strong> cache. LOCKING uses a reentrant lock and tolerates that 
same-thread nesting; THREADED delegates to 
<code>ConcurrentHashMap.compute()</code>, whose nested update on the same map 
throws <code>IllegalStateException(&quot;Recursive update&quot;)</code> when 
the two keys collide in a bin (reproduced: a cold 
<code>getAllDeclaredFields</code> sweep threw intermittently).</li>
   <li><strong>BUG FIX</strong>: <code>ReflectionUtils.isTrustedCaller()</code> 
(dangerous-class security gate) now recognizes cache-infrastructure stack 
frames even when they are lambda/inner-class frames 
(<code>Owner$$Lambda...</code>), and includes 
<code>AbstractConcurrentNullSafeMap</code>. The THREADED cache invokes the 
security check from inside a <code>com.cedarsoftware.util.*</code> 
cache-internal lambda; the previous exact-<code>equals</code> frame check would 
have mis-read that lambda as a trusted java-util caller and bypassed the 
dangerous-class block for external callers. (This tightens the trusted set — 
strictly safer — and only matters when the opt-in security features are 
enabled.)</li>
   <li><strong>ROBUSTNESS</strong>: 
<code>ReflectionUtils.getClassNameFromByteCode</code> throws its documented 
<code>IllegalStateException</code> instead of a 
<code>NegativeArraySizeException</code> when given a malformed class file whose 
<code>constant_pool_count</code> is 0.</li>
   <li><strong>BUG FIX</strong>: <strong><code>Converter</code> user 
conversions can no longer be silently masked by the shared resolution 
cache.</strong> <code>convert()</code> and 
<code>isConversionSupportedFor()</code> consulted the static 
<code>FULL_CONVERSION_CACHE</code> <em>before</em> the instance's user 
conversions, so (a) an override supplied via 
<code>ConverterOptions.getConverterOverrides()</code> was ignored for any 
(source, target) pair previously converted by ANY plain Converter instance in 
the JVM (json-io's default converter populates this cache constantly, so in 
practice constructor overrides for built-in pairs never fired), and (b) an 
<code>addConversion()</code> override worked only until any plain instance 
converted the same pair and repopulated the shared cache — after which the 
override instance silently reverted to the built-in conversion 
(order-dependent, race-prone). This also affected the static 
<code>Converter.addConversion()</code> facade API. User conv
 ersions (guarded by a flag, so the no-override hot path is unchanged — 
verified ~8 ns/op cache hits before and after) are now consulted first, per the 
documented precedence.</li>
   <li><strong>BUG FIX</strong>: <code>Converter</code> — overrides supplied 
via <code>ConverterOptions</code> now receive the same primitive/wrapper 
variation expansion as <code>addConversion()</code>: an override registered 
with <code>int.class</code> also fires for <code>Integer.class</code> lookups 
and vice versa. Previously only the exact registered pair matched, so the 
unregistered variant silently fell through to the built-in conversion.</li>
   <li><strong>PERFORMANCE</strong>: <code>Converter</code> negative lookup 
results are now actually cached. <code>isConversionSupportedFor()</code> always 
intended to cache &quot;unsupported&quot; results, but the cache-write helper 
silently refused the UNSUPPORTED sentinel, so every repeated miss re-walked the 
full inheritance pair list — and json-io's <code>Resolver</code> probes these 
per value during graph resolution. Misses now resolve O(1) after first check: 
measured 41–52 → 4–8 ns/op (shallow hierarchy; deep hierarchies benefit far 
more). Safe with the precedence fix above: instances holding user conversions 
check their own conversions before trusting a shared negative, and 
<code>addConversion()</code> purges affected entries.</li>
   <li><strong>PERFORMANCE</strong>: 
<code>Converter.getInheritedConverter</code> skips the guaranteed-empty 
user-conversion probe per inheritance pair on instances with no user 
conversions (the common case), halving map lookups on the 
inheritance-resolution walk.</li>
   <li><strong>PERFORMANCE</strong>: <strong>Lock-free fast path for the 
<code>ClassUtilities.forName</code> name cache.</strong> The per-ClassLoader 
class-name cache sits behind a synchronized <code>WeakHashMap</code>, so every 
<code>forName()</code> hit — the json-io <code>@type</code>-resolution hot path 
— took one global lock, which didn't just cap concurrency, it inverted it 
(measured 12-core: 1 thread ≈ 123 M ops/s, 8 threads ≈ 22 M ops/s 
<em>aggregate</em>). A one-entry (loader → cache) memo, identity-checked and 
held via <code>WeakReference</code> so it never pins a ClassLoader, now fronts 
the map: 8 threads <strong>22 M → ~1.1 B ops/s (~51×)</strong>, single-thread 
<strong>123 → ~188 M ops/s (~1.5×)</strong>. <code>clearCaches()</code> drops 
the memo with the map; per-loader isolation is pinned by new tests.</li>
   <li><strong>BUG FIX</strong>: <code>ClassUtilities.newInstance</code> — 
array-typed constructor parameters now default to an <strong>empty array of the 
correct type</strong>. Every Java array implements <code>Cloneable</code>, so 
the assignable-interface scan in the default-value lookup matched 
<code>Cloneable → ArrayList</code> for any array type outside the direct map 
(e.g. <code>Date[]</code>, <code>String[][]</code>), a type-incompatible 
default that forced the first constructor pass to fail and fall back to 
<code>null</code>; the intended empty-array branch was unreachable.</li>
   <li><strong>BUG FIX</strong>: <code>ClassUtilities.newInstance</code> 
argument matching passed <code>(target, source)</code> to 
<code>Converter.isSimpleTypeConversionSupported(source, target)</code> — 
swapped. Mostly masked because the simple-type matrix is largely bidirectional, 
but direction-specific registrations (e.g. user converter overrides, one-way 
conversions) were judged backwards in the convertible-match phase.</li>
   <li><strong>SECURITY</strong>: <code>ClassUtilities.SecurityChecker</code> 
hierarchy check now consults the blocked-<strong>name</strong> list for 
supertypes as well as the blocked-class set. Previously a class that merely 
extends/implements a blocked-by-name type (e.g. a subclass of 
<code>javax.script.ScriptEngineManager</code>, or a 
<code>javax.script.ScriptEngine</code> implementation) passed 
<code>verifyClass()</code> because only its own name was compared; loading such 
a type by its blocked name would have been refused.</li>
   <li><strong>SECURITY / ROBUSTNESS</strong>: 
<code>ClassUtilities.forName</code> catches <code>LinkageError</code> (e.g. 
<code>ClassFormatError</code>, <code>UnsupportedClassVersionError</code>, 
<code>NoClassDefFoundError</code> from a broken dependency) and returns 
<code>null</code> per its contract, instead of letting an <code>Error</code> 
raised by a bad — possibly attacker-supplied — type name escape and kill the 
calling thread.</li>
   <li><strong>MEMORY LEAK</strong>: 
<strong><code>ClassUtilities.SecurityChecker</code> no longer pins every 
verified class — and its ClassLoader — for the JVM's lifetime.</strong> The 
security-verdict path recorded each checked class in two static 
strong-reference <code>ClassValueSet</code> memo caches 
(<code>VERIFIED_SAFE_CLASSES</code> / <code>INHERITS_FROM_BLOCKED</code>). 
Those sets could never produce a hit the fronting <code>ClassValue</code> 
verdict cache wouldn't — the verdict computes at most once per 
<code>Class</code> lifetime, and a re-loaded class is a new identity that must 
be re-verified — but because <code>verifyClass</code> runs unconditionally in 
<code>newInstance</code>, every class instantiated through 
<code>ClassUtilities</code>/json-io was retained forever, surviving even 
<code>clearCaches()</code>, leaking ClassLoaders in redeploy/dynamic-class 
environments. Removed the memo sets (the <code>ClassValue</code> entries live 
inside each <code>Class</code>
  and pin nothing); proven by a disposable-ClassLoader GC test that fails 
before and passes after. Also folded <code>ASSIGNABLE_TYPE_CACHE</code> (keyed 
by arbitrary constructor argument types) into <code>clearCaches()</code> — it 
was the one remaining per-user-class static cache with no release path — and 
documented the strong-retention trade-off of long-lived sets in 
<code>ClassValueSet</code>'s javadoc.</li>
   <li><strong>BUG FIX</strong>: 
<strong><code>CollectionUtilities.deepCopyContainers</code> silently lost 
elements when copying sets of collections.</strong> Element copies were 
inserted into content-sensitive parent collections (<code>LinkedHashSet</code>, 
<code>TreeSet</code>, <code>PriorityQueue</code>) while still empty — the 
iterative work queue fills them later — so two distinct-but-unfilled containers 
compared equal and were deduplicated (runtime-proven: a <code>Set</code> of two 
lists copied to a one-element set, same for <code>TreeSet</code> with a content 
comparator; content-inspecting comparators could also throw on the empty 
shells, and <code>PriorityQueue</code> heaps were built from wrong 
comparisons). Elements destined for such targets are now buffered and installed 
after the whole graph is copied, children before parents; pure cycles fall back 
deepest-first, and <code>EnumSet</code> still fills directly (enum elements are 
berries, never copies). Also affects the 
 <code>ArrayUtilities.deepCopyContainers</code> delegate. While there: 
<code>setOf</code> presizes its <code>LinkedHashSet</code> with load-factor 
headroom so construction never rehashes (the old <code>new 
LinkedHashSet&lt;&gt;(n)</code> rehashed for power-of-2 sizes).</li>
   <li><strong>BUG FIX / FEATURE</strong>: 
<strong><code>CompactMap.builder()</code> / <code>newMap()</code> no longer 
refuse to run on a JRE.</strong> Both entry points still guarded on 
<code>javax.tools.JavaCompiler</code> being present — vestigial from the old 
javac-based implementation — and threw <code>IllegalStateException</code> in 
JRE-only environments, even though the current implementation patches a 
pre-compiled bytecode template and needs no compiler at all (the class javadoc 
already promised &quot;works on both JDK and JRE&quot;). Guards removed, docs 
reconciled; proven with a simulated-JRE test 
(<code>java.util.force.jre</code>).</li>
   <li><strong>BUG FIX</strong>: <strong><code>CompactMap</code> got 
permanently stuck in backing-MAP state when a null-valued key was removed at 
the downsize boundary.</strong> <code>removeFromMap</code> judged key presence 
by calling <code>containsKey</code> <em>after</em> <code>map.remove()</code> — 
which can never distinguish &quot;was absent&quot; from &quot;was present 
mapped to null&quot; — so removing a null-valued mapping returned early and 
skipped the MAP→array (at <code>compactSize</code>) and →EMPTY transitions. 
Since the array transition only fires exactly at the boundary, missing it once 
meant the map never compacted again (defeating the point of the class). 
Presence is now judged by size delta.</li>
   </ul>
   <!-- raw HTML omitted -->
   </blockquote>
   <p>... (truncated)</p>
   </details>
   <details>
   <summary>Commits</summary>
   <ul>
   <li><a 
href="https://github.com/jdereg/java-util/commit/229429fd54c90da194c3c1171920443557b3f6ff";><code>229429f</code></a>
 Docs: set 4.106.0 changelog date to release date 2026-07-04</li>
   <li><a 
href="https://github.com/jdereg/java-util/commit/2e368f2dccc840309c76b856ebb897b988880966";><code>2e368f2</code></a>
 Build: remove unused jackson-databind test dependency (resolves Dependabot <a 
href="https://redirect.github.com/jdereg/java-util/issues/14";>#14</a>)</li>
   <li><a 
href="https://github.com/jdereg/java-util/commit/90ed990587e2fbedc993ecc7d3f241d74b21913a";><code>90ed990</code></a>
 Docs: infographic + README — CaseInsensitiveMap, 1,800+ conversions, JDK 8+, 
...</li>
   <li><a 
href="https://github.com/jdereg/java-util/commit/aa4544399e398e7ec16128c404ef98549f0513e3";><code>aa45443</code></a>
 Deprecate UrlUtilities for removal in 5.0</li>
   <li><a 
href="https://github.com/jdereg/java-util/commit/c297aa05b8ec880eb9e517298455f36ee5ff484c";><code>c297aa0</code></a>
 Doc/Perf: Traverser deprecation links; TrackingMap readKeys presize</li>
   <li><a 
href="https://github.com/jdereg/java-util/commit/8c1c674885d2d78af64658ea88a2ebe8dd5a0765";><code>8c1c674</code></a>
 Bug Fix: RegexUtilities ReDoS pool starvation; SafeSimpleDateFormat 
clone/ser...</li>
   <li><a 
href="https://github.com/jdereg/java-util/commit/bbeb7cc5f345c70429acee008613a1462020a7ee";><code>bbeb7cc</code></a>
 Bug Fix: MultiKeyMap resize size-collapse; MapUtilities/LoggingConfig 
cleanups</li>
   <li><a 
href="https://github.com/jdereg/java-util/commit/38f77665e67fd41b0e7ba61e4f3a292c10343f2e";><code>38f7766</code></a>
 Bug Fix: IOUtilities locale + SSRF upload gap; IntervalSet reader atomicity; 
...</li>
   <li><a 
href="https://github.com/jdereg/java-util/commit/6a3b8b9998af84f0b42c525d15b0f852032dab34";><code>6a3b8b9</code></a>
 Test: pin CaseInsensitiveSet/Map copy-constructor backing dispatch</li>
   <li><a 
href="https://github.com/jdereg/java-util/commit/4f9cb262f7825fa4995ce83ca648822786bd7ace";><code>4f9cb26</code></a>
 Harden CaseInsensitiveMap/Set against double-wrapping</li>
   <li>Additional commits viewable in <a 
href="https://github.com/jdereg/java-util/compare/4.105.0...4.106.0";>compare 
view</a></li>
   </ul>
   </details>
   <br />
   
   
   [![Dependabot compatibility 
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.cedarsoftware:java-util&package-manager=maven&previous-version=4.105.0&new-version=4.106.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
   
   Dependabot will resolve any conflicts with this PR as long as you don't 
alter it yourself. You can also trigger a rebase manually by commenting 
`@dependabot rebase`.
   
   [//]: # (dependabot-automerge-start)
   [//]: # (dependabot-automerge-end)
   
   ---
   
   <details>
   <summary>Dependabot commands and options</summary>
   <br />
   
   You can trigger Dependabot actions by commenting on this PR:
   - `@dependabot rebase` will rebase this PR
   - `@dependabot recreate` will recreate this PR, overwriting any edits that 
have been made to it
   - `@dependabot show <dependency name> ignore conditions` will show all of 
the ignore conditions of the specified dependency
   - `@dependabot ignore this major version` will close this PR and stop 
Dependabot creating any more for this major version (unless you reopen the PR 
or upgrade to it yourself)
   - `@dependabot ignore this minor version` will close this PR and stop 
Dependabot creating any more for this minor version (unless you reopen the PR 
or upgrade to it yourself)
   - `@dependabot ignore this dependency` will close this PR and stop 
Dependabot creating any more for this dependency (unless you reopen the PR or 
upgrade to it yourself)
   
   
   </details>


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to