RELEASE NOTES

Chilkat v11.6.0

New platforms · AI tooling · MCP · dozens of fixes

This release adds several major new capabilities — Chilkat for B4X, cross-platform Delphi DLL and Lazarus / Free Pascal editions, Model Context Protocol (MCP) support, AI structured output and web search, and Argon2 password hashing — along with a broad set of fixes and improvements across the crypto, email, HTTP/REST, and text-processing classes.

✨ Release Highlights

AreaWhat’s new
🧩 New platformsChilkat for B4X (B4A + B4J), cross-platform Delphi DLL (Linux, macOS, iOS, Android, Win-ARM), and Lazarus / Free Pascal
🤖 AIMCP client + Ai.UseMcp, JSON-Schema structured output, provider-hosted web search
🔐 CryptoArgon2 (id/i/d) password hashing & key derivation in Crypt2
🛡️ ReliabilityStrict JSON/XML loading, StringBuilder.IsWellFormed, secrets-aware unlock & JSON load
🧰 FixesJWE, JWS, MIME, PrivateKey/PublicKey, Socket, IMAP, REST, HtmlToText, PCRE2

✨ New Features & Additions

📱 Chilkat for B4X (B4A and B4J)

Chilkat is now available for B4X: B4A (Android) and B4J (Windows, Linux, macOS).

  • One download, two librariesChilkatB4A.jar and ChilkatB4J.jar (each with its .xml), installed by copying into the IDE’s additional-libraries folder.
  • Familiar, prefixed classes — every Chilkat class appears as a Chilkat-prefixed B4X type (ChilkatHttp, ChilkatCrypt2, ChilkatZip, …) with full IDE autocomplete. The API is identical in B4A and B4J, so code moves between them unchanged.
  • Self-contained jars — native libraries for all supported CPUs are inside: packaged into the APK automatically on Android (armeabi-v7a, arm64-v8a, x86, x86_64; 16 KB-page aligned), and loaded automatically on the desktop (Windows x64, Linux x86_64/arm64/arm, macOS Intel and Apple Silicon).
  • Progress events — long-running calls raise the standard AbortCheck, PercentDone, and ProgressInfo events as ordinary B4X event Subs.
  • Requirements — Android 7.0+ (minSdkVersion 24) on B4A; Java 8+ on B4J.

🧡 Chilkat for Lazarus / Free Pascal

Chilkat is now available for Lazarus / Free Pascal (FPC) — a fully generated Object Pascal API in which each Chilkat class is wrapped by its own self-contained Pascal unit (Chilkat.Http.pas, Chilkat.Zip.pas, …), each providing a Pascal class (THttp, TZip, …) derived from TChilkatBase.

  • No compile-time linking — the units resolve all functions at runtime from the native Chilkat C bridge library via CkDllLoader.pas.
  • Plain Pascal stringsstring throughout; UTF-8 conversion is handled internally.
  • No circular uses — object parameters and return values are typed as TChilkatBase, so you add only the units you actually use.

Supported platforms (the chilkat_c_bridge runtime library):

OSArchitectures
Windowsx86, x64, ARM64
Linuxx86_64, arm64, x86, armhf
macOSUniversal (Apple Silicon + Intel)

CkDllLoader.pas selects the correct library for the current OS and architecture automatically, and a custom load path can be specified.

uses
  Chilkat.Base, Chilkat.Http;
var
  http: THttp;
begin
  http := THttp.Create;
  if not http.IsValid then
    raise Exception.Create('Failed to load the Chilkat library.');
  WriteLn(http.QuickGetStr('https://www.example.com/'));
  http.Free;
end;

Event-capable classes provide the three synchronous callbacks as Pascal of object event properties — OnAbortCheck, OnPercentDone, and OnProgressInfo (handler types declared in Chilkat.Base.pas). The HeartbeatMs property controls OnAbortCheck frequency, and returning True from OnAbortCheck or OnPercentDone aborts the running method.

⚙️ Scope synchronous API only: no async (*Async) variants, and no Task / TaskChain classes.

🔷 Chilkat Delphi DLL — Now Cross-Platform

The Chilkat Delphi DLL API, previously available only as a Windows 32-bit/64-bit DLL, is now provided as a native library for every major Delphi target. The same flat API (CkHttp_QuickGetStr, CkZip_Unzip, …) that Delphi applications call on Windows can now be used unchanged in FireMonkey (FMX) applications on Linux, macOS, iOS, and Android, and on Windows-on-ARM devices.

PlatformDelivered as
Linuxshared libraries for x86_64 and arm64
macOSa universal (Apple Silicon + Intel) dylib, code-signed with a Developer ID certificate and secure-timestamped for notarization
iOSa static library linked directly into the application, per Apple’s requirements for device deployment
Androidnative libraries for the standard Android ABIs
Windows on ARMa new ARM64 (ARM64EC) DLL — native ARM code on Windows-on-ARM devices, including within existing x64 Delphi apps running under emulation

🤖 Model Context Protocol (MCP)

Chilkat v11.6.0 adds support for the Model Context Protocol (MCP) — an open protocol that standardizes how applications provide tools, resources, and prompts to AI models. This release introduces a new Mcp class (an MCP client) and integrates MCP tools into the existing Ai class through a new UseMcp method.

New class: Mcp

The Mcp class connects to an MCP server and gives an application unified access to the server’s tools, resources, and prompts. It uses the MCP Streamable HTTP transport (protocol version 2025-06-18): a single endpoint URL handles the JSON-RPC exchange over HTTP POST, and a server response may arrive either as a single JSON object or as a Server-Sent-Events stream — both handled transparently. The stdio transport is not supported in this release.

CapabilityDetails
ConnectingConnect performs the MCP initialize handshake, then SessionId, ProtocolVersion, ServerName, ServerVersion, and ServerInstructions are populated and Connected is true. Chilkat sends the MCP-Protocol-Version and Mcp-Session-Id headers automatically; Close terminates the session (HTTP DELETE).
ToolsListTools returns each tool’s name, description, and inputSchema; CallTool invokes a tool by name and returns its content array and isError flag. A tool that runs but reports failure returns success with isError true.
Resources & promptsListResources / ReadResource (text or base64 blob) and ListPrompts / GetPrompt.
Auth & settingsAuthToken for a bearer token; SetConnectionSettings copies proxy, bind-IP, and TLS options from a Socket. Timeouts via IdleTimeoutMs (180000) and ConnectTimeoutMs (30000); HeartbeatMs controls the AbortCheck interval.

MCP tools in the Ai class: UseMcp

Mcp mcp;
mcp.Connect("https://example.com/mcp");

Ai ai;
ai.put_Provider("openai");
ai.put_ApiKey(myKey);
ai.put_Model("gpt-5.1");
ai.NewConvo("chat","You are a helpful assistant","");

// Register the MCP server's tools with the model.
ai.UseMcp(mcp,"myserver");

ai.InputAddText("Use the available tools to answer: ...");
ai.Ask("text");

UseMcp registers the connected server’s tools with the model, namespacing each tool name with the supplied prefix so tools from different servers (and JavaScript tools) cannot collide. Because MCP tools are presented as ordinary function tools, UseMcp works with every provider the Ai class supports — OpenAI, Anthropic Claude, Google Gemini, xAI Grok, Mistral, and Perplexity. When the model requests a tool during an Ask, Chilkat automatically routes the call via Mcp.CallTool, adds the result to the conversation, and continues — no application code is required to run the tool. This works in both the standard Ask and in streaming mode (surfacing as a js_function_call event handled by StreamingJsToolCall). An informational ProgressInfo event named McpToolCall is emitted before each automatic MCP tool call.

📝 Notes Automatic tool use requires a selected conversation (not a stateless query). The Mcp object passed to UseMcp must remain connected and valid for as long as its tools are used.

🎯 Ai — Structured Output (JSON Schema)

Supply a JSON Schema and the AI model returns a response that conforms to it — ideal for reliable data extraction and function-argument generation.

Call SetOutputSchema(name, schema, strict) to request schema-constrained output, then retrieve the parsed result with GetOutputJson. The same code works across OpenAI, Anthropic Claude, Google Gemini, xAI Grok, Mistral, and Perplexity — Chilkat translates your one schema into each provider’s native format. When strict is enabled, Chilkat automatically augments the schema (adding additionalProperties: false and required-property lists) for the providers that need it. Refusals are surfaced distinctly via the LastResponseRefused and RefusalText properties.

📘 See Chilkat AI Structured Output for full details, the provider-support matrix, and examples.

🔎 Ai — Web Search

Unified, provider-hosted web search for the Ai class. When enabled, the AI provider performs a live web search while generating its response and answers using the retrieved results, returning citations. A single Chilkat API drives web search across providers, so the same application code works whether the provider is OpenAI, Anthropic Claude, Google Gemini, xAI Grok, or Perplexity.

Enabling web search — turned on per-request through a new web_search object passed to SetAskParams. Only enabled is required; every other field is optional, and Chilkat silently ignores fields a given provider does not support.

{
  "web_search": {
    "enabled": true,
    "max_uses": 3,
    "allowed_domains": [ "wikipedia.org", "nasa.gov" ],
    "blocked_domains": [ ],
    "recency": "week",
    "user_location": {
      "country": "US",
      "city": "Chicago",
      "region": "Illinois",
      "timezone": "America/Chicago"
    }
  }
}
FieldMeaning
enabledTurns web search on for the Ask. For Perplexity, search is always on (no-op).
max_usesMaximum searches the model may perform — the primary cost-control knob.
allowed_domains / blocked_domainsRestrict results to, or exclude, specific domains.
recencyLimit results by age: day, week, month, or year.
user_locationOptional country, city, region, timezone to localize results.

Retrieving the sources — a new GetSearchResults method returns the sources the model used in the most recent Ask, normalizing each provider’s citation format into one flat structure (url, title, snippet, page_age). The complete, unmodified provider response remains available via GetLastJsonData. Streaming — when Streaming is enabled, a standardized web_search_call event is delivered through NextAiEvent while the provider searches.

Provider support:

Fieldopenaiclaudegooglexaiperplexity
enabledYesYesgroundingYesalways on
max_usesYesmax results
allowed_domainsYesYesYesYes
blocked_domainsYesYesYes
recencydate rangeYes
user_locationYesYes

📝 Notes Google Gemini web search (grounding) is available only through the native Gemini API, not the OpenAI-compatible path. deepseek and mistral (chat) have no web-search tool: if web_search is set, the Ask proceeds without search and a note is written to LastErrorText, so provider-switching code degrades gracefully. Most providers bill web searches separately from tokens — use max_uses to bound per-request cost.

🔐 Crypt2 — Argon2

Chilkat now implements Argon2, the memory-hard password hashing and key-derivation function specified in RFC 9106 and winner of the Password Hashing Competition. All three variants are supported: Argon2id (the recommended default), Argon2i, and Argon2d. Its memory cost makes large-scale cracking on GPUs and custom hardware impractical, which is why Argon2 is now the recommended choice over PBKDF2 and bcrypt for new applications.

MethodPurpose
Argon2DeriveKeyDerives a key of any length from a password (for encryption keys and other key-derivation uses).
Argon2HashPasswordHashes a password for storage, returning a PHC-format string such as $argon2id$v=19$m=65536,t=3,p=1$<salt>$<hash>. A random salt is generated automatically.
Argon2VerifyPasswordVerifies a password against a stored PHC-format hash. All parameters are read from the stored hash.

Options are passed as a JSON string rather than many new properties. Every member is optional — an empty string uses defaults suitable for password hashing (Argon2id, version 19, 3 iterations, 64 MB memory, 32-byte hash, 16-byte random salt):

{
  "variant": "argon2id",
  "iterations": 3,
  "memoryCostKb": 65536,
  "parallelism": 1,
  "keyLen": 32,
  "salt": "cmFuZG9tc2FsdDEyMzQ="
}

The short RFC 9106 / PHC parameter names (t, m, p, v) are accepted as aliases, and the optional RFC 9106 secret (a pepper) and associated data inputs are supported.

  • Hash strings are standard PHC format and interoperate with other Argon2 implementations in both directions.
  • If a stored hash string is malformed, Argon2VerifyPassword returns false and LastMethodSuccess is false, distinguishing a bad hash string from a wrong password.
  • A maxMemoryKb option caps allocation — important when verifying hashes from an untrusted source, since the memory cost is read from the stored string.
  • Version 0x10 (16) hashes can be verified for compatibility; new hashes use version 0x13 (19).

🔑 Secrets-Aware Methods

Chilkat.Global.UnlockBundle and JsonObject.Load are now secrets aware. Each can accept a secret specification string (beginning with !!) in place of a literal value, and Chilkat resolves it from the Windows Credential Manager (Windows) or Apple Keychain (macOS). Secrets are identified by the structured format !![appName|]service[|domain]|username, letting applications resolve credentials at runtime instead of embedding them in code.

📝 There is no EnableSecrets property — UnlockBundle is always secrets aware. If the secret is not present in a local manager, the spec is used as-is, causing UnlockBundle to either fail or succeed in trial mode.

🧪 Strict Loading for Xml and JsonObject

Chilkat’s XML and JSON parsers are deliberately tolerant: given input that is not well-formed they parse what they can, report success, and leave a partially populated document. That is the wrong behavior when a silently dropped element or member changes what the application does. Both classes now have a Strict property that closes this off.

PropertyBehavior when true
Xml.Strict
(default false)
Checks the input is well-formed XML before parsing; on failure the load fails and the object is left unchanged. Applies to LoadXml, LoadXml2, LoadSb, LoadBd, LoadXmlFile, LoadXmlFile2. (Well-formedness only, not validating.)
JsonObject.Strict
(default false)
Validates the text against the full JSON grammar first; on failure leaves existing contents unchanged. Applies to Load, LoadSb, LoadBd, LoadFile, LoadPredefined.

Both default to false, so existing applications are unaffected. Turn Strict on for input carrying configuration, credentials, signed content, or security parameters.

✔️ StringBuilder.IsWellFormed

A new method, IsWellFormed(format), returns true if the contents of the StringBuilder are well-formed JSON or XML. The format argument must be "json" or "xml" (case insensitive). It answers the question the tolerant parsers do not — about text already in hand, with no JsonObject or Xml object created first.

sb.LoadFile("config.json","utf-8");
if (!sb.IsWellFormed("json")) {
    // the file is not well-formed JSON
}

For "json", the full RFC 8259 grammar is checked; for "xml", XML 1.0 well-formedness (the same checks Strict applies). Empty contents are not well-formed. The contents are never modified, and deeply nested input is rejected at a nesting limit of 256 (validation is iterative, so no depth can exhaust the call stack).

📊 HtmlToText — Table Rendering

HtmlToText now renders HTML tables as fixed-width text tables. Previously a <table> was converted by placing each cell on its own line, losing the row-and-column relationship; tables are now drawn as aligned, bordered text tables that preserve the original structure. No code changes are required to benefit.

⚠️ Output change because this changes the text produced for tables, review the notes below if your application compares HtmlToText output against saved or expected strings.

  • Rows and columns preserved — drawn with | separators and +/- borders, every column aligned.
  • Header rows set apart<th> cells are centered and underlined with a row of =.
  • Columns sized to content and kept within RightMargin; long cell text wraps inside the cell rather than overflowing.
  • Rich cell contents — paragraphs, ordered/unordered lists (including nested), <pre> blocks, line breaks, and basic inline formatting render within the cell’s column.
  • Merged and nested tables honoredcolspan and rowspan are supported, and a table inside a cell is drawn as its own bordered table. A <caption> is centered above the table.
  • Links in cells follow the same link settings as the rest of the document (shared “References” list with bracketed numbers by default).

🖼️ See the HTML Table to Plain Text Gallery for examples rendered with the improved v11.6.0 HtmlToText.

➕ Smaller Additions

  • Url.Scheme — added the Scheme property to Chilkat.Url. The scheme is the first part of a URL (e.g. https in https://www.example.com/page); common schemes include http, https, ftp, file, and mailto.
  • Ssh.GetReceivedSb — added to the Ssh class, for retrieving received data into a StringBuilder.
  • MailMan.RequireHostnameMatch — added property.
  • JsonArray.FindStartIndex — added property.
  • Azure Key Vault cloud signing — an application may now specify the access_token directly instead of client_id / client_secret / tenant_id, so it can obtain its own token (for example via a Managed Identity) and pass it straight to Chilkat:
    jsonAzure.UpdateString("service", "azure_keyvault");
    jsonAzure.UpdateString("access_token", accessToken);
    jsonAzure.UpdateString("vault_name", "VAULT_NAME");
    jsonAzure.UpdateString("cert_name", "CERT_NAME");
    jsonAzure.UpdateString("cert_version", "CERT_VERSION");
    See Sign PDF in the Cloud using Azure Key Vault.
  • iOS builds — updated makeUniversalLib.sh and added a new script for building an XCFramework; the iOS download page was updated following removal of the obsolete armv7 and armv7s slices.

🛠️ Fixes & Improvements

🌐 HTTP / REST

⚠️ Breaking change AllowHeaderFolding (on both Chilkat.Rest and Chilkat.Http) now defaults to false. HTTP header folding is obsolete (RFC 7230 says a sender must not generate folded headers), and modern servers increasingly reject folded headers with 400 Bad Request — which previously happened whenever a header value was long (e.g. a lengthy Authorization header). Applications that require folded headers can restore the old behavior by explicitly setting AllowHeaderFolding = true.

Rest — response body after ReadResponseHeader. In the manual request/response pattern (explicit steps rather than a FullRequest* method), the response body was not readable after ReadResponseHeader: the object incorrectly moved to an idle state for all verbs, so every body-read call failed with “not in the state to read the response body.” Fixed — after a valid status code, the object now correctly enters the body-reading state for any request that can have a body. A HEAD request (no body) still correctly stops after the header. FullRequest* methods were never affected.

Rest — ReadRespBodyStream and EndOfStream. Fixed a spurious read failure when downloading a response body into a Stream and reading it on another thread. After the full body was received, EndOfStream could remain false, so a loop on EndOfStream made one extra read that failed. Now EndOfStream becomes true once the body is delivered and consumed, and a read at the very end returns success with no bytes rather than an error. No code changes required.

📄 HtmlToText — Correctness Fixes

A number of correctness and reliability fixes. Existing code does not need to change; items that alter the exact output are marked (output change).

  • Fixed a possible crash or garbage output on invalid or truncated UTF-8. Malformed multi-byte characters near a line-wrap boundary could cause the converter to read past the end of the text. Such input is now handled safely.
  • Right-margin wrapping for non-ASCII text (output change) — words with multi-byte characters (accented letters, CJK, emoji) are now measured by display width rather than byte count, so lines wrap at the intended margin.
  • Removed spurious spaces around hyperlinks (output change) — e.g. (link) instead of ( link ), and no space before punctuation following a link.
  • Links cross-referenced to the References list (output change) — each link is followed by a bracketed reference number matching the References list; duplicate URLs share a number.
  • Ordered lists numbered correctly (output change) — items counted correctly even with stray content in an <ol>; the start attribute is honored.
  • List markers no longer leak into nested lists, and line up consistently (output change).
  • Removed a leading blank line (output change) before the first heading, paragraph, or list.

🔒 Crypto — JWE, JWS, Keys

JWE — ECDH-ES key wrapping. ECDH-ES+A128KW / A192KW / A256KW now produce standards-compliant, interoperable output in all cases. The content-encryption key had been sized to twice the key-wrap key length instead of the size required by the chosen enc algorithm, so behavior depended on whether the two happened to line up:

OutcomePairings
UnaffectedValid & interoperable — “aligned” pairings: A128KW+A128CBC-HS256, A192KW+A192CBC-HS384, A256KW+A256CBC-HS512, and A128KW+A256GCM
FailedCBC-HMAC enc whose required size didn’t match — e.g. A128KW+A256CBC-HS512
Wrong outputAES-GCM enc pairings where sizes didn’t align (non-interoperable, or failed)

The content-encryption key is now always generated at the correct size and wrapped correctly. Only JWEs from the affected combinations need to be regenerated; those from the unaffected pairings remain fully compatible.

JWS — CreateJwsSb serialization. Fixed: CreateJwsSb now respects PreferCompact and PreferFlattened. Previously it always produced the general JSON serialization, even when compact output was requested. To keep the old always-general output, set PreferCompact = false (and, for a single signature, PreferFlattened = false).

PrivateKey — fixes and changes (verified with RSA, P-256 EC, and Ed25519 keys)

  • Fixed SavePemFile and SavePkcs8PemFile, which had been reversedSavePemFile now writes the traditional representation, SavePkcs8PemFile writes PKCS #8.
  • Ed25519 DER/PEM export now uses the correct OID 1.3.101.112 (was sometimes the X25519 OID 1.3.101.110).
  • Ed25519 XML from GetXml now loads successfully.
  • JWK validation: an unsupported kty now fails instead of silently leaving the object empty.
  • GetJwkThumbprint: unsupported/empty hash algorithm now fails instead of silently using SHA-1.
  • Pkcs8EncryptAlg: names normalized consistently; unsupported/empty resets to the default 3des.
  • EC PEM labeling corrected (EC PRIVATE KEY, PRIVATE KEY, or ENCRYPTED PRIVATE KEY) so the label agrees with the DER structure.

PublicKey — fixes and changes (verified with RSA, EC, and Ed25519 keys)

  • GetJwkThumbprint: unsupported/empty hash algorithm now fails instead of using SHA-1.
  • JWK validation now fails on missing required members, unsupported key type, or a zero RSA exponent, without leaving a partially initialized object.
  • LoadEd25519 requires exactly 32 bytes (64 hex chars) and rejects prefixes, whitespace, and bad lengths; LoadEcdsa rejects malformed/short coordinates, prefixes, whitespace, empty and all-zero values, and unsupported curves.
  • Standardized failure behavior across all load methods: a failed load clears the object (Empty = true, KeyType = "empty", KeySize = 0, LastMethodSuccess = false) and preserves no previous key.

📦 MIME

  • Convert8Bit — MIME parts using Content-Transfer-Encoding: 8bit or binary are now correctly converted to Base64, keeping the serialized MIME, child Encoding properties, and headers consistent.
  • UrlEncodeBody — URL-encoded text now replaces the existing body instead of being appended; invalid charset names no longer duplicate the body.
  • RemovePart — an out-of-range index returns false and leaves the tree unchanged.
  • SetBodyFromEncoded — improved validation; rejects malformed data and unsupported encodings, preserving existing content on failure.
  • PartsToFiles — the returned StringTable now contains the actual sanitized paths, and no nonexistent paths are added when extraction fails.

🔌 Sockets

  • SoReuseAddr on Linux — the property (default true) was not being applied: SO_REUSEADDR was never set via setsockopt before the internal bind(), so BindAndListen could fail with EADDRINUSE when the port had a socket in TIME_WAIT (e.g. after a server restart). The option is now set prior to binding.
  • ClientPort — now clamped to the valid range 0–65535; out-of-range values leave the property unchanged.

📧 Email — IMAP & MailMan

  • Large UID handling — fixed mailboxes mixing ordinary and very large UIDs, where UID-based searches previously mishandled the large values.
  • Imap.FetchRange — no longer appends an empty Email (with an invalid ckx-imap-uid of 0) when requesting sequence numbers past the end of the mailbox.
  • Imap.QueryMbx with the special new-email criterion — a caller-supplied MessageSet is now cleared when no new messages are found, instead of retaining prior state.
  • Imap.GetMailFlag — now returns -1 when the required ckx-imap-* metadata is missing from the Email.
  • MessageSet — improved, better-defined error handling for FromCompactString, and improved performance for larger id sets.
  • Fixed a crash bug in MailMan.FetchUidlSet.

🧮 JSON, PCRE2, Objective-C

  • JsonObject.StringOfEquals — case-sensitivity was reversed (behavior change). Previously caseSensitive = true compared case-insensitively and vice-versa. Now corrected: true = case-sensitive, false = case-insensitive. If you had compensated for the old behavior, review those calls.
  • PCRE2 — upstream bug fix (present in 10.45/10.46, fixed in 10.47). pcre2_callout_enumerate() crashed with an out-of-bounds read on any pattern containing a Unicode character class (e.g. \p{L}, \d, [[:alpha:]] in Unicode mode). Chilkat’s bundled PCRE2 now uses the corrected offset calculation.
  • Objective-C — 64-bit widening. Several NSNumber-returning functions were widened to correctly represent large 64-bit sizes and counts: ContentLength64, XferByteCount64, GetSize64, GetSizeByName64, UncompressedLength64, CompressedLength64, and FileSize64.

📦 Deprecations

  • Dkim — DomainKeys deprecated. The Dkim class’s DomainKeys-related methods and properties are deprecated. DomainKeys (an older Yahoo protocol) was superseded by DKIM, the standardized protocol used by modern email systems, and should be considered obsolete.
  • Ftp2.DetermineSettings and Ftp2.DetermineProxyMethod are deprecated. These can be replaced with simple examples showing what the methods did internally.

For previous versions and archived updates, visit the Release Notes Archive.