From 707da3f2152813f20847f82a185093031372c93f Mon Sep 17 00:00:00 2001
From: Ken Little <8117061+krlittle@users.noreply.github.com>
Date: Wed, 4 Nov 2026 22:06:40 +0000
Subject: [PATCH] Add `UpgradeTwilio_13` to migrate the Twilio Java SDK to 13.x
No recipe covered `com.twilio.sdk:twilio`. This raises it to 13.x, declares
what the SDK stopped bringing along, and changes the calls that have a
mechanical replacement. Calls that need a decision are left for the compiler.
---
build.gradle.kts | 2 +
.../twilio/TwilioJwtSecretToByteArray.java | 121 +++
.../java/migrate/twilio/package-info.java | 21 +
.../resources/META-INF/rewrite/category.yml | 5 +
.../resources/META-INF/rewrite/recipes.csv | 11 +
.../resources/META-INF/rewrite/twilio.yml | 232 +++++
.../TwilioJwtSecretToByteArrayTest.java | 347 ++++++++
.../migrate/twilio/UpgradeTwilio13Test.java | 800 ++++++++++++++++++
.../META-INF/rewrite/classpath.tsv.gz | Bin 1398440 -> 1715447 bytes
9 files changed, 1539 insertions(+)
create mode 100644 src/main/java/org/openrewrite/java/migrate/twilio/TwilioJwtSecretToByteArray.java
create mode 100644 src/main/java/org/openrewrite/java/migrate/twilio/package-info.java
create mode 100644 src/main/resources/META-INF/rewrite/twilio.yml
create mode 100644 src/test/java/org/openrewrite/java/migrate/twilio/TwilioJwtSecretToByteArrayTest.java
create mode 100644 src/test/java/org/openrewrite/java/migrate/twilio/UpgradeTwilio13Test.java
diff --git a/build.gradle.kts b/build.gradle.kts
index d280a73a8f..d187ac145b 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -24,6 +24,7 @@ recipeDependencies {
testParserClasspath("com.github.spotbugs:spotbugs-annotations:4.9.3")
testParserClasspath("com.sun.faces:jsf-api:2.1.29-11")
testParserClasspath("com.sun.istack:istack-commons-runtime:4.1.2")
+ testParserClasspath("com.twilio.sdk:twilio:7.55.3")
testParserClasspath("commons-fileupload:commons-fileupload:1.5")
testParserClasspath("commons-logging:commons-logging:1.3.2")
testParserClasspath("io.micrometer:micrometer-core:1.15.4")
@@ -51,6 +52,7 @@ recipeDependencies {
testParserClasspath("javax.xml.bind:jaxb-api:2.3.1")
testParserClasspath("org.apache.commons:commons-fileupload2-jakarta:2.0.0-M1")
testParserClasspath("org.apache.commons:commons-fileupload2-jakarta-servlet5:2.0.0-M5")
+ testParserClasspath("org.apache.httpcomponents:httpclient:4.5.14")
testParserClasspath("org.apache.johnzon:johnzon-core:1.2.18")
testParserClasspath("org.apache.logging.log4j:log4j-api:2.23.1")
testParserClasspath("org.apache.ws.security:wss4j:1.6.19")
diff --git a/src/main/java/org/openrewrite/java/migrate/twilio/TwilioJwtSecretToByteArray.java b/src/main/java/org/openrewrite/java/migrate/twilio/TwilioJwtSecretToByteArray.java
new file mode 100644
index 0000000000..e2122ed3a1
--- /dev/null
+++ b/src/main/java/org/openrewrite/java/migrate/twilio/TwilioJwtSecretToByteArray.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2026 the original author or authors.
+ *
+ * Licensed under the Moderne Source Available License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://docs.moderne.io/licensing/moderne-source-available-license
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.openrewrite.java.migrate.twilio;
+
+import lombok.Getter;
+import org.openrewrite.Cursor;
+import org.openrewrite.ExecutionContext;
+import org.openrewrite.Preconditions;
+import org.openrewrite.Recipe;
+import org.openrewrite.SourceFile;
+import org.openrewrite.TreeVisitor;
+import org.openrewrite.internal.ListUtils;
+import org.openrewrite.java.JavaIsoVisitor;
+import org.openrewrite.java.JavaTemplate;
+import org.openrewrite.java.MethodMatcher;
+import org.openrewrite.java.search.UsesMethod;
+import org.openrewrite.java.tree.Expression;
+import org.openrewrite.java.tree.J;
+import org.openrewrite.java.tree.JContainer;
+import org.openrewrite.java.tree.JavaType;
+
+public class TwilioJwtSecretToByteArray extends Recipe {
+ private static final MethodMatcher ACCESS_TOKEN_BUILDER =
+ new MethodMatcher("com.twilio.jwt.accesstoken.AccessToken$Builder (String, String, String)");
+ private static final MethodMatcher CLIENT_CAPABILITY_BUILDER =
+ new MethodMatcher("com.twilio.jwt.client.ClientCapability$Builder (String, String)");
+ private static final MethodMatcher TASK_ROUTER_CAPABILITY_BUILDER =
+ new MethodMatcher("com.twilio.jwt.taskrouter.TaskRouterCapability$Builder (String, String, String, String)");
+
+ private static final JavaType BYTE_ARRAY = new JavaType.Array(null, JavaType.Primitive.Byte, null);
+
+ @Getter
+ final String displayName = "Pass Twilio JWT secrets as `byte[]`";
+
+ @Getter
+ final String description = "Twilio Java SDK 10.8.0 changed the secret of `AccessToken.Builder`, " +
+ "`ClientCapability.Builder` and `TaskRouterCapability.Builder` from `String` to `byte[]`. " +
+ "The SDK used to call `String#getBytes()` itself, so this calls it at the construction site, " +
+ "with `StandardCharsets.UTF_8` rather than the platform default. " +
+ "Twilio secrets are ASCII, so the bytes and the signatures made with them stay the same.";
+
+ @Override
+ public TreeVisitor, ExecutionContext> getVisitor() {
+ return Preconditions.check(
+ Preconditions.or(
+ new UsesMethod<>(ACCESS_TOKEN_BUILDER),
+ new UsesMethod<>(CLIENT_CAPABILITY_BUILDER),
+ new UsesMethod<>(TASK_ROUTER_CAPABILITY_BUILDER)),
+ new JavaIsoVisitor() {
+ @Override
+ public boolean isAcceptable(SourceFile sourceFile, ExecutionContext ctx) {
+ // The template is Java; Kotlin has no `String#getBytes(Charset)`
+ return sourceFile instanceof J.CompilationUnit;
+ }
+
+ @Override
+ public J.NewClass visitNewClass(J.NewClass newClass, ExecutionContext ctx) {
+ J.NewClass n = super.visitNewClass(newClass, ctx);
+ int index = secretIndex(n);
+ if (index < 0) {
+ return n;
+ }
+ Expression secret = n.getArguments().get(index);
+ if (J.Literal.isLiteralValue(secret, null) || secret.getType() instanceof JavaType.Array) {
+ return n;
+ }
+
+ String receiver = isPrimary(secret) ? "#{any(String)}" : "(#{any(String)})";
+ Expression bytes = JavaTemplate.builder(receiver + ".getBytes(StandardCharsets.UTF_8)")
+ .imports("java.nio.charset.StandardCharsets")
+ .build()
+ .apply(new Cursor(getCursor(), secret), secret.getCoordinates().replace(), secret);
+ maybeAddImport("java.nio.charset.StandardCharsets");
+
+ // Through the padding, as the whitespace before a closing parenthesis on its own line is kept there
+ JContainer arguments = n.getPadding().getArguments();
+ n = n.getPadding().withArguments(arguments.getPadding().withElements(ListUtils.map(
+ arguments.getPadding().getElements(), (i, arg) -> i == index ? arg.withElement(bytes) : arg)));
+ JavaType.Method constructor = n.getConstructorType();
+ if (constructor != null) {
+ n = n.withConstructorType(constructor.withParameterTypes(ListUtils.map(
+ constructor.getParameterTypes(), (i, type) -> i == index ? BYTE_ARRAY : type)));
+ }
+ return n;
+ }
+
+ private int secretIndex(J.NewClass newClass) {
+ if (ACCESS_TOKEN_BUILDER.matches(newClass)) {
+ return 2;
+ }
+ if (CLIENT_CAPABILITY_BUILDER.matches(newClass) || TASK_ROUTER_CAPABILITY_BUILDER.matches(newClass)) {
+ return 1;
+ }
+ return -1;
+ }
+
+ private boolean isPrimary(Expression expression) {
+ return expression instanceof J.Identifier ||
+ expression instanceof J.FieldAccess ||
+ expression instanceof J.Literal ||
+ expression instanceof J.MethodInvocation ||
+ expression instanceof J.ArrayAccess ||
+ expression instanceof J.NewClass ||
+ expression instanceof J.Parentheses;
+ }
+ });
+ }
+}
diff --git a/src/main/java/org/openrewrite/java/migrate/twilio/package-info.java b/src/main/java/org/openrewrite/java/migrate/twilio/package-info.java
new file mode 100644
index 0000000000..db74d8e918
--- /dev/null
+++ b/src/main/java/org/openrewrite/java/migrate/twilio/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2025 the original author or authors.
+ *
+ * Licensed under the Moderne Source Available License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://docs.moderne.io/licensing/moderne-source-available-license
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+@NullMarked
+@NonNullFields
+package org.openrewrite.java.migrate.twilio;
+
+import org.jspecify.annotations.NullMarked;
+import org.openrewrite.internal.lang.NonNullFields;
diff --git a/src/main/resources/META-INF/rewrite/category.yml b/src/main/resources/META-INF/rewrite/category.yml
index c502367b0d..bfb8ffb91e 100644
--- a/src/main/resources/META-INF/rewrite/category.yml
+++ b/src/main/resources/META-INF/rewrite/category.yml
@@ -90,3 +90,8 @@ type: specs.openrewrite.org/v1beta/category
name: DataNucleus
packageName: org.openrewrite.java.migrate.datanucleus
description: Recipes for migrating [DataNucleus](https://www.datanucleus.org/) JDO/JPA persistence applications.
+---
+type: specs.openrewrite.org/v1beta/category
+name: Twilio
+packageName: org.openrewrite.java.migrate.twilio
+description: Recipes for migrating applications that use the [Twilio Java SDK](https://github.com/twilio/twilio-java).
diff --git a/src/main/resources/META-INF/rewrite/recipes.csv b/src/main/resources/META-INF/rewrite/recipes.csv
index 783c5bc0be..0501de2e7c 100644
--- a/src/main/resources/META-INF/rewrite/recipes.csv
+++ b/src/main/resources/META-INF/rewrite/recipes.csv
@@ -542,6 +542,17 @@ maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.s
maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.search.PlanJavaMigration,Plan a Java version migration,Study the set of Java versions and associated tools in use across many repositories.,1,,Search,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,,"[{""name"":""org.openrewrite.java.migrate.table.JavaVersionMigrationPlan"",""displayName"":""Java version migration plan"",""instanceName"":""Java version migration plan"",""description"":""A per-repository view of the current state of Java versions and associated build tools"",""columns"":[{""name"":""hasJava"",""type"":""boolean"",""displayName"":""Has Java"",""description"":""Whether this is a Java repository at all.""},{""name"":""sourceCompatibility"",""type"":""String"",""displayName"":""Source compatibility"",""description"":""The source compatibility of the source file.""},{""name"":""majorVersionSourceCompatibility"",""type"":""Integer"",""displayName"":""Major version source compatibility"",""description"":""The major version.""},{""name"":""targetCompatibility"",""type"":""String"",""displayName"":""Target compatibility"",""description"":""The target compatibility or `--release` version of the source file.""},{""name"":""gradleVersion"",""type"":""String"",""displayName"":""Gradle version"",""description"":""The version of Gradle in use, if any.""},{""name"":""hasGradleBuild"",""type"":""Boolean"",""displayName"":""Has Gradle build"",""description"":""Whether a `build.gradle` file exists in the repository.""},{""name"":""mavenVersion"",""type"":""String"",""displayName"":""Maven version"",""description"":""The version of Maven in use, if any.""},{""name"":""hasMavenPom"",""type"":""Boolean"",""displayName"":""Has Maven pom"",""description"":""Whether a `pom.xml` file exists in the repository.""}]}]"
maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.sql.JavaSqlAPIs,Use modernized `java.sql` APIs,"Certain Java sql APIs have become deprecated and their usages changed, necessitating usage changes.",2,,`java.sql` APIs,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.sql.MigrateDriverManagerSetLogStream,Use `DriverManager#setLogWriter(java.io.PrintWriter)`,Use `DriverManager#setLogWriter(java.io.PrintWriter)` instead of the deprecated `DriverManager#setLogStream(java.io.PrintStream)` in Java 1.2 or higher.,1,,`java.sql` APIs,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,,
+maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.twilio.TwilioDroppedDependencies,Declare the dependencies the Twilio Java SDK no longer brings along,"Twilio Java SDK 7.x brought Guava, Joda-Time and Apache HttpClient 4 to the projects using it, which can use them without declaring them. Later versions do not, so this declares the ones a project uses and no longer gets any other way. A version the project declares itself is left as it is.",7,,Twilio,Modernize,Java,,Recipes for migrating applications that use the [Twilio Java SDK](https://github.com/twilio/twilio-java).,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]"
+maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.twilio.TwilioDroppedGuava,Declare the Guava the Twilio Java SDK no longer brings along,"Adds `com.google.guava:guava` to a project that uses it but does not declare it, as `AddDependency` would otherwise raise a version the project does declare.",2,,Twilio,Modernize,Java,,Recipes for migrating applications that use the [Twilio Java SDK](https://github.com/twilio/twilio-java).,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]"
+maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.twilio.TwilioDroppedHttpClient,Declare the Apache HttpClient 4 the Twilio Java SDK no longer brings along,"Adds `org.apache.httpcomponents:httpclient` to a project that uses it but does not declare it, as `AddDependency` would otherwise raise a version the project does declare.",2,,Twilio,Modernize,Java,,Recipes for migrating applications that use the [Twilio Java SDK](https://github.com/twilio/twilio-java).,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]"
+maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.twilio.TwilioDroppedJodaTime,Declare the Joda-Time the Twilio Java SDK no longer brings along,"Adds `joda-time:joda-time` to a project that uses it but does not declare it, as `AddDependency` would otherwise raise a version the project does declare.",2,,Twilio,Modernize,Java,,Recipes for migrating applications that use the [Twilio Java SDK](https://github.com/twilio/twilio-java).,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]"
+maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.twilio.TwilioJwtSecretToByteArray,Pass Twilio JWT secrets as `byte[]`,"Twilio Java SDK 10.8.0 changed the secret of `AccessToken.Builder`, `ClientCapability.Builder` and `TaskRouterCapability.Builder` from `String` to `byte[]`. The SDK used to call `String#getBytes()` itself, so this calls it at the construction site, with `StandardCharsets.UTF_8` rather than the platform default. Twilio secrets are ASCII, so the bytes and the signatures made with them stay the same.",1,,Twilio,Modernize,Java,,Recipes for migrating applications that use the [Twilio Java SDK](https://github.com/twilio/twilio-java).,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,,
+maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.twilio.TwilioNetworkHttpClientBuilder,Pass `NetworkHttpClient` an Apache HttpClient 5 builder,"Twilio Java SDK 11.0.0 moved `NetworkHttpClient` from Apache HttpClient 4 to 5, so its constructor takes the HttpClient 5 `HttpClientBuilder`. This changes the builder's type only in the source files that pass one to `NetworkHttpClient`, as other uses of Apache HttpClient 4 are not part of this migration.",2,,Twilio,Modernize,Java,,Recipes for migrating applications that use the [Twilio Java SDK](https://github.com/twilio/twilio-java).,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,,
+maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.twilio.TwilioRenamedApis,Use the Twilio APIs renamed in 8.0.0,"Twilio Java SDK 8.0.0 renamed the nested TwiML builder methods after their TwiML element, and removed the deprecated `ConversationsGrant` and `configurationProfileSid` of `VideoGrant`, whose replacements are `VideoGrant` and `room`.",15,,Twilio,Modernize,Java,,Recipes for migrating applications that use the [Twilio Java SDK](https://github.com/twilio/twilio-java).,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,,
+maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.twilio.TwilioUnusedAuthyImports,Remove unused imports of Twilio Authy,"Authy was removed from the Twilio Java SDK, so an import of it no longer compiles even when nothing uses it. A use of Authy has no replacement, so it is left for the compiler to point out.",2,,Twilio,Modernize,Java,,Recipes for migrating applications that use the [Twilio Java SDK](https://github.com/twilio/twilio-java).,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,,
+maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.twilio.TwilioUnusedAutopilotImports,Remove unused imports of Twilio Autopilot,"Autopilot was removed from the Twilio Java SDK, so an import of it no longer compiles even when nothing uses it. A use of Autopilot has no replacement, so it is left for the compiler to point out.",2,,Twilio,Modernize,Java,,Recipes for migrating applications that use the [Twilio Java SDK](https://github.com/twilio/twilio-java).,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,,
+maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.twilio.TwilioUnusedFaxImports,Remove unused imports of Twilio Fax,"Fax was removed from the Twilio Java SDK, so an import of it no longer compiles even when nothing uses it. A use of Fax has no replacement, so it is left for the compiler to point out.",2,,Twilio,Modernize,Java,,Recipes for migrating applications that use the [Twilio Java SDK](https://github.com/twilio/twilio-java).,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,,
+maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.twilio.UpgradeTwilio_13,Migrate to Twilio Java SDK 13,"Migrate applications from the Twilio Java SDK `com.twilio.sdk:twilio` 7.x or later to 13.x, which needs Java 8 or later. This raises the dependency, declares what the SDK no longer brings along, and changes the calls that have a mechanical replacement. A Gradle project with dependency locking needs its `gradle.lockfile` written again. Calls that need a decision are left for the compiler to point out: the `org.joda.time` values the resources returned are `java.time` since 8.0.0, `ListenableFuture` is `CompletableFuture` in the `*Async` methods, the Guava `Range` date filters are separate before and after setters, and `getPrice()` of `Message` and `Call` is a `String`. The Authy, Autopilot, Fax and Preview resources were removed with no replacement, and a newer JJWT comes along with the SDK, which removed `Jwts.parserBuilder()` for code that uses JJWT itself. No compiler reports these, which appear at runtime: JJWT 0.12 refuses an HMAC secret shorter than 256 bits, which a real Twilio secret is not but a placeholder in a test may be; a mocked `TwilioRestClient` needs `getAccountSid()` stubbed, as the resources no longer tolerate it being `null`; and `Message.fromJson` given a plain `ObjectMapper` needs `JavaTimeModule` on Java 17 or later with an old Jackson such as the 2.9 of Spring Boot 2.1, which the mapper of a real `TwilioRestClient` already has.",33,,Twilio,Modernize,Java,,Recipes for migrating applications that use the [Twilio Java SDK](https://github.com/twilio/twilio-java).,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]"
maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.util.IteratorNext,Replace `iterator().next()` with `getFirst()`,Replace `SequencedCollection.iterator().next()` with `getFirst()`.,1,,`java.util` APIs,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.util.JavaUtilAPIs,Use modernized `java.util` APIs,Certain java util APIs have been introduced and are favored over previous APIs.,25,,`java.util` APIs,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.util.ListFirstAndLast,"Replace `List.get(int)`, `add(int, Object)`, and `remove(int)` with `SequencedCollection` `*First` and `*Last` methods","Replace `list.get(0)` with `list.getFirst()`, `list.get(list.size() - 1)` with `list.getLast()`, and similar for `add(int, E)` and `remove(int)`.",1,,`java.util` APIs,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,,
diff --git a/src/main/resources/META-INF/rewrite/twilio.yml b/src/main/resources/META-INF/rewrite/twilio.yml
new file mode 100644
index 0000000000..541227d501
--- /dev/null
+++ b/src/main/resources/META-INF/rewrite/twilio.yml
@@ -0,0 +1,232 @@
+#
+# Copyright 2026 the original author or authors.
+#
+# Licensed under the Moderne Source Available License (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://docs.moderne.io/licensing/moderne-source-available-license
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+---
+type: specs.openrewrite.org/v1beta/recipe
+name: org.openrewrite.java.migrate.twilio.UpgradeTwilio_13
+displayName: Migrate to Twilio Java SDK 13
+description: >-
+ Migrate applications from the Twilio Java SDK `com.twilio.sdk:twilio` 7.x or later to 13.x, which needs Java 8 or
+ later. This raises the dependency, declares what the SDK no longer brings along, and changes the calls that have a
+ mechanical replacement. A Gradle project with dependency locking needs its `gradle.lockfile` written again. Calls
+ that need a decision are left for the compiler to point out: the `org.joda.time` values the resources returned
+ are `java.time` since 8.0.0, `ListenableFuture` is `CompletableFuture` in the `*Async` methods, the Guava `Range`
+ date filters are separate before and after setters, and `getPrice()` of `Message` and `Call` is a `String`. The
+ Authy, Autopilot, Fax and Preview resources were removed with no replacement, and a newer JJWT comes along with the
+ SDK, which removed `Jwts.parserBuilder()` for code that uses JJWT itself. No compiler reports these, which
+ appear at runtime: JJWT 0.12 refuses an HMAC secret shorter than 256 bits, which a real Twilio secret is not but a
+ placeholder in a test may be; a mocked `TwilioRestClient` needs `getAccountSid()` stubbed, as the resources no
+ longer tolerate it being `null`; and `Message.fromJson` given a plain `ObjectMapper` needs `JavaTimeModule` on Java
+ 17 or later with an old Jackson such as the 2.9 of Spring Boot 2.1, which the mapper of a real `TwilioRestClient`
+ already has.
+tags:
+ - twilio
+recipeList:
+ - org.openrewrite.java.migrate.twilio.TwilioRenamedApis
+ - org.openrewrite.java.migrate.twilio.TwilioJwtSecretToByteArray
+ - org.openrewrite.java.migrate.twilio.TwilioNetworkHttpClientBuilder
+ - org.openrewrite.java.migrate.twilio.TwilioUnusedAutopilotImports
+ - org.openrewrite.java.migrate.twilio.TwilioUnusedAuthyImports
+ - org.openrewrite.java.migrate.twilio.TwilioUnusedFaxImports
+ - org.openrewrite.java.dependencies.UpgradeDependencyVersion:
+ groupId: com.twilio.sdk
+ artifactId: twilio
+ newVersion: 13.x
+ - org.openrewrite.java.migrate.twilio.TwilioDroppedDependencies
+
+---
+type: specs.openrewrite.org/v1beta/recipe
+name: org.openrewrite.java.migrate.twilio.TwilioRenamedApis
+displayName: Use the Twilio APIs renamed in 8.0.0
+description: >-
+ Twilio Java SDK 8.0.0 renamed the nested TwiML builder methods after their TwiML element, and removed the deprecated
+ `ConversationsGrant` and `configurationProfileSid` of `VideoGrant`, whose replacements are `VideoGrant` and `room`.
+recipeList:
+ - org.openrewrite.java.ChangeType:
+ oldFullyQualifiedTypeName: com.twilio.jwt.accesstoken.ConversationsGrant
+ newFullyQualifiedTypeName: com.twilio.jwt.accesstoken.VideoGrant
+ - org.openrewrite.java.ChangeMethodName:
+ methodPattern: com.twilio.jwt.accesstoken.VideoGrant getConfigurationProfileSid()
+ newMethodName: getRoom
+ - org.openrewrite.java.ChangeMethodName:
+ methodPattern: com.twilio.jwt.accesstoken.VideoGrant setConfigurationProfileSid(String)
+ newMethodName: setRoom
+ - org.openrewrite.java.ChangeMethodName:
+ methodPattern: com.twilio.twiml.voice.Refer$Builder referSip(com.twilio.twiml.voice.ReferSip)
+ newMethodName: sip
+ - org.openrewrite.java.ChangeMethodName:
+ methodPattern: com.twilio.twiml.voice.Say$Builder ssmlBreak(com.twilio.twiml.voice.SsmlBreak)
+ newMethodName: break_
+ - org.openrewrite.java.ChangeMethodName:
+ methodPattern: com.twilio.twiml.voice.Say$Builder ssmlEmphasis(com.twilio.twiml.voice.SsmlEmphasis)
+ newMethodName: emphasis
+ - org.openrewrite.java.ChangeMethodName:
+ methodPattern: com.twilio.twiml.voice.Say$Builder ssmlLang(com.twilio.twiml.voice.SsmlLang)
+ newMethodName: lang
+ - org.openrewrite.java.ChangeMethodName:
+ methodPattern: com.twilio.twiml.voice.Say$Builder ssmlP(com.twilio.twiml.voice.SsmlP)
+ newMethodName: p
+ - org.openrewrite.java.ChangeMethodName:
+ methodPattern: com.twilio.twiml.voice.Say$Builder ssmlPhoneme(com.twilio.twiml.voice.SsmlPhoneme)
+ newMethodName: phoneme
+ - org.openrewrite.java.ChangeMethodName:
+ methodPattern: com.twilio.twiml.voice.Say$Builder ssmlProsody(com.twilio.twiml.voice.SsmlProsody)
+ newMethodName: prosody
+ - org.openrewrite.java.ChangeMethodName:
+ methodPattern: com.twilio.twiml.voice.Say$Builder ssmlS(com.twilio.twiml.voice.SsmlS)
+ newMethodName: s
+ - org.openrewrite.java.ChangeMethodName:
+ methodPattern: com.twilio.twiml.voice.Say$Builder ssmlSayAs(com.twilio.twiml.voice.SsmlSayAs)
+ newMethodName: sayAs
+ - org.openrewrite.java.ChangeMethodName:
+ methodPattern: com.twilio.twiml.voice.Say$Builder ssmlSub(com.twilio.twiml.voice.SsmlSub)
+ newMethodName: sub
+ - org.openrewrite.java.ChangeMethodName:
+ methodPattern: com.twilio.twiml.voice.Say$Builder ssmlW(com.twilio.twiml.voice.SsmlW)
+ newMethodName: w
+
+---
+type: specs.openrewrite.org/v1beta/recipe
+name: org.openrewrite.java.migrate.twilio.TwilioNetworkHttpClientBuilder
+displayName: Pass `NetworkHttpClient` an Apache HttpClient 5 builder
+description: >-
+ Twilio Java SDK 11.0.0 moved `NetworkHttpClient` from Apache HttpClient 4 to 5, so its constructor takes the
+ HttpClient 5 `HttpClientBuilder`. This changes the builder's type only in the source files that pass one to
+ `NetworkHttpClient`, as other uses of Apache HttpClient 4 are not part of this migration.
+preconditions:
+ - org.openrewrite.java.search.FindMethods:
+ methodPattern: com.twilio.http.NetworkHttpClient (org.apache.http.impl.client.HttpClientBuilder)
+recipeList:
+ - org.openrewrite.java.ChangeType:
+ oldFullyQualifiedTypeName: org.apache.http.impl.client.HttpClientBuilder
+ newFullyQualifiedTypeName: org.apache.hc.client5.http.impl.classic.HttpClientBuilder
+
+---
+type: specs.openrewrite.org/v1beta/recipe
+name: org.openrewrite.java.migrate.twilio.TwilioDroppedDependencies
+displayName: Declare the dependencies the Twilio Java SDK no longer brings along
+description: >-
+ Twilio Java SDK 7.x brought Guava, Joda-Time and Apache HttpClient 4 to the projects using it, which can use them
+ without declaring them. Later versions do not, so this declares the ones a project uses and no longer gets any other
+ way. A version the project declares itself is left as it is.
+preconditions:
+ - org.openrewrite.java.dependencies.search.RepositoryHasDependency:
+ groupIdPattern: com.twilio.sdk
+ artifactIdPattern: twilio
+recipeList:
+ - org.openrewrite.java.migrate.twilio.TwilioDroppedHttpClient
+ - org.openrewrite.java.migrate.twilio.TwilioDroppedGuava
+ - org.openrewrite.java.migrate.twilio.TwilioDroppedJodaTime
+
+---
+type: specs.openrewrite.org/v1beta/recipe
+name: org.openrewrite.java.migrate.twilio.TwilioDroppedHttpClient
+displayName: Declare the Apache HttpClient 4 the Twilio Java SDK no longer brings along
+description: >-
+ Adds `org.apache.httpcomponents:httpclient` to a project that uses it but does not declare it, as `AddDependency`
+ would otherwise raise a version the project does declare.
+preconditions:
+ - org.openrewrite.java.dependencies.search.DoesNotIncludeDependency:
+ groupId: org.apache.httpcomponents
+ artifactId: httpclient
+ onlyDirect: true
+recipeList:
+ - org.openrewrite.java.dependencies.AddDependency:
+ groupId: org.apache.httpcomponents
+ artifactId: httpclient
+ version: 4.5.x
+ onlyIfUsing: org.apache.http..*
+ acceptTransitive: true
+
+---
+type: specs.openrewrite.org/v1beta/recipe
+name: org.openrewrite.java.migrate.twilio.TwilioDroppedGuava
+displayName: Declare the Guava the Twilio Java SDK no longer brings along
+description: >-
+ Adds `com.google.guava:guava` to a project that uses it but does not declare it, as `AddDependency` would otherwise
+ raise a version the project does declare.
+preconditions:
+ - org.openrewrite.java.dependencies.search.DoesNotIncludeDependency:
+ groupId: com.google.guava
+ artifactId: guava
+ onlyDirect: true
+recipeList:
+ - org.openrewrite.java.dependencies.AddDependency:
+ groupId: com.google.guava
+ artifactId: guava
+ version: 33.x
+ versionPattern: -jre
+ onlyIfUsing: com.google.common..*
+ acceptTransitive: true
+
+---
+type: specs.openrewrite.org/v1beta/recipe
+name: org.openrewrite.java.migrate.twilio.TwilioDroppedJodaTime
+displayName: Declare the Joda-Time the Twilio Java SDK no longer brings along
+description: >-
+ Adds `joda-time:joda-time` to a project that uses it but does not declare it, as `AddDependency` would otherwise
+ raise a version the project does declare.
+preconditions:
+ - org.openrewrite.java.dependencies.search.DoesNotIncludeDependency:
+ groupId: joda-time
+ artifactId: joda-time
+ onlyDirect: true
+recipeList:
+ - org.openrewrite.java.dependencies.AddDependency:
+ groupId: joda-time
+ artifactId: joda-time
+ version: 2.x
+ onlyIfUsing: org.joda.time..*
+ acceptTransitive: true
+
+---
+type: specs.openrewrite.org/v1beta/recipe
+name: org.openrewrite.java.migrate.twilio.TwilioUnusedAutopilotImports
+displayName: Remove unused imports of Twilio Autopilot
+description: >-
+ Autopilot was removed from the Twilio Java SDK, so an import of it no longer compiles even when nothing uses it. A
+ use of Autopilot has no replacement, so it is left for the compiler to point out.
+preconditions:
+ - org.openrewrite.java.search.FindImports:
+ typePattern: com.twilio.rest.autopilot..*
+recipeList:
+ - org.openrewrite.java.RemoveUnusedImports
+
+---
+type: specs.openrewrite.org/v1beta/recipe
+name: org.openrewrite.java.migrate.twilio.TwilioUnusedAuthyImports
+displayName: Remove unused imports of Twilio Authy
+description: >-
+ Authy was removed from the Twilio Java SDK, so an import of it no longer compiles even when nothing uses it. A use
+ of Authy has no replacement, so it is left for the compiler to point out.
+preconditions:
+ - org.openrewrite.java.search.FindImports:
+ typePattern: com.twilio.rest.authy..*
+recipeList:
+ - org.openrewrite.java.RemoveUnusedImports
+
+---
+type: specs.openrewrite.org/v1beta/recipe
+name: org.openrewrite.java.migrate.twilio.TwilioUnusedFaxImports
+displayName: Remove unused imports of Twilio Fax
+description: >-
+ Fax was removed from the Twilio Java SDK, so an import of it no longer compiles even when nothing uses it. A use of
+ Fax has no replacement, so it is left for the compiler to point out.
+preconditions:
+ - org.openrewrite.java.search.FindImports:
+ typePattern: com.twilio.rest.fax..*
+recipeList:
+ - org.openrewrite.java.RemoveUnusedImports
diff --git a/src/test/java/org/openrewrite/java/migrate/twilio/TwilioJwtSecretToByteArrayTest.java b/src/test/java/org/openrewrite/java/migrate/twilio/TwilioJwtSecretToByteArrayTest.java
new file mode 100644
index 0000000000..78607caf9c
--- /dev/null
+++ b/src/test/java/org/openrewrite/java/migrate/twilio/TwilioJwtSecretToByteArrayTest.java
@@ -0,0 +1,347 @@
+/*
+ * Copyright 2026 the original author or authors.
+ *
+ * Licensed under the Moderne Source Available License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://docs.moderne.io/licensing/moderne-source-available-license
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.openrewrite.java.migrate.twilio;
+
+import org.junit.jupiter.api.Test;
+import org.openrewrite.DocumentExample;
+import org.openrewrite.InMemoryExecutionContext;
+import org.openrewrite.java.JavaParser;
+import org.openrewrite.kotlin.KotlinParser;
+import org.openrewrite.test.RecipeSpec;
+import org.openrewrite.test.RewriteTest;
+
+import static org.openrewrite.java.Assertions.java;
+import static org.openrewrite.kotlin.Assertions.kotlin;
+
+class TwilioJwtSecretToByteArrayTest implements RewriteTest {
+
+ @Override
+ public void defaults(RecipeSpec spec) {
+ spec.recipe(new TwilioJwtSecretToByteArray())
+ .parser(JavaParser.fromJavaVersion().classpathFromResources(new InMemoryExecutionContext(), "twilio"));
+ }
+
+ @DocumentExample
+ @Test
+ void accessTokenSecret() {
+ rewriteRun(
+ //language=java
+ java(
+ """
+ import com.twilio.jwt.accesstoken.AccessToken;
+
+ class Tokens {
+ String mint(String accountSid, String apiKey, String apiSecret) {
+ return new AccessToken.Builder(accountSid, apiKey, apiSecret).identity("alice").build().toJwt();
+ }
+ }
+ """,
+ """
+ import com.twilio.jwt.accesstoken.AccessToken;
+
+ import java.nio.charset.StandardCharsets;
+
+ class Tokens {
+ String mint(String accountSid, String apiKey, String apiSecret) {
+ return new AccessToken.Builder(accountSid, apiKey, apiSecret.getBytes(StandardCharsets.UTF_8)).identity("alice").build().toJwt();
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void clientCapabilityAuthToken() {
+ rewriteRun(
+ //language=java
+ java(
+ """
+ import com.twilio.jwt.client.ClientCapability;
+
+ class Tokens {
+ ClientCapability capability(String accountSid, String authToken) {
+ return new ClientCapability.Builder(accountSid, authToken).build();
+ }
+ }
+ """,
+ """
+ import com.twilio.jwt.client.ClientCapability;
+
+ import java.nio.charset.StandardCharsets;
+
+ class Tokens {
+ ClientCapability capability(String accountSid, String authToken) {
+ return new ClientCapability.Builder(accountSid, authToken.getBytes(StandardCharsets.UTF_8)).build();
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void taskRouterCapabilityAuthTokenIsNotTheLastArgument() {
+ rewriteRun(
+ //language=java
+ java(
+ """
+ import com.twilio.jwt.taskrouter.TaskRouterCapability;
+
+ class Tokens {
+ TaskRouterCapability capability(String accountSid, String authToken, String workspaceSid, String channelId) {
+ return new TaskRouterCapability.Builder(accountSid, authToken, workspaceSid, channelId).build();
+ }
+ }
+ """,
+ """
+ import com.twilio.jwt.taskrouter.TaskRouterCapability;
+
+ import java.nio.charset.StandardCharsets;
+
+ class Tokens {
+ TaskRouterCapability capability(String accountSid, String authToken, String workspaceSid, String channelId) {
+ return new TaskRouterCapability.Builder(accountSid, authToken.getBytes(StandardCharsets.UTF_8), workspaceSid, channelId).build();
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void keepsTheLayoutOfArgumentsOnTheirOwnLines() {
+ rewriteRun(
+ //language=java
+ java(
+ """
+ import com.twilio.jwt.accesstoken.AccessToken;
+
+ class Tokens {
+ AccessToken.Builder builder() {
+ return new AccessToken.Builder(
+ System.getProperty("ACCOUNT_SID"),
+ System.getProperty("API_KEY"),
+ System.getProperty("API_SECRET")
+ ).identity("alice");
+ }
+ }
+ """,
+ """
+ import com.twilio.jwt.accesstoken.AccessToken;
+
+ import java.nio.charset.StandardCharsets;
+
+ class Tokens {
+ AccessToken.Builder builder() {
+ return new AccessToken.Builder(
+ System.getProperty("ACCOUNT_SID"),
+ System.getProperty("API_KEY"),
+ System.getProperty("API_SECRET").getBytes(StandardCharsets.UTF_8)
+ ).identity("alice");
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void concatenationKeepsItsPrecedence() {
+ rewriteRun(
+ //language=java
+ java(
+ """
+ import com.twilio.jwt.accesstoken.AccessToken;
+
+ class Tokens {
+ AccessToken.Builder builder(String sid, String key, String head, String tail) {
+ return new AccessToken.Builder(sid, key, head + tail);
+ }
+ }
+ """,
+ """
+ import com.twilio.jwt.accesstoken.AccessToken;
+
+ import java.nio.charset.StandardCharsets;
+
+ class Tokens {
+ AccessToken.Builder builder(String sid, String key, String head, String tail) {
+ return new AccessToken.Builder(sid, key, (head + tail).getBytes(StandardCharsets.UTF_8));
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void ternaryKeepsItsPrecedence() {
+ rewriteRun(
+ //language=java
+ java(
+ """
+ import com.twilio.jwt.accesstoken.AccessToken;
+
+ class Tokens {
+ AccessToken.Builder builder(String sid, String key, boolean live, String a, String b) {
+ return new AccessToken.Builder(sid, key, live ? a : b);
+ }
+ }
+ """,
+ """
+ import com.twilio.jwt.accesstoken.AccessToken;
+
+ import java.nio.charset.StandardCharsets;
+
+ class Tokens {
+ AccessToken.Builder builder(String sid, String key, boolean live, String a, String b) {
+ return new AccessToken.Builder(sid, key, (live ? a : b).getBytes(StandardCharsets.UTF_8));
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void methodCallAndLiteralNeedNoParentheses() {
+ rewriteRun(
+ //language=java
+ java(
+ """
+ import com.twilio.jwt.accesstoken.AccessToken;
+
+ class Tokens {
+ AccessToken.Builder fromEnvironment(String sid, String key) {
+ return new AccessToken.Builder(sid, key, System.getenv("TWILIO_API_SECRET"));
+ }
+
+ AccessToken.Builder fromLiteral(String sid, String key) {
+ return new AccessToken.Builder(sid, key, "abcdefghijklmnopqrstuvwxyz012345");
+ }
+ }
+ """,
+ """
+ import com.twilio.jwt.accesstoken.AccessToken;
+
+ import java.nio.charset.StandardCharsets;
+
+ class Tokens {
+ AccessToken.Builder fromEnvironment(String sid, String key) {
+ return new AccessToken.Builder(sid, key, System.getenv("TWILIO_API_SECRET").getBytes(StandardCharsets.UTF_8));
+ }
+
+ AccessToken.Builder fromLiteral(String sid, String key) {
+ return new AccessToken.Builder(sid, key, "abcdefghijklmnopqrstuvwxyz012345".getBytes(StandardCharsets.UTF_8));
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void reusesAnExistingImport() {
+ rewriteRun(
+ //language=java
+ java(
+ """
+ import com.twilio.jwt.accesstoken.AccessToken;
+
+ import java.nio.charset.StandardCharsets;
+
+ class Tokens {
+ byte[] utf8 = "x".getBytes(StandardCharsets.UTF_8);
+
+ AccessToken.Builder builder(String sid, String key, String secret) {
+ return new AccessToken.Builder(sid, key, secret);
+ }
+ }
+ """,
+ """
+ import com.twilio.jwt.accesstoken.AccessToken;
+
+ import java.nio.charset.StandardCharsets;
+
+ class Tokens {
+ byte[] utf8 = "x".getBytes(StandardCharsets.UTF_8);
+
+ AccessToken.Builder builder(String sid, String key, String secret) {
+ return new AccessToken.Builder(sid, key, secret.getBytes(StandardCharsets.UTF_8));
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void nullSecretCompilesAsItIs() {
+ rewriteRun(
+ //language=java
+ java(
+ """
+ import com.twilio.jwt.accesstoken.AccessToken;
+
+ class Tokens {
+ AccessToken.Builder builder(String sid, String key) {
+ return new AccessToken.Builder(sid, key, null);
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void kotlinIsLeftForTheCompilerToPointOut() {
+ rewriteRun(
+ spec -> spec.parser(KotlinParser.builder().classpathFromResources(new InMemoryExecutionContext(), "twilio")),
+ //language=kotlin
+ kotlin(
+ """
+ import com.twilio.jwt.accesstoken.AccessToken
+
+ fun builder(sid: String, key: String, secret: String): AccessToken.Builder {
+ return AccessToken.Builder(sid, key, secret)
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void otherConstructorsAreLeftAlone() {
+ rewriteRun(
+ //language=java
+ java(
+ """
+ class Builder {
+ Builder(String accountSid, String keySid, String secret) {
+ }
+ }
+
+ class Tokens {
+ Builder builder(String sid, String key, String secret) {
+ return new Builder(sid, key, secret);
+ }
+ }
+ """
+ )
+ );
+ }
+}
diff --git a/src/test/java/org/openrewrite/java/migrate/twilio/UpgradeTwilio13Test.java b/src/test/java/org/openrewrite/java/migrate/twilio/UpgradeTwilio13Test.java
new file mode 100644
index 0000000000..f858aaad1f
--- /dev/null
+++ b/src/test/java/org/openrewrite/java/migrate/twilio/UpgradeTwilio13Test.java
@@ -0,0 +1,800 @@
+/*
+ * Copyright 2026 the original author or authors.
+ *
+ * Licensed under the Moderne Source Available License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://docs.moderne.io/licensing/moderne-source-available-license
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.openrewrite.java.migrate.twilio;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+import org.openrewrite.DocumentExample;
+import org.openrewrite.InMemoryExecutionContext;
+import org.openrewrite.java.JavaParser;
+import org.openrewrite.test.RecipeSpec;
+import org.openrewrite.test.RewriteTest;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.openrewrite.gradle.Assertions.buildGradle;
+import static org.openrewrite.gradle.toolingapi.Assertions.withToolingApi;
+import static org.openrewrite.java.Assertions.java;
+import static org.openrewrite.java.Assertions.mavenProject;
+import static org.openrewrite.java.Assertions.srcMainJava;
+import static org.openrewrite.maven.Assertions.pomXml;
+
+class UpgradeTwilio13Test implements RewriteTest {
+
+ @Override
+ public void defaults(RecipeSpec spec) {
+ spec.recipeFromResources("org.openrewrite.java.migrate.twilio.UpgradeTwilio_13")
+ .parser(JavaParser.fromJavaVersion().classpathFromResources(new InMemoryExecutionContext(), "twilio", "httpclient"));
+ }
+
+ @DocumentExample
+ @Test
+ void raisesThePropertyTheVersionComesFrom() {
+ rewriteRun(
+ //language=xml
+ pomXml(
+ """
+
+ com.example
+ notifier
+ 1.0.0
+
+ 7.38.0
+
+
+
+ com.twilio.sdk
+ twilio
+ ${twilio.version}
+
+
+
+ """,
+ spec -> spec.after(pom -> {
+ assertThat(pom)
+ .containsPattern("13\\.\\d+\\.\\d+")
+ .contains("${twilio.version}");
+ return pom;
+ })
+ )
+ );
+ }
+
+ @Test
+ void raisesAVersionManagedInTheParent() {
+ rewriteRun(
+ mavenProject("parent",
+ //language=xml
+ pomXml(
+ """
+
+ com.example
+ parent
+ 1.0.0
+ pom
+
+ sms
+
+
+ 7.38.1
+
+
+
+
+ com.twilio.sdk
+ twilio
+ ${twilio.version}
+
+
+
+
+ """,
+ spec -> spec.after(pom -> {
+ assertThat(pom).containsPattern("13\\.\\d+\\.\\d+");
+ return pom;
+ })
+ ),
+ mavenProject("sms",
+ //language=xml
+ pomXml(
+ """
+
+
+ com.example
+ parent
+ 1.0.0
+
+ sms
+
+
+ com.twilio.sdk
+ twilio
+
+
+
+ """
+ )
+ )
+ )
+ );
+ }
+
+ @Test
+ void raisesAGradleDependency() {
+ rewriteRun(
+ spec -> spec.beforeRecipe(withToolingApi()),
+ //language=groovy
+ buildGradle(
+ """
+ plugins {
+ id 'java'
+ }
+
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ implementation 'com.twilio.sdk:twilio:7.38.0'
+ }
+ """,
+ spec -> spec.after(gradle -> {
+ assertThat(gradle).containsPattern("com\\.twilio\\.sdk:twilio:13\\.\\d+\\.\\d+");
+ return gradle;
+ })
+ )
+ );
+ }
+
+ @Test
+ void leavesTheJavaVersionAlone() {
+ rewriteRun(
+ mavenProject("notifier",
+ //language=xml
+ pomXml(
+ """
+
+ com.example
+ notifier
+ 1.0.0
+
+ 1.8
+ 1.8
+ 1.8
+
+
+
+ com.twilio.sdk
+ twilio
+ 7.38.0
+
+
+
+ """,
+ spec -> spec.after(pom -> {
+ assertThat(pom)
+ .contains("1.8")
+ .contains("1.8")
+ .contains("1.8")
+ .containsPattern("13\\.\\d+\\.\\d+");
+ return pom;
+ })
+ )
+ )
+ );
+ }
+
+ @Test
+ void leavesARepositoryWithoutTwilioAlone() {
+ rewriteRun(
+ mavenProject("unrelated",
+ //language=xml
+ pomXml(
+ """
+
+ com.example
+ unrelated
+ 1.0.0
+
+
+ com.google.guava
+ guava
+ 33.0.0-jre
+
+
+
+ """
+ )
+ )
+ );
+ }
+
+ @Test
+ void addsTheHttpClientTwilioNoLongerBringsAlong() {
+ rewriteRun(
+ mavenProject("voice",
+ srcMainJava(
+ //language=java
+ java(
+ """
+ import org.apache.http.client.utils.URIBuilder;
+
+ class Params {
+ String host(URIBuilder uri) {
+ return uri.getHost();
+ }
+ }
+ """
+ )
+ ),
+ //language=xml
+ pomXml(
+ """
+
+ com.example
+ voice
+ 1.0.0
+
+
+ com.twilio.sdk
+ twilio
+ 8.7.0
+
+
+
+ """,
+ spec -> spec.after(pom -> {
+ assertThat(pom)
+ .containsPattern("13\\.\\d+\\.\\d+")
+ .contains("httpclient")
+ .containsPattern("4\\.5\\.\\d+");
+ return pom;
+ })
+ )
+ )
+ );
+ }
+
+ @Test
+ void addsTheGuavaTwilioNoLongerBringsAlong() {
+ rewriteRun(
+ spec -> spec.parser(JavaParser.fromJavaVersion().classpathFromResources(new InMemoryExecutionContext(), "guava")),
+ mavenProject("sms",
+ srcMainJava(
+ //language=java
+ java(
+ """
+ import com.google.common.base.Strings;
+
+ class Numbers {
+ boolean blank(String number) {
+ return Strings.isNullOrEmpty(number);
+ }
+ }
+ """
+ )
+ ),
+ //language=xml
+ pomXml(
+ """
+
+ com.example
+ sms
+ 1.0.0
+
+
+ com.twilio.sdk
+ twilio
+ 7.38.0
+
+
+
+ """,
+ spec -> spec.after(pom -> {
+ assertThat(pom)
+ .contains("guava")
+ .containsPattern("\\d+\\.\\d+(\\.\\d+)?-jre");
+ return pom;
+ })
+ )
+ )
+ );
+ }
+
+ @Test
+ void addsTheGuavaTwilioNoLongerBringsAlongToAGradleProject() {
+ rewriteRun(
+ spec -> spec.beforeRecipe(withToolingApi())
+ .parser(JavaParser.fromJavaVersion().classpathFromResources(new InMemoryExecutionContext(), "guava")),
+ mavenProject("sms",
+ srcMainJava(
+ //language=java
+ java(
+ """
+ import com.google.common.base.Strings;
+
+ class Numbers {
+ boolean blank(String number) {
+ return Strings.isNullOrEmpty(number);
+ }
+ }
+ """
+ )
+ ),
+ //language=groovy
+ buildGradle(
+ """
+ plugins {
+ id 'java'
+ }
+
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ implementation 'com.twilio.sdk:twilio:7.38.0'
+ }
+ """,
+ spec -> spec.after(gradle -> {
+ assertThat(gradle)
+ .containsPattern("com\\.twilio\\.sdk:twilio:13\\.\\d+\\.\\d+")
+ .containsPattern("com\\.google\\.guava:guava:\\d+\\.\\d+(\\.\\d+)?-jre");
+ return gradle;
+ })
+ )
+ )
+ );
+ }
+
+ @Test
+ void keepsAVersionTheProjectDeclaresItself() {
+ rewriteRun(
+ spec -> spec.parser(JavaParser.fromJavaVersion().classpathFromResources(new InMemoryExecutionContext(), "guava")),
+ mavenProject("sms",
+ srcMainJava(
+ //language=java
+ java(
+ """
+ import com.google.common.base.Strings;
+
+ class Numbers {
+ boolean blank(String number) {
+ return Strings.isNullOrEmpty(number);
+ }
+ }
+ """
+ )
+ ),
+ //language=xml
+ pomXml(
+ """
+
+ com.example
+ sms
+ 1.0.0
+
+ 27.0-jre
+
+
+
+ com.google.guava
+ guava
+ ${guava.version}
+
+
+ com.twilio.sdk
+ twilio
+ 7.38.0
+
+
+
+ """,
+ spec -> spec.after(pom -> {
+ assertThat(pom)
+ .contains("27.0-jre")
+ .containsPattern("13\\.\\d+\\.\\d+");
+ return pom;
+ })
+ )
+ )
+ );
+ }
+
+ @Test
+ void keepsAVersionTheGradleProjectDeclaresItself() {
+ rewriteRun(
+ spec -> spec.beforeRecipe(withToolingApi())
+ .parser(JavaParser.fromJavaVersion().classpathFromResources(new InMemoryExecutionContext(), "guava")),
+ mavenProject("sms",
+ srcMainJava(
+ //language=java
+ java(
+ """
+ import com.google.common.base.Strings;
+
+ class Numbers {
+ boolean blank(String number) {
+ return Strings.isNullOrEmpty(number);
+ }
+ }
+ """
+ )
+ ),
+ //language=groovy
+ buildGradle(
+ """
+ plugins {
+ id 'java'
+ }
+
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ implementation 'com.google.guava:guava:30.1.1-jre'
+ implementation 'com.twilio.sdk:twilio:10.2.0'
+ }
+ """,
+ spec -> spec.after(gradle -> {
+ assertThat(gradle)
+ .contains("com.google.guava:guava:30.1.1-jre")
+ .containsPattern("com\\.twilio\\.sdk:twilio:13\\.\\d+\\.\\d+");
+ return gradle;
+ })
+ )
+ )
+ );
+ }
+
+ @Test
+ void addsNothingWhereTheTransitiveDependencyWasNotUsed() {
+ rewriteRun(
+ mavenProject("sms",
+ srcMainJava(
+ //language=java
+ java(
+ """
+ import com.twilio.Twilio;
+
+ class Init {
+ void init() {
+ Twilio.init("AC", "token");
+ }
+ }
+ """
+ )
+ ),
+ //language=xml
+ pomXml(
+ """
+
+ com.example
+ sms
+ 1.0.0
+
+
+ com.twilio.sdk
+ twilio
+ 7.38.0
+
+
+
+ """,
+ spec -> spec.after(pom -> {
+ assertThat(pom)
+ .doesNotContain("httpclient")
+ .doesNotContain("guava")
+ .doesNotContain("joda-time");
+ return pom;
+ })
+ )
+ )
+ );
+ }
+
+ @Test
+ void addsNothingToARepositoryWithoutTwilio() {
+ rewriteRun(
+ mavenProject("unrelated",
+ srcMainJava(
+ //language=java
+ java(
+ """
+ import org.apache.http.client.utils.URIBuilder;
+
+ class Params {
+ String host(URIBuilder uri) {
+ return uri.getHost();
+ }
+ }
+ """
+ )
+ ),
+ //language=xml
+ pomXml(
+ """
+
+ com.example
+ unrelated
+ 1.0.0
+
+ """
+ )
+ )
+ );
+ }
+
+ @Test
+ void removesAnUnusedImportOfARemovedProduct() {
+ rewriteRun(
+ //language=java
+ java(
+ """
+ import com.twilio.rest.autopilot.v1.assistant.Task;
+ import org.apache.http.client.utils.URIBuilder;
+
+ class Exemption {
+ String host(URIBuilder uri) {
+ return uri.getHost();
+ }
+ }
+ """,
+ """
+ import org.apache.http.client.utils.URIBuilder;
+
+ class Exemption {
+ String host(URIBuilder uri) {
+ return uri.getHost();
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"com.twilio.rest.authy.v1.Service", "com.twilio.rest.fax.v1.Fax"})
+ void removesUnusedImportsOfTheOtherRemovedProducts(String removed) {
+ rewriteRun(
+ //language=java
+ java(
+ """
+ import %s;
+
+ class Exemption {
+ }
+ """.formatted(removed),
+ """
+ class Exemption {
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void leavesAnImportOfARemovedProductThatIsUsedForTheCompiler() {
+ rewriteRun(
+ //language=java
+ java(
+ """
+ import com.twilio.rest.autopilot.v1.assistant.Task;
+
+ class Exemption {
+ Task task;
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void leavesOtherUnusedImportsAlone() {
+ rewriteRun(
+ //language=java
+ java(
+ """
+ import com.twilio.Twilio;
+ import java.util.List;
+
+ class Init {
+ void init() {
+ Twilio.init("AC", "token");
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void callsWithoutABreakingChangeStayAsTheyAre() {
+ rewriteRun(
+ //language=java
+ java(
+ """
+ import com.twilio.http.TwilioRestClient;
+ import com.twilio.rest.api.v2010.account.Message;
+ import com.twilio.type.PhoneNumber;
+
+ class Communicator {
+ String send(TwilioRestClient client, String to, String from, String body) {
+ Message message = Message.creator(new PhoneNumber(to), new PhoneNumber(from), body).create(client);
+ return message.getSid() + message.getTo() + message.getBody();
+ }
+
+ TwilioRestClient client(String accountSid, String authToken) {
+ return new TwilioRestClient.Builder(accountSid, authToken).build();
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void renamesNestedTwimlMethods() {
+ rewriteRun(
+ //language=java
+ java(
+ """
+ import com.twilio.twiml.voice.*;
+
+ class Twiml {
+ Say say(SsmlBreak pause, SsmlEmphasis emphasis, SsmlLang lang, SsmlP p, SsmlPhoneme phoneme,
+ SsmlProsody prosody, SsmlS s, SsmlSayAs sayAs, SsmlSub sub, SsmlW w) {
+ return new Say.Builder("hello")
+ .ssmlBreak(pause)
+ .ssmlEmphasis(emphasis)
+ .ssmlLang(lang)
+ .ssmlP(p)
+ .ssmlPhoneme(phoneme)
+ .ssmlProsody(prosody)
+ .ssmlS(s)
+ .ssmlSayAs(sayAs)
+ .ssmlSub(sub)
+ .ssmlW(w)
+ .build();
+ }
+
+ Refer refer(ReferSip sip) {
+ return new Refer.Builder().referSip(sip).build();
+ }
+ }
+ """,
+ """
+ import com.twilio.twiml.voice.*;
+
+ class Twiml {
+ Say say(SsmlBreak pause, SsmlEmphasis emphasis, SsmlLang lang, SsmlP p, SsmlPhoneme phoneme,
+ SsmlProsody prosody, SsmlS s, SsmlSayAs sayAs, SsmlSub sub, SsmlW w) {
+ return new Say.Builder("hello")
+ .break_(pause)
+ .emphasis(emphasis)
+ .lang(lang)
+ .p(p)
+ .phoneme(phoneme)
+ .prosody(prosody)
+ .s(s)
+ .sayAs(sayAs)
+ .sub(sub)
+ .w(w)
+ .build();
+ }
+
+ Refer refer(ReferSip sip) {
+ return new Refer.Builder().sip(sip).build();
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void movesDeprecatedGrantsToVideoGrant() {
+ rewriteRun(
+ //language=java
+ java(
+ """
+ import com.twilio.jwt.accesstoken.ConversationsGrant;
+ import com.twilio.jwt.accesstoken.VideoGrant;
+
+ class Grants {
+ String conversations(String profile) {
+ ConversationsGrant grant = new ConversationsGrant();
+ grant.setConfigurationProfileSid(profile);
+ return grant.getConfigurationProfileSid();
+ }
+
+ String video(String profile) {
+ VideoGrant grant = new VideoGrant();
+ grant.setConfigurationProfileSid(profile);
+ return grant.getConfigurationProfileSid();
+ }
+ }
+ """,
+ """
+ import com.twilio.jwt.accesstoken.VideoGrant;
+
+ class Grants {
+ String conversations(String profile) {
+ VideoGrant grant = new VideoGrant();
+ grant.setRoom(profile);
+ return grant.getRoom();
+ }
+
+ String video(String profile) {
+ VideoGrant grant = new VideoGrant();
+ grant.setRoom(profile);
+ return grant.getRoom();
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void changesTheBuilderPassedToNetworkHttpClient() {
+ rewriteRun(
+ //language=java
+ java(
+ """
+ import com.twilio.http.NetworkHttpClient;
+ import org.apache.http.impl.client.HttpClientBuilder;
+
+ class Client {
+ NetworkHttpClient client() {
+ return new NetworkHttpClient(HttpClientBuilder.create().disableRedirectHandling().useSystemProperties());
+ }
+ }
+ """,
+ """
+ import com.twilio.http.NetworkHttpClient;
+ import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
+
+ class Client {
+ NetworkHttpClient client() {
+ return new NetworkHttpClient(HttpClientBuilder.create().disableRedirectHandling().useSystemProperties());
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void leavesHttpClient4AloneElsewhere() {
+ rewriteRun(
+ //language=java
+ java(
+ """
+ import org.apache.http.impl.client.CloseableHttpClient;
+ import org.apache.http.impl.client.HttpClientBuilder;
+
+ class Unrelated {
+ CloseableHttpClient client() {
+ return HttpClientBuilder.create().build();
+ }
+ }
+ """
+ )
+ );
+ }
+}
diff --git a/src/test/resources/META-INF/rewrite/classpath.tsv.gz b/src/test/resources/META-INF/rewrite/classpath.tsv.gz
index d860be618a47470ce301f090dca63871d5316ab7..beca7184ff19572c4d3dde805fbb6464ee995467 100644
GIT binary patch
delta 1390144
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