You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streams.apache.org by sb...@apache.org on 2024/01/20 17:06:57 UTC

(streams) 01/01: #545 WIP

This is an automated email from the ASF dual-hosted git repository.

sblackmon pushed a commit to branch 545-juneau-9
in repository https://gitbox.apache.org/repos/asf/streams.git

commit e8a7e0a175edd24ab0a8e3d750f933fcf4eb8858
Author: Steve Blackmon <sb...@salesforce.com>
AuthorDate: Sat Jan 20 11:06:44 2024 -0600

    #545 WIP
---
 pom.xml                                            |   2 +-
 streams-cli/pom.xml                                |   8 +-
 .../test/StreamsConfigurationForTesting.java       |  14 +-
 .../streams/fullcontact/CompanyEnrichment.java     |  15 +-
 .../apache/streams/fullcontact/FullContact.java    |  27 ++-
 .../streams/fullcontact/PersonEnrichment.java      |  15 +-
 .../fullcontact/util/AffinityOrdering.scala        |   8 +-
 .../fullcontact/util/FullContactUtils.scala        |  53 +++--
 .../streams/peopledatalabs/PeopleDataLabs.java     |  43 ++--
 .../streams/peopledatalabs/PersonEnrichment.java   |  20 +-
 .../main/java/org/apache/streams/pipl/Pipl.java    |  46 ++---
 .../main/java/org/apache/streams/pipl/Search.java  |  25 +--
 .../apache/streams/thedatagroup/SyncAppend.java    |  30 +--
 .../apache/streams/thedatagroup/SyncLookup.java    |  26 +--
 .../apache/streams/thedatagroup/TheDataGroup.java  |  67 ++++---
 .../apache/streams/instagram/api/Instagram.java    |  49 +++--
 .../instagram/api/InstagramRetryHandler.java       |  60 ------
 .../instagram/provider/InstagramDataCollector.java |   1 -
 .../userinfo/InstagramUserInfoCollector.java       |   2 +-
 .../org/apache/streams/sprinklr/Bootstrap.java     |  11 +-
 .../java/org/apache/streams/sprinklr/Profiles.java |  14 +-
 .../java/org/apache/streams/sprinklr/Sprinklr.java |  55 +++---
 .../org/apache/streams/twitter/api/Account.java    |  22 +--
 .../streams/twitter/api/AccountActivity.java       |  27 ++-
 .../apache/streams/twitter/api/DirectMessages.java |  38 ++--
 .../org/apache/streams/twitter/api/Favorites.java  |  13 +-
 .../org/apache/streams/twitter/api/Followers.java  |  14 +-
 .../org/apache/streams/twitter/api/Friends.java    |  14 +-
 .../apache/streams/twitter/api/Friendships.java    |  38 ++--
 .../java/org/apache/streams/twitter/api/Geo.java   |  19 +-
 .../java/org/apache/streams/twitter/api/Media.java |  10 +-
 .../apache/streams/twitter/api/SevenDaySearch.java |  10 +-
 .../org/apache/streams/twitter/api/Statuses.java   |  33 ++--
 .../apache/streams/twitter/api/SuggestedUsers.java |  19 +-
 .../streams/twitter/api/ThirtyDaySearch.java       |  12 +-
 .../streams/twitter/api/ThirtyDaySearchCounts.java |  12 +-
 .../org/apache/streams/twitter/api/Twitter.java    | 216 +++++++++------------
 .../api/TwitterOAuthRequestInterceptor.java        |   9 +-
 .../streams/twitter/api/TwitterRetryHandler.java   |  81 --------
 .../streams/twitter/api/TwitterSecurity.java       |  13 +-
 .../java/org/apache/streams/twitter/api/Users.java |  21 +-
 .../streams/twitter/api/WelcomeMessageRules.java   |  25 +--
 .../streams/twitter/api/WelcomeMessages.java       |  25 +--
 .../streams/twitter/converter/TwitterDateSwap.java |  26 +--
 .../twitter/converter/TwitterJodaDateSwap.java     |  49 -----
 .../streams/plugins/JuneauPojoAnnotator.java       |  12 +-
 .../java/org/apache/streams/juneau/DateSwap.java   |  69 -------
 .../org/apache/streams/juneau/JodaDateSwap.java    |  65 -------
 48 files changed, 529 insertions(+), 954 deletions(-)

diff --git a/pom.xml b/pom.xml
index d13c3f5784..e223cdb0b4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -381,7 +381,7 @@
         <joda-time.version>2.9.9</joda-time.version>
         <json-path.version>2.8.0</json-path.version>
         <json-schema-validator.version>1.1.0</json-schema-validator.version>
-        <juneau.version>7.2.1</juneau.version>
+        <juneau.version>9.0.1</juneau.version>
         <jsonschema2pojo.version>1.2.1</jsonschema2pojo.version>
         <jaxb2.version>0.15.3</jaxb2.version>
         <jaxb2-basics.version>0.13.1</jaxb2-basics.version>
diff --git a/streams-cli/pom.xml b/streams-cli/pom.xml
index 8cd638bc17..e523028961 100644
--- a/streams-cli/pom.xml
+++ b/streams-cli/pom.xml
@@ -45,10 +45,10 @@
             <groupId>org.apache.juneau</groupId>
             <artifactId>juneau-marshall</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.apache.juneau</groupId>
-            <artifactId>juneau-marshall-rdf</artifactId>
-        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>org.apache.juneau</groupId>-->
+<!--            <artifactId>juneau-marshall-rdf</artifactId>-->
+<!--        </dependency>-->
         <dependency>
             <groupId>org.freemarker</groupId>
             <artifactId>freemarker</artifactId>
diff --git a/streams-config/src/test/java/org/apache/streams/config/test/StreamsConfigurationForTesting.java b/streams-config/src/test/java/org/apache/streams/config/test/StreamsConfigurationForTesting.java
index dab82d6597..5a814737da 100644
--- a/streams-config/src/test/java/org/apache/streams/config/test/StreamsConfigurationForTesting.java
+++ b/streams-config/src/test/java/org/apache/streams/config/test/StreamsConfigurationForTesting.java
@@ -22,16 +22,16 @@ import org.apache.streams.config.ComponentConfiguration;
 import org.apache.streams.config.StreamsConfiguration;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
-import org.apache.juneau.annotation.BeanProperty;
+import org.apache.juneau.annotation.Beanp;
 
 public class StreamsConfigurationForTesting extends StreamsConfiguration {
 
   @JsonProperty("componentOne")
-  @BeanProperty("componentOne")
+  @Beanp("componentOne")
   private org.apache.streams.config.ComponentConfiguration componentOne;
 
   @JsonProperty("componentTwo")
-  @BeanProperty("componentTwo")
+  @Beanp("componentTwo")
   private org.apache.streams.config.ComponentConfiguration componentTwo;
 
   public StreamsConfigurationForTesting() {
@@ -43,25 +43,25 @@ public class StreamsConfigurationForTesting extends StreamsConfiguration {
   }
 
   @JsonProperty("componentOne")
-  @BeanProperty("componentOne")
+  @Beanp("componentOne")
   public ComponentConfiguration getComponentOne() {
     return componentOne;
   }
 
   @JsonProperty("componentOne")
-  @BeanProperty("componentOne")
+  @Beanp("componentOne")
   public void setComponentOne(ComponentConfiguration componentOne) {
     this.componentOne = componentOne;
   }
 
   @JsonProperty("componentTwo")
-  @BeanProperty("componentTwo")
+  @Beanp("componentTwo")
   public ComponentConfiguration getComponentTwo() {
     return componentTwo;
   }
 
   @JsonProperty("componentTwo")
-  @BeanProperty("componentTwo")
+  @Beanp("componentTwo")
   public void setComponentTwo(ComponentConfiguration componentTwo) {
     this.componentTwo = componentTwo;
   }
diff --git a/streams-contrib/streams-processor-fullcontact/src/main/java/org/apache/streams/fullcontact/CompanyEnrichment.java b/streams-contrib/streams-processor-fullcontact/src/main/java/org/apache/streams/fullcontact/CompanyEnrichment.java
index 6782374a33..5bbcd7817e 100644
--- a/streams-contrib/streams-processor-fullcontact/src/main/java/org/apache/streams/fullcontact/CompanyEnrichment.java
+++ b/streams-contrib/streams-processor-fullcontact/src/main/java/org/apache/streams/fullcontact/CompanyEnrichment.java
@@ -18,17 +18,16 @@
 
 package org.apache.streams.fullcontact;
 
+import org.apache.juneau.http.annotation.Content;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemotePost;
 import org.apache.streams.fullcontact.api.EnrichCompanyRequest;
 import org.apache.streams.fullcontact.pojo.CompanySummary;
 
-import org.apache.juneau.http.annotation.Body;
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
-
-@RemoteInterface(path = "https://api.fullcontact.com/v3/company.enrich")
+@Remote(path = "https://api.fullcontact.com/v3/company.enrich")
 public interface CompanyEnrichment {
 
-  @RemoteMethod(method ="POST")
-  public CompanySummary enrichCompany(@Body EnrichCompanyRequest request);
+  @RemotePost
+  public CompanySummary enrichCompany(@Content EnrichCompanyRequest request);
 
-}
\ No newline at end of file
+}
diff --git a/streams-contrib/streams-processor-fullcontact/src/main/java/org/apache/streams/fullcontact/FullContact.java b/streams-contrib/streams-processor-fullcontact/src/main/java/org/apache/streams/fullcontact/FullContact.java
index 933337f3ac..4959fe9a2c 100644
--- a/streams-contrib/streams-processor-fullcontact/src/main/java/org/apache/streams/fullcontact/FullContact.java
+++ b/streams-contrib/streams-processor-fullcontact/src/main/java/org/apache/streams/fullcontact/FullContact.java
@@ -19,6 +19,7 @@
 package org.apache.streams.fullcontact;
 
 import org.apache.juneau.rest.client.RestCallException;
+import org.apache.juneau.rest.client.RestRequest;
 import org.apache.streams.config.ComponentConfigurator;
 import org.apache.streams.fullcontact.api.EnrichCompanyRequest;
 import org.apache.streams.fullcontact.api.EnrichPersonRequest;
@@ -30,9 +31,7 @@ import org.apache.streams.fullcontact.pojo.PersonSummary;
 import com.google.common.util.concurrent.Uninterruptibles;
 import org.apache.juneau.json.JsonParser;
 import org.apache.juneau.json.JsonSerializer;
-import org.apache.juneau.rest.client.RestCall;
 import org.apache.juneau.rest.client.RestClient;
-import org.apache.juneau.rest.client.RestClientBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -53,7 +52,7 @@ public class FullContact implements CompanyEnrichment, PersonEnrichment {
   protected JsonParser parser;
   protected JsonSerializer serializer;
 
-  protected RestClientBuilder restClientBuilder;
+  protected RestClient.Builder restClientBuilder;
   protected RestClient restClient;
 
   private static Map<FullContactConfiguration, FullContact> INSTANCE_MAP = new ConcurrentHashMap<>();
@@ -74,10 +73,10 @@ public class FullContact implements CompanyEnrichment, PersonEnrichment {
 
   private FullContact(FullContactConfiguration configuration) {
     this.configuration = configuration;
-    this.parser = JsonParser.DEFAULT.builder()
-      .ignoreUnknownBeanProperties(true)
+    this.parser = JsonParser.DEFAULT.copy()
+      .ignoreUnknownBeanProperties()
       .build();
-    this.serializer = JsonSerializer.DEFAULT.builder()
+    this.serializer = JsonSerializer.DEFAULT.copy()
       .trimEmptyCollections(true)
       .trimEmptyMaps(true)
       .build();
@@ -105,11 +104,11 @@ public class FullContact implements CompanyEnrichment, PersonEnrichment {
   public CompanySummary enrichCompany(EnrichCompanyRequest request) {
     try {
       String requestJson = serializer.serialize(request);
-      RestCall call = restClient
-        .doPost(baseUrl() + "company.enrich")
+      RestRequest call = restClient
+        .post(baseUrl() + "company.enrich")
         .accept("application/json")
         .contentType("application/json")
-        .body(new StringReader(requestJson));
+        .content(new StringReader(requestJson));
       String responseJson = call.getResponseAsString();
       CompanySummary result = parser.parse(responseJson, CompanySummary.class);
       return result;
@@ -125,12 +124,12 @@ public class FullContact implements CompanyEnrichment, PersonEnrichment {
   public EnrichPersonResponse enrichPerson(EnrichPersonRequest request) {
     try {
       String requestJson = serializer.serialize(request);
-      RestCall call = restClient
-              .doPost(baseUrl() + "person.enrich")
+      RestRequest call = restClient
+              .post(baseUrl() + "person.enrich")
               .accept("application/json")
               .contentType("application/json")
-              .ignoreErrors()
-              .body(new StringReader(requestJson));
+              .content(new StringReader(requestJson))
+              .ignoreErrors();
       String responseJson = call.getResponseAsString();
       EnrichPersonResponse response = parser.parse(responseJson, EnrichPersonResponse.class);
       return response;
@@ -141,4 +140,4 @@ public class FullContact implements CompanyEnrichment, PersonEnrichment {
       Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS);
     }
   }
-}
\ No newline at end of file
+}
diff --git a/streams-contrib/streams-processor-fullcontact/src/main/java/org/apache/streams/fullcontact/PersonEnrichment.java b/streams-contrib/streams-processor-fullcontact/src/main/java/org/apache/streams/fullcontact/PersonEnrichment.java
index d4202ac8fc..61d2270fda 100644
--- a/streams-contrib/streams-processor-fullcontact/src/main/java/org/apache/streams/fullcontact/PersonEnrichment.java
+++ b/streams-contrib/streams-processor-fullcontact/src/main/java/org/apache/streams/fullcontact/PersonEnrichment.java
@@ -18,17 +18,16 @@
 
 package org.apache.streams.fullcontact;
 
+import org.apache.juneau.http.annotation.Content;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemotePost;
 import org.apache.streams.fullcontact.api.EnrichPersonRequest;
 import org.apache.streams.fullcontact.api.EnrichPersonResponse;
 
-import org.apache.juneau.http.annotation.Body;
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
-
-@RemoteInterface(path = "https://api.fullcontact.com/v3/person.enrich")
+@Remote(path = "https://api.fullcontact.com/v3/person.enrich")
 public interface PersonEnrichment {
 
-  @RemoteMethod(method ="POST")
-  public EnrichPersonResponse enrichPerson(@Body EnrichPersonRequest request);
+  @RemotePost
+  public EnrichPersonResponse enrichPerson(@Content EnrichPersonRequest request);
 
-}
\ No newline at end of file
+}
diff --git a/streams-contrib/streams-processor-fullcontact/src/main/scala/org/apache/streams/fullcontact/util/AffinityOrdering.scala b/streams-contrib/streams-processor-fullcontact/src/main/scala/org/apache/streams/fullcontact/util/AffinityOrdering.scala
index dabadc13c9..7f1f5b054e 100644
--- a/streams-contrib/streams-processor-fullcontact/src/main/scala/org/apache/streams/fullcontact/util/AffinityOrdering.scala
+++ b/streams-contrib/streams-processor-fullcontact/src/main/scala/org/apache/streams/fullcontact/util/AffinityOrdering.scala
@@ -18,9 +18,9 @@
 
 package org.apache.streams.fullcontact.util
 
-import org.apache.juneau.ObjectMap
+import org.apache.juneau.collections.JsonMap
 
-object AffinityOrdering extends Ordering[ObjectMap] {
+object AffinityOrdering extends Ordering[JsonMap] {
   def sortByAffinityString(s1: String, s2: String) : Int = {
     if(s1 == null && s2 == null) return 0;
     if(s1 == null ) return -1;
@@ -31,8 +31,8 @@ object AffinityOrdering extends Ordering[ObjectMap] {
     if(s2.isEmpty ) return 1;
     return s1.takeRight(1).compareToIgnoreCase(s2.takeRight(1))
   }
-  def sortByAffinity(o1: ObjectMap, o2: ObjectMap) : Int = {
+  def sortByAffinity(o1: JsonMap, o2: JsonMap) : Int = {
     return sortByAffinityString(o1.getString("affinity", ""), o2.getString("affinity", ""))
   }
-  def compare(a:ObjectMap, b:ObjectMap) = sortByAffinity(a,b)
+  def compare(a:JsonMap, b:JsonMap) = sortByAffinity(a,b)
 }
diff --git a/streams-contrib/streams-processor-fullcontact/src/main/scala/org/apache/streams/fullcontact/util/FullContactUtils.scala b/streams-contrib/streams-processor-fullcontact/src/main/scala/org/apache/streams/fullcontact/util/FullContactUtils.scala
index f3f910f250..e30d4bcb12 100644
--- a/streams-contrib/streams-processor-fullcontact/src/main/scala/org/apache/streams/fullcontact/util/FullContactUtils.scala
+++ b/streams-contrib/streams-processor-fullcontact/src/main/scala/org/apache/streams/fullcontact/util/FullContactUtils.scala
@@ -18,13 +18,15 @@
 
 package org.apache.streams.fullcontact.util
 
-import org.apache.juneau.ObjectList
-import org.apache.juneau.ObjectMap
 import org.apache.juneau.json.JsonParser
 import org.apache.streams.config.ComponentConfigurator
-
 import scala.collection.mutable.ListBuffer
 
+import org.apache.juneau.collections.JsonList
+import org.apache.juneau.collections.JsonMap
+import org.apache.juneau.http.HttpHeaders.authorization
+import org.reflections.util.ConfigurationBuilder.build
+
 case class Employer(name : String, domain : String)
 
 case class EmployerRelationship(personId : String, employerId : String)
@@ -446,26 +448,24 @@ object FullContactUtils {
     import org.apache.http.client.utils.URIBuilder
     import org.apache.juneau.json.JsonParser
     import org.apache.juneau.json.JsonSerializer
-    import org.apache.juneau.rest.client.RestCall
     import org.apache.juneau.rest.client.RestClient
     val auth_header = s"Bearer ${config.getToken()}"
     val url = "https://api.fullcontact.com/v3/person.enrich"
     val uri : URI = new URIBuilder(url).build()
     lazy val parser = JsonParser.create().
       debug().
-      ignoreUnknownBeanProperties(true).
-      ignorePropertiesWithoutSetters(true).
+      ignoreUnknownBeanProperties().
       build()
     lazy val serializer = JsonSerializer.create().
       debug().
+      keepNullProperties(false).
       trimEmptyCollections(true).
-      trimNullProperties(true).
       trimEmptyMaps(true).
       build()
     val restClientBuilder = RestClient.
       create().
-      authorization(auth_header).
-      beansRequireSerializable(true).
+      header("Authorization", auth_header).
+      beansRequireSerializable().
       debug().
       disableAutomaticRetries().
       disableCookieManagement().
@@ -475,10 +475,9 @@ object FullContactUtils {
       rootUrl(uri).
       serializer(serializer)
 
-    val post : RestCall = restClientBuilder.
+    val post = restClientBuilder.
       build().
-      doPost(uri).
-      body(request)
+      post(uri, request)
 
     Thread.sleep(1000)
 
@@ -499,38 +498,38 @@ object FullContactUtils {
     Try(parseEnrichPersonResponse(response)).toOption
   }
 
-  def educationItem(row : ObjectMap) : Option[String] = Try(f"""${row.getString("name","")}%s ${row.getString("degree","")}%s (${row.getAt("start/year",classOf[String])}%s - ${row.getAt("end/year",classOf[String])}%s)""").toOption
+  def educationItem(row : JsonMap) : Option[String] = Try(f"""${row.getString("name","")}%s ${row.getString("degree","")}%s (${row.getAt("start/year",classOf[String])}%s - ${row.getAt("end/year",classOf[String])}%s)""").toOption
   def educationSummary(json : String) : List[String] = {
-    val list = JsonParser.DEFAULT.parse(json, classOf[ObjectList])
-    val summaries = Try(list.elements(classOf[ObjectMap]).flatMap( row => educationItem(row) ))
+    val list = JsonParser.DEFAULT.parse(json, classOf[JsonList])
+    val summaries = Try(list.elements(classOf[JsonMap]).flatMap( row => educationItem(row) ))
     if( summaries.isFailure || summaries.get.size == 0 ) return List() else return summaries.get.toList
   }
 
-  def employmentItem(row : ObjectMap) : Option[String] = Try(f"""${row.getString("name","")}%s ${row.getString("title","")}%s (${row.getAt("start/year",classOf[String])}%s - ${row.getAt("end/year",classOf[String])})""").toOption
+  def employmentItem(row : JsonMap) : Option[String] = Try(f"""${row.getString("name","")}%s ${row.getString("title","")}%s (${row.getAt("start/year",classOf[String])}%s - ${row.getAt("end/year",classOf[String])})""").toOption
   def employmentSummary(json : String) : List[String] = {
-    val list = JsonParser.DEFAULT.parse(json, classOf[ObjectList])
-    val summaries = Try(list.elements(classOf[ObjectMap]).flatMap( row => employmentItem(row)))
+    val list = JsonParser.DEFAULT.parse(json, classOf[JsonList])
+    val summaries = Try(list.elements(classOf[JsonMap]).flatMap( row => employmentItem(row)))
     if( summaries.isFailure || summaries.get.size == 0 ) return List() else summaries.get.toList
   }
 
-  def interestItem(row : ObjectMap) : Option[String] = Try(f"""${row.getString("name","")}%s (${row.getString("affinity","")}%s)""").toOption
+  def interestItem(row : JsonMap) : Option[String] = Try(f"""${row.getString("name","")}%s (${row.getString("affinity","")}%s)""").toOption
   def interestSummary(json : String) : List[String] = {
-    val list = JsonParser.DEFAULT.parse(json, classOf[ObjectList])
-    val summaries = Try(list.elements(classOf[ObjectMap]).toSeq.sorted(AffinityOrdering).flatMap( row => interestItem(row)))
+    val list = JsonParser.DEFAULT.parse(json, classOf[JsonList])
+    val summaries = Try(list.elements(classOf[JsonMap]).toSeq.sorted(AffinityOrdering).flatMap( row => interestItem(row)))
     if( summaries.isFailure || summaries.get.size == 0 ) return List() else summaries.get.toList
   }
 
-  def profileItem(row : ObjectMap) : Option[String] = Try(f"""${row.get("url")}%s""").toOption
+  def profileItem(row : JsonMap) : Option[String] = Try(f"""${row.get("url")}%s""").toOption
   def profileSummary(json : String) : List[String] = {
-    val map = JsonParser.DEFAULT.parse(json, classOf[ObjectMap])
-    val summaries = Try(map.entrySet().flatMap( row => profileItem(row.getValue().asInstanceOf[ObjectMap])).toSeq.sorted)
+    val map = JsonParser.DEFAULT.parse(json, classOf[JsonMap])
+    val summaries = Try(map.entrySet().flatMap( row => profileItem(row.getValue().asInstanceOf[JsonMap])).toSeq.sorted)
     if( summaries.isFailure || summaries.get.size == 0 ) return List() else summaries.get.toList
   }
 
-  def urlItem(row : ObjectMap) : Option[String] = Try(f"""${row.get("value")}%s""").toOption
+  def urlItem(row : JsonMap) : Option[String] = Try(f"""${row.get("value")}%s""").toOption
   def urlSummary(json : String) : List[String] = {
-    val list = JsonParser.DEFAULT.parse(json, classOf[ObjectList])
-    val summaries = Try(list.elements(classOf[ObjectMap]).flatMap( row => urlItem(row)).toSeq.sorted)
+    val list = JsonParser.DEFAULT.parse(json, classOf[JsonList])
+    val summaries = Try(list.elements(classOf[JsonMap]).flatMap( row => urlItem(row)).toSeq.sorted)
     if( summaries.isFailure || summaries.get.size == 0 ) return List() else summaries.get.toList
   }
 
diff --git a/streams-contrib/streams-processor-peopledatalabs/src/main/java/org/apache/streams/peopledatalabs/PeopleDataLabs.java b/streams-contrib/streams-processor-peopledatalabs/src/main/java/org/apache/streams/peopledatalabs/PeopleDataLabs.java
index 6f32ccec1c..177fecf5f1 100755
--- a/streams-contrib/streams-processor-peopledatalabs/src/main/java/org/apache/streams/peopledatalabs/PeopleDataLabs.java
+++ b/streams-contrib/streams-processor-peopledatalabs/src/main/java/org/apache/streams/peopledatalabs/PeopleDataLabs.java
@@ -20,16 +20,16 @@ package org.apache.streams.peopledatalabs;
 
 import org.apache.http.entity.StringEntity;
 import org.apache.http.util.EntityUtils;
-import org.apache.juneau.ObjectMap;
+import org.apache.juneau.collections.JsonMap;
 import org.apache.juneau.rest.client.RestCallException;
+import org.apache.juneau.rest.client.RestRequest;
 import org.apache.streams.config.ComponentConfigurator;
 
 import com.google.common.util.concurrent.Uninterruptibles;
 import org.apache.juneau.json.JsonParser;
 import org.apache.juneau.json.JsonSerializer;
-import org.apache.juneau.rest.client.RestCall;
+
 import org.apache.juneau.rest.client.RestClient;
-import org.apache.juneau.rest.client.RestClientBuilder;
 import org.apache.streams.peopledatalabs.api.BulkEnrichPersonRequest;
 import org.apache.streams.peopledatalabs.api.BulkEnrichPersonResponseItem;
 import org.apache.streams.peopledatalabs.api.EnrichPersonRequest;
@@ -58,7 +58,7 @@ public class PeopleDataLabs implements PersonEnrichment {
   JsonParser parser;
   JsonSerializer serializer;
 
-  RestClientBuilder restClientBuilder;
+  RestClient.Builder restClientBuilder;
   RestClient restClient;
 
   private static Map<PeopleDataLabsConfiguration, PeopleDataLabs> INSTANCE_MAP = new ConcurrentHashMap<>();
@@ -79,10 +79,10 @@ public class PeopleDataLabs implements PersonEnrichment {
 
   private PeopleDataLabs(PeopleDataLabsConfiguration configuration) {
     this.configuration = configuration;
-    this.parser = JsonParser.DEFAULT.builder()
-      .ignoreUnknownBeanProperties(true)
+    this.parser = JsonParser.DEFAULT.copy()
+      .ignoreUnknownBeanProperties()
       .build();
-    this.serializer = JsonSerializer.DEFAULT.builder()
+    this.serializer = JsonSerializer.DEFAULT.copy()
       .trimEmptyCollections(true)
       .trimEmptyMaps(true)
       .build();
@@ -109,17 +109,8 @@ public class PeopleDataLabs implements PersonEnrichment {
   public EnrichPersonResponse enrichPerson(EnrichPersonRequest request) {
     try {
       // TODO: use juneau remoting here once upgraded and tested
-      //      PersonEnrichment personEnrichment = restClient.getRemoteResource(PersonEnrichment.class);
-      String requestJson = serializer.serialize(request);
-      ObjectMap requestParams = new ObjectMap(requestJson);
-      RestCall call = restClient
-          .doGet(baseUrl() + "person")
-          .accept("application/json")
-          .contentType("application/json")
-          .ignoreErrors()
-          .queryIfNE(requestParams);
-      String responseJson = call.getResponseAsString();
-      EnrichPersonResponse result = parser.parse(responseJson, EnrichPersonResponse.class);
+      PersonEnrichment personEnrichment = restClient.getRemote(PersonEnrichment.class);
+      EnrichPersonResponse result = personEnrichment.enrichPerson(request);
       return result;
     } catch( Exception e ) {
       LOGGER.error("Exception", e);
@@ -133,18 +124,8 @@ public class PeopleDataLabs implements PersonEnrichment {
   @Override
   public List<BulkEnrichPersonResponseItem> bulkEnrichPerson(BulkEnrichPersonRequest request) {
     try {
-      // TODO: use juneau remoting here once upgraded and tested
-      //    PersonEnrichment personEnrichment = restClient.getRemoteResource(PersonEnrichment.class);
-      //    List<EnrichPersonResponse> result = personEnrichment.bulkEnrichPerson(request);
-      String requestJson = serializer.serialize(request);
-      RestCall call = restClient
-        .doPost(baseUrl() + "person/bulk")
-        .accept("application/json")
-        .contentType("application/json")
-        .ignoreErrors()
-        .body(new StringReader(requestJson));
-      String responseJson = call.getResponseAsString();
-      List<BulkEnrichPersonResponseItem> result = parser.parse(responseJson, List.class, BulkEnrichPersonResponseItem.class);
+      PersonEnrichment personEnrichment = restClient.getRemote(PersonEnrichment.class);
+      List<BulkEnrichPersonResponseItem> result = personEnrichment.bulkEnrichPerson(request);
       return result;
     } catch( Exception e ) {
       LOGGER.error("Exception", e);
@@ -153,4 +134,4 @@ public class PeopleDataLabs implements PersonEnrichment {
       Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS);
     }
   }
-}
\ No newline at end of file
+}
diff --git a/streams-contrib/streams-processor-peopledatalabs/src/main/java/org/apache/streams/peopledatalabs/PersonEnrichment.java b/streams-contrib/streams-processor-peopledatalabs/src/main/java/org/apache/streams/peopledatalabs/PersonEnrichment.java
index 4d42c317b9..09533a4454 100755
--- a/streams-contrib/streams-processor-peopledatalabs/src/main/java/org/apache/streams/peopledatalabs/PersonEnrichment.java
+++ b/streams-contrib/streams-processor-peopledatalabs/src/main/java/org/apache/streams/peopledatalabs/PersonEnrichment.java
@@ -18,26 +18,26 @@
 
 package org.apache.streams.peopledatalabs;
 
-import org.apache.juneau.rest.client.RestCallException;
+import org.apache.juneau.http.annotation.Content;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemoteGet;
+import org.apache.juneau.http.remote.RemotePost;
 import org.apache.streams.peopledatalabs.api.BulkEnrichPersonResponseItem;
 import org.apache.streams.peopledatalabs.api.EnrichPersonRequest;
 import org.apache.streams.peopledatalabs.api.BulkEnrichPersonRequest;
 import org.apache.streams.peopledatalabs.api.EnrichPersonResponse;
 
-import org.apache.juneau.http.annotation.Body;
 import org.apache.juneau.http.annotation.Query;
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
 
 import java.util.List;
 
-@RemoteInterface(path = "https://api.peopledatalabs.com/v4")
+@Remote(path = "https://api.peopledatalabs.com/v4")
 public interface PersonEnrichment {
 
-    @RemoteMethod(method ="GET", path="/person")
-    public EnrichPersonResponse enrichPerson(@Query(name = "*", skipIfEmpty = true) EnrichPersonRequest request);
+    @RemoteGet(path="/person")
+    public EnrichPersonResponse enrichPerson(@Query(name = "*") EnrichPersonRequest request);
 
-    @RemoteMethod(method ="POST", path="/person/bulk")
-    public List<BulkEnrichPersonResponseItem> bulkEnrichPerson(@Body(required = true) BulkEnrichPersonRequest request);
+    @RemotePost(path="/person/bulk")
+    public List<BulkEnrichPersonResponseItem> bulkEnrichPerson(@Content BulkEnrichPersonRequest request);
 
-}
\ No newline at end of file
+}
diff --git a/streams-contrib/streams-processor-pipl/src/main/java/org/apache/streams/pipl/Pipl.java b/streams-contrib/streams-processor-pipl/src/main/java/org/apache/streams/pipl/Pipl.java
index e2b0fa7302..83117af73a 100755
--- a/streams-contrib/streams-processor-pipl/src/main/java/org/apache/streams/pipl/Pipl.java
+++ b/streams-contrib/streams-processor-pipl/src/main/java/org/apache/streams/pipl/Pipl.java
@@ -19,12 +19,13 @@
 package org.apache.streams.pipl;
 
 import com.google.common.util.concurrent.Uninterruptibles;
-import org.apache.juneau.ObjectMap;
+import org.apache.commons.collections4.Get;
+import org.apache.juneau.collections.JsonMap;
 import org.apache.juneau.json.JsonParser;
 import org.apache.juneau.json.JsonSerializer;
-import org.apache.juneau.rest.client.RestCall;
 import org.apache.juneau.rest.client.RestClient;
-import org.apache.juneau.rest.client.RestClientBuilder;
+
+import org.apache.juneau.rest.client.RestRequest;
 import org.apache.streams.config.ComponentConfigurator;
 import org.apache.streams.pipl.api.BasicSearchRequest;
 import org.apache.streams.pipl.api.FullPersonSearchRequest;
@@ -50,7 +51,7 @@ public class Pipl implements Search {
   JsonParser parser;
   JsonSerializer serializer;
 
-  RestClientBuilder restClientBuilder;
+  RestClient.Builder restClientBuilder;
   RestClient restClient;
 
   private static Map<PiplConfiguration, Pipl> INSTANCE_MAP = new ConcurrentHashMap<>();
@@ -71,18 +72,17 @@ public class Pipl implements Search {
 
   private Pipl(PiplConfiguration configuration) {
     this.configuration = configuration;
-    this.parser = JsonParser.DEFAULT.builder()
-      .ignoreUnknownBeanProperties(true)
+    this.parser = JsonParser.DEFAULT.copy()
+      .ignoreUnknownBeanProperties()
       .build();
-    this.serializer = JsonSerializer.DEFAULT.builder()
+    this.serializer = JsonSerializer.DEFAULT.copy()
       .trimEmptyCollections(true)
       .trimEmptyMaps(true)
       .build();
     this.restClientBuilder = RestClient.create()
-      .accept("application/json")
-      .contentType("application/json")
       .disableCookieManagement()
       .disableRedirectHandling()
+      .json()
       .parser(parser)
       .serializer(serializer)
       .rootUrl(baseUrl());
@@ -100,11 +100,11 @@ public class Pipl implements Search {
   public SearchResponse basicSearch(BasicSearchRequest request) {
     try {
       String requestJson = serializer.serialize(request);
-      ObjectMap requestMap = parser.parse(requestJson, ObjectMap.class);
+      JsonMap requestMap = parser.parse(requestJson, JsonMap.class);
       requestMap.put("key", configuration.getKey());
-      RestCall call = restClient
-              .doGet(baseUrl() + "search")
-              .queryIfNE(requestMap)
+      RestRequest call = restClient
+              .get(baseUrl() + "search")
+              .queryDataBean(requestMap)
               .ignoreErrors();
       String responseJson = call.getResponseAsString();
       SearchResponse response = parser.parse(responseJson, SearchResponse.class);
@@ -122,14 +122,14 @@ public class Pipl implements Search {
   public SearchResponse fullPersonSearch(FullPersonSearchRequest request) {
     try {
       String requestJson = serializer.serialize(request);
-      ObjectMap requestMap = parser.parse(requestJson, ObjectMap.class);
+      JsonMap requestMap = parser.parse(requestJson, JsonMap.class);
       Object person = requestMap.remove("person");
       String personJson = serializer.serialize(person);
       requestMap.put("person", personJson);
-      RestCall call = restClient
-          .doPost(baseUrl() + "search")
-          .query("key", configuration.getKey())
-          .query(requestMap)
+      RestRequest call = restClient
+          .post(baseUrl() + "search")
+          .queryData("key", configuration.getKey())
+          .queryDataBean(requestMap)
           .ignoreErrors();
       String responseJson = call.getResponseAsString();
       SearchResponse response = parser.parse(responseJson, SearchResponse.class);
@@ -146,10 +146,10 @@ public class Pipl implements Search {
   @Override
   public SearchResponse pointerSearch(SearchPointerRequest request) {
     try {
-      RestCall call = restClient
-              .doPost(baseUrl() + "search")
-              .query("key", configuration.getKey())
-              .query(request.getSearchPointer())
+      RestRequest call = restClient
+              .post(baseUrl() + "search")
+              .queryData("key", configuration.getKey())
+              .queryDataBean(request.getSearchPointer())
               .ignoreErrors();
       String responseJson = call.getResponseAsString();
       SearchResponse response = parser.parse(responseJson, SearchResponse.class);
@@ -163,4 +163,4 @@ public class Pipl implements Search {
     }
   }
 
-}
\ No newline at end of file
+}
diff --git a/streams-contrib/streams-processor-pipl/src/main/java/org/apache/streams/pipl/Search.java b/streams-contrib/streams-processor-pipl/src/main/java/org/apache/streams/pipl/Search.java
index 44a3046189..a360e2e3d3 100644
--- a/streams-contrib/streams-processor-pipl/src/main/java/org/apache/streams/pipl/Search.java
+++ b/streams-contrib/streams-processor-pipl/src/main/java/org/apache/streams/pipl/Search.java
@@ -18,25 +18,26 @@
 
 package org.apache.streams.pipl;
 
-import org.apache.juneau.http.annotation.Body;
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.remoteable.QueryIfNE;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
+import org.apache.juneau.http.annotation.Content;
+import org.apache.juneau.http.annotation.Query;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemoteGet;
+import org.apache.juneau.http.remote.RemotePost;
 import org.apache.streams.pipl.api.BasicSearchRequest;
 import org.apache.streams.pipl.api.FullPersonSearchRequest;
 import org.apache.streams.pipl.api.SearchPointerRequest;
 import org.apache.streams.pipl.api.SearchResponse;
 
-@RemoteInterface(path = "https://api.pipl.com/search")
+@Remote(path = "https://api.pipl.com/search")
 public interface Search {
 
-  @RemoteMethod(method ="GET")
-  public SearchResponse basicSearch(@QueryIfNE("*") BasicSearchRequest request);
+  @RemoteGet
+  public SearchResponse basicSearch(@Query("*") BasicSearchRequest request);
 
-  @RemoteMethod(method ="POST")
-  public SearchResponse fullPersonSearch(@Body FullPersonSearchRequest request);
+  @RemotePost
+  public SearchResponse fullPersonSearch(@Content FullPersonSearchRequest request);
 
-  @RemoteMethod(method ="POST")
-  public SearchResponse pointerSearch(@Body SearchPointerRequest request);
+  @RemotePost
+  public SearchResponse pointerSearch(@Content SearchPointerRequest request);
 
-}
\ No newline at end of file
+}
diff --git a/streams-contrib/streams-processor-thedatagroup/src/main/java/org/apache/streams/thedatagroup/SyncAppend.java b/streams-contrib/streams-processor-thedatagroup/src/main/java/org/apache/streams/thedatagroup/SyncAppend.java
index 7949914435..ea82595e95 100644
--- a/streams-contrib/streams-processor-thedatagroup/src/main/java/org/apache/streams/thedatagroup/SyncAppend.java
+++ b/streams-contrib/streams-processor-thedatagroup/src/main/java/org/apache/streams/thedatagroup/SyncAppend.java
@@ -18,27 +18,27 @@
 
 package org.apache.streams.thedatagroup;
 
-import org.apache.juneau.http.annotation.Body;
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
+import org.apache.juneau.http.annotation.Content;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemotePost;
 import org.apache.streams.thedatagroup.api.*;
 
-@RemoteInterface(path = "https://api.thedatagroup.com/v3/sync/append")
+@Remote(path = "https://api.thedatagroup.com/v3/sync/append")
 public interface SyncAppend {
 
-  @RemoteMethod(method ="POST", path="/demographics")
-  public DemographicsAppendResponse appendDemographics(@Body AppendRequest request);
+  @RemotePost(path="/demographics")
+  public DemographicsAppendResponse appendDemographics(@Content AppendRequest request);
 
-  @RemoteMethod(method ="POST", path="/email")
-  public EmailAppendResponse appendEmail(@Body AppendRequest request);
+  @RemotePost(path="/email")
+  public EmailAppendResponse appendEmail(@Content AppendRequest request);
 
-  @RemoteMethod(method ="POST", path="/mobile")
-  public MobileAppendResponse appendMobile(@Body AppendRequest request);
+  @RemotePost(path="/mobile")
+  public MobileAppendResponse appendMobile(@Content AppendRequest request);
 
-  @RemoteMethod(method ="POST", path="/phone")
-  public PhoneAppendResponse appendPhone(@Body AppendRequest request);
+  @RemotePost(path="/phone")
+  public PhoneAppendResponse appendPhone(@Content AppendRequest request);
 
-  @RemoteMethod(method ="POST", path="/vehicle")
-  public VehicleAppendResponse appendVehicle(@Body AppendRequest request);
+  @RemotePost(path="/vehicle")
+  public VehicleAppendResponse appendVehicle(@Content AppendRequest request);
 
-}
\ No newline at end of file
+}
diff --git a/streams-contrib/streams-processor-thedatagroup/src/main/java/org/apache/streams/thedatagroup/SyncLookup.java b/streams-contrib/streams-processor-thedatagroup/src/main/java/org/apache/streams/thedatagroup/SyncLookup.java
index a6bcfafef9..921ea5df3d 100644
--- a/streams-contrib/streams-processor-thedatagroup/src/main/java/org/apache/streams/thedatagroup/SyncLookup.java
+++ b/streams-contrib/streams-processor-thedatagroup/src/main/java/org/apache/streams/thedatagroup/SyncLookup.java
@@ -18,27 +18,27 @@
 
 package org.apache.streams.thedatagroup;
 
-import org.apache.juneau.http.annotation.Body;
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
+import org.apache.juneau.http.annotation.Content;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemotePost;
 import org.apache.streams.thedatagroup.api.EmailLookupRequest;
 import org.apache.streams.thedatagroup.api.IpLookupRequest;
 import org.apache.streams.thedatagroup.api.LookupResponse;
 import org.apache.streams.thedatagroup.api.PhoneLookupRequest;
 
-@RemoteInterface(path = "https://api.thedatagroup.com/v3/sync/lookup")
+@Remote(path = "https://api.thedatagroup.com/v3/sync/lookup")
 public interface SyncLookup {
 
-  @RemoteMethod(method ="POST", path="/email")
-  public LookupResponse lookupEmail(@Body EmailLookupRequest request);
+  @RemotePost(path="/email")
+  public LookupResponse lookupEmail(@Content EmailLookupRequest request);
 
-  @RemoteMethod(method ="POST", path="/mobile")
-  public LookupResponse lookupMobile(@Body PhoneLookupRequest request);
+  @RemotePost(path="/mobile")
+  public LookupResponse lookupMobile(@Content PhoneLookupRequest request);
 
-  @RemoteMethod(method ="POST", path="/ip")
-  public LookupResponse lookupIp(@Body IpLookupRequest request);
+  @RemotePost(path="/ip")
+  public LookupResponse lookupIp(@Content IpLookupRequest request);
 
-  @RemoteMethod(method ="POST", path="/phone")
-  public LookupResponse lookupPhone(@Body PhoneLookupRequest request);
+  @RemotePost(path="/phone")
+  public LookupResponse lookupPhone(@Content PhoneLookupRequest request);
 
-}
\ No newline at end of file
+}
diff --git a/streams-contrib/streams-processor-thedatagroup/src/main/java/org/apache/streams/thedatagroup/TheDataGroup.java b/streams-contrib/streams-processor-thedatagroup/src/main/java/org/apache/streams/thedatagroup/TheDataGroup.java
index e59771d144..5a5b695eee 100755
--- a/streams-contrib/streams-processor-thedatagroup/src/main/java/org/apache/streams/thedatagroup/TheDataGroup.java
+++ b/streams-contrib/streams-processor-thedatagroup/src/main/java/org/apache/streams/thedatagroup/TheDataGroup.java
@@ -21,9 +21,8 @@ package org.apache.streams.thedatagroup;
 import com.google.common.util.concurrent.Uninterruptibles;
 import org.apache.juneau.json.JsonParser;
 import org.apache.juneau.json.JsonSerializer;
-import org.apache.juneau.rest.client.RestCall;
 import org.apache.juneau.rest.client.RestClient;
-import org.apache.juneau.rest.client.RestClientBuilder;
+import org.apache.juneau.rest.client.RestRequest;
 import org.apache.streams.config.ComponentConfigurator;
 import org.apache.streams.thedatagroup.api.AppendRequest;
 import org.apache.streams.thedatagroup.api.DemographicsAppendResponse;
@@ -55,7 +54,7 @@ public class TheDataGroup implements SyncAppend, SyncLookup {
   JsonParser parser;
   JsonSerializer serializer;
 
-  RestClientBuilder restClientBuilder;
+  RestClient.Builder restClientBuilder;
   RestClient restClient;
 
   private static Map<TheDataGroupConfiguration, TheDataGroup> INSTANCE_MAP = new ConcurrentHashMap<>();
@@ -76,10 +75,10 @@ public class TheDataGroup implements SyncAppend, SyncLookup {
 
   private TheDataGroup(TheDataGroupConfiguration configuration) {
     this.configuration = configuration;
-    this.parser = JsonParser.DEFAULT.builder()
-      .ignoreUnknownBeanProperties(true)
+    this.parser = JsonParser.DEFAULT.copy()
+      .ignoreUnknownBeanProperties()
       .build();
-    this.serializer = JsonSerializer.DEFAULT.builder()
+    this.serializer = JsonSerializer.DEFAULT.copy()
       .trimEmptyCollections(true)
       .trimEmptyMaps(true)
       .build();
@@ -106,9 +105,9 @@ public class TheDataGroup implements SyncAppend, SyncLookup {
   @Override
   public DemographicsAppendResponse appendDemographics(AppendRequest request) {
     try {
-      RestCall call = restClient
-              .doPost(baseUrl() + "sync/append/demographics")
-              .body(request)
+      RestRequest call = restClient
+              .post(baseUrl() + "sync/append/demographics")
+              .content(request)
               .ignoreErrors();
       String responseJson = call.getResponseAsString();
       DemographicsAppendResponse response = parser.parse(responseJson, DemographicsAppendResponse.class);
@@ -124,9 +123,9 @@ public class TheDataGroup implements SyncAppend, SyncLookup {
   @Override
   public EmailAppendResponse appendEmail(AppendRequest request) {
     try {
-      RestCall call = restClient
-              .doPost(baseUrl() + "sync/append/email")
-              .body(request)
+      RestRequest call = restClient
+              .post(baseUrl() + "sync/append/email")
+              .content(request)
               .ignoreErrors();
       String responseJson = call.getResponseAsString();
       EmailAppendResponse response = parser.parse(responseJson, EmailAppendResponse.class);
@@ -142,9 +141,9 @@ public class TheDataGroup implements SyncAppend, SyncLookup {
   @Override
   public PhoneAppendResponse appendPhone(AppendRequest request) {
     try {
-      RestCall call = restClient
-              .doPost(baseUrl() + "sync/append/phone")
-              .body(request)
+      RestRequest call = restClient
+              .post(baseUrl() + "sync/append/phone")
+              .content(request)
               .ignoreErrors();
       String responseJson = call.getResponseAsString();
       PhoneAppendResponse response = parser.parse(responseJson, PhoneAppendResponse.class);
@@ -160,9 +159,9 @@ public class TheDataGroup implements SyncAppend, SyncLookup {
   @Override
   public MobileAppendResponse appendMobile(AppendRequest request) {
     try {
-      RestCall call = restClient
-              .doPost(baseUrl() + "sync/append/mobile")
-              .body(request)
+      RestRequest call = restClient
+              .post(baseUrl() + "sync/append/mobile")
+              .content(request)
               .ignoreErrors();
       String responseJson = call.getResponseAsString();
       MobileAppendResponse response = parser.parse(responseJson, MobileAppendResponse.class);
@@ -178,9 +177,9 @@ public class TheDataGroup implements SyncAppend, SyncLookup {
   @Override
   public VehicleAppendResponse appendVehicle(AppendRequest request) {
     try {
-      RestCall call = restClient
-              .doPost(baseUrl() + "sync/append/vehicle")
-              .body(request)
+      RestRequest call = restClient
+              .post(baseUrl() + "sync/append/vehicle")
+              .content(request)
               .ignoreErrors();
       String responseJson = call.getResponseAsString();
       VehicleAppendResponse response = parser.parse(responseJson, VehicleAppendResponse.class);
@@ -196,9 +195,9 @@ public class TheDataGroup implements SyncAppend, SyncLookup {
   @Override
   public LookupResponse lookupEmail(EmailLookupRequest request) {
     try {
-      RestCall call = restClient
-              .doPost(baseUrl() + "sync/lookup/email")
-              .body(request)
+      RestRequest call = restClient
+              .post(baseUrl() + "sync/lookup/email")
+              .content(request)
               .ignoreErrors();
       String responseJson = call.getResponseAsString();
       LookupResponse response = parser.parse(responseJson, LookupResponse.class);
@@ -214,9 +213,9 @@ public class TheDataGroup implements SyncAppend, SyncLookup {
   @Override
   public LookupResponse lookupMobile(PhoneLookupRequest request) {
     try {
-      RestCall call = restClient
-              .doPost(baseUrl() + "sync/lookup/mobile")
-              .body(request)
+      RestRequest call = restClient
+              .post(baseUrl() + "sync/lookup/mobile")
+              .content(request)
               .ignoreErrors();
       String responseJson = call.getResponseAsString();
       LookupResponse response = parser.parse(responseJson, LookupResponse.class);
@@ -232,9 +231,9 @@ public class TheDataGroup implements SyncAppend, SyncLookup {
   @Override
   public LookupResponse lookupIp(IpLookupRequest request) {
     try {
-      RestCall call = restClient
-              .doPost(baseUrl() + "sync/lookup/ip")
-              .body(request)
+      RestRequest call = restClient
+              .post(baseUrl() + "sync/lookup/ip")
+              .content(request)
               .ignoreErrors();
       String responseJson = call.getResponseAsString();
       LookupResponse response = parser.parse(responseJson, LookupResponse.class);
@@ -250,9 +249,9 @@ public class TheDataGroup implements SyncAppend, SyncLookup {
   @Override
   public LookupResponse lookupPhone(PhoneLookupRequest request) {
     try {
-      RestCall call = restClient
-              .doPost(baseUrl() + "sync/lookup/phone")
-              .body(request)
+      RestRequest call = restClient
+              .post(baseUrl() + "sync/lookup/phone")
+              .content(request)
               .ignoreErrors();
       String responseJson = call.getResponseAsString();
       LookupResponse response = parser.parse(responseJson, LookupResponse.class);
@@ -264,4 +263,4 @@ public class TheDataGroup implements SyncAppend, SyncLookup {
       Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS);
     }
   }
-}
\ No newline at end of file
+}
diff --git a/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/api/Instagram.java b/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/api/Instagram.java
index 9f5cd63c2c..fd3456582b 100644
--- a/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/api/Instagram.java
+++ b/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/api/Instagram.java
@@ -18,11 +18,12 @@
 
 package org.apache.streams.instagram.api;
 
+import org.apache.juneau.rest.client.BasicHttpRequestRetryHandler;
+import org.apache.juneau.rest.client.RestRequest;
 import org.apache.streams.instagram.config.InstagramConfiguration;
 import org.apache.streams.instagram.pojo.UserRecentMediaRequest;
 import org.apache.streams.instagram.provider.InstagramProviderUtil;
 import org.apache.streams.jackson.StreamsJacksonMapper;
-import org.apache.streams.juneau.JodaDateSwap;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.apache.commons.lang3.StringUtils;
@@ -32,10 +33,8 @@ import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClientBuilder;
 import org.apache.juneau.json.JsonParser;
 import org.apache.juneau.json.JsonSerializer;
-import org.apache.juneau.rest.client.RestCall;
 import org.apache.juneau.rest.client.RestCallException;
 import org.apache.juneau.rest.client.RestClient;
-import org.apache.juneau.rest.client.RestClientBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -86,22 +85,22 @@ public class Instagram implements Media, Users {
     this.restClient = RestClient.create()
         .rootUrl(rootUrl)
         .accept(APPLICATION_JSON.getMimeType())
-        .httpClient(httpclient, true)
+        .httpClient(httpclient)
         .pooled()
         .parser(
-            JsonParser.DEFAULT.builder()
-                .ignoreUnknownBeanProperties(true)
-                .pojoSwaps(JodaDateSwap.class)
+            JsonParser.DEFAULT.copy()
+                .ignoreUnknownBeanProperties()
                 .build())
         .serializer(
-            JsonSerializer.DEFAULT.builder()
-                .pojoSwaps(JodaDateSwap.class)
+            JsonSerializer.DEFAULT.copy()
                 .build())
-        .retryable(
-            configuration.getRetryMax().intValue(),
-            configuration.getRetrySleepMs().intValue(),
-            new InstagramRetryHandler())
-        .build();
+        .retryHandler(
+            new BasicHttpRequestRetryHandler(
+                configuration.getRetryMax().intValue(),
+                configuration.getRetrySleepMs().intValue(),
+                true
+            )
+        ).build();
     this.mapper = StreamsJacksonMapper.getInstance();
   }
 
@@ -134,7 +133,7 @@ public class Instagram implements Media, Users {
       uriBuilder.addParameter("access_token", configuration.getOauth().getAccessToken());
       String sig = oauthSigner.generateSignature(uriBuilder.build().toString());
       uriBuilder.addParameter("sig", sig);
-      RestCall restCall = restClient.doGet(uriBuilder.build().toString());
+      RestRequest restCall = restClient.get(uriBuilder.build().toString());
       try {
         String restResponseEntity = restCall
             .getResponseAsString();
@@ -165,7 +164,7 @@ public class Instagram implements Media, Users {
       uriBuilder.addParameter("access_token", configuration.getOauth().getAccessToken());
       String sig = oauthSigner.generateSignature(uriBuilder.build().toString());
       uriBuilder.addParameter("sig", sig);
-      RestCall restCall = restClient.doGet(uriBuilder.build().toString());
+      RestRequest restCall = restClient.get(uriBuilder.build().toString());
       try {
         String restResponseEntity = restCall
             .getResponseAsString();
@@ -205,7 +204,7 @@ public class Instagram implements Media, Users {
       }
       String sig = oauthSigner.generateSignature(uriBuilder.build().toString());
       uriBuilder.addParameter("sig", sig);
-      RestCall restCall = restClient.doGet(uriBuilder.build().toString());
+      RestRequest restCall = restClient.get(uriBuilder.build().toString());
       try {
         String restResponseEntity = restCall
             .getResponseAsString();
@@ -245,7 +244,7 @@ public class Instagram implements Media, Users {
       }
       String sig = oauthSigner.generateSignature(uriBuilder.build().toString());
       uriBuilder.addParameter("sig", sig);
-      RestCall restCall = restClient.doGet(uriBuilder.build().toString());
+      RestRequest restCall = restClient.get(uriBuilder.build().toString());
       try {
         String restResponseEntity = restCall
             .getResponseAsString();
@@ -282,7 +281,7 @@ public class Instagram implements Media, Users {
       }
       String sig = oauthSigner.generateSignature(uriBuilder.build().toString());
       uriBuilder.addParameter("sig", sig);
-      RestCall restCall = restClient.doGet(uriBuilder.build().toString());
+      RestRequest restCall = restClient.get(uriBuilder.build().toString());
       try {
         String restResponseEntity = restCall
             .getResponseAsString();
@@ -319,7 +318,7 @@ public class Instagram implements Media, Users {
       }
       String sig = oauthSigner.generateSignature(uriBuilder.build().toString());
       uriBuilder.addParameter("sig", sig);
-      RestCall restCall = restClient.doGet(uriBuilder.build().toString());
+      RestRequest restCall = restClient.get(uriBuilder.build().toString());
       try {
         String restResponseEntity = restCall
             .getResponseAsString();
@@ -351,7 +350,7 @@ public class Instagram implements Media, Users {
       uriBuilder.addParameter("media_id", media_id);
       String sig = oauthSigner.generateSignature(uriBuilder.build().toString());
       uriBuilder.addParameter("sig", sig);
-      RestCall restCall = restClient.doGet(uriBuilder.build().toString());
+      RestRequest restCall = restClient.get(uriBuilder.build().toString());
       try {
         String restResponseEntity = restCall
             .getResponseAsString();
@@ -382,7 +381,7 @@ public class Instagram implements Media, Users {
       uriBuilder.addParameter("access_token", configuration.getOauth().getAccessToken());
       String sig = oauthSigner.generateSignature(uriBuilder.build().toString());
       uriBuilder.addParameter("sig", sig);
-      RestCall restCall = restClient.doGet(uriBuilder.build().toString());
+      RestRequest restCall = restClient.get(uriBuilder.build().toString());
       try {
         String restResponseEntity = restCall
             .getResponseAsString();
@@ -413,7 +412,7 @@ public class Instagram implements Media, Users {
       uriBuilder.addParameter("access_token", configuration.getOauth().getAccessToken());
       String sig = oauthSigner.generateSignature(uriBuilder.build().toString());
       uriBuilder.addParameter("sig", sig);
-      RestCall restCall = restClient.doGet(uriBuilder.build().toString());
+      RestRequest restCall = restClient.get(uriBuilder.build().toString());
       try {
         String restResponseEntity = restCall
             .getResponseAsString();
@@ -444,7 +443,7 @@ public class Instagram implements Media, Users {
       uriBuilder.addParameter("access_token", configuration.getOauth().getAccessToken());
       String sig = oauthSigner.generateSignature(uriBuilder.build().toString());
       uriBuilder.addParameter("sig", sig);
-      RestCall restCall = restClient.doGet(uriBuilder.build().toString());
+      RestRequest restCall = restClient.get(uriBuilder.build().toString());
       try {
         String restResponseEntity = restCall
             .getResponseAsString();
@@ -478,7 +477,7 @@ public class Instagram implements Media, Users {
       uriBuilder.addParameter("lng", parameters.getLng().toString());
       String sig = oauthSigner.generateSignature(uriBuilder.build().toString());
       uriBuilder.addParameter("sig", sig);
-      RestCall restCall = restClient.doGet(uriBuilder.build().toString());
+      RestRequest restCall = restClient.get(uriBuilder.build().toString());
       try {
         String restResponseEntity = restCall
             .getResponseAsString();
diff --git a/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/api/InstagramRetryHandler.java b/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/api/InstagramRetryHandler.java
deleted file mode 100644
index 51cd395410..0000000000
--- a/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/api/InstagramRetryHandler.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.apache.streams.instagram.api;
-
-import org.apache.streams.util.api.requests.backoff.AbstractBackOffStrategy;
-
-import org.apache.http.HttpResponse;
-import org.apache.juneau.rest.client.RetryOn;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- *  Handle expected and unexpected exceptions.
- */
-public class InstagramRetryHandler extends RetryOn {
-
-  private static final Logger LOGGER = LoggerFactory.getLogger(InstagramRetryHandler.class);
-
-  private static AbstractBackOffStrategy backoff_strategy;
-
-  protected boolean onResponse(HttpResponse response) {
-    LOGGER.debug(response.toString());
-    switch(response.getStatusLine().getStatusCode()) {
-      case 200: // Response.Status.OK
-      case 304: // Response.Status.NOT_MODIFIED
-      case 400: // Response.Status.BAD_REQUEST
-        return false;
-      case 401: // Response.Status.UNAUTHORIZED
-        return true;
-      case 403: // Response.Status.FORBIDDEN
-      case 404: // Response.Status.NOT_FOUND
-      case 406: // Response.Status.NOT_ACCEPTABLE
-      case 410: // Response.Status.GONE
-        return false;
-      case 500: // Response.Status.INTERNAL_SERVER_ERROR
-      case 502: // Bad Gateway
-      case 503: // Response.Status.SERVICE_UNAVAILABLE
-      case 504: // Gateway Timeout
-        return true;
-      default:
-        return false;
-    }
-  }
-}
diff --git a/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/provider/InstagramDataCollector.java b/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/provider/InstagramDataCollector.java
index f20c9498ae..2f380d2f64 100644
--- a/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/provider/InstagramDataCollector.java
+++ b/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/provider/InstagramDataCollector.java
@@ -27,7 +27,6 @@ import org.apache.streams.util.api.requests.backoff.impl.ExponentialBackOffStrat
 import org.apache.streams.util.oauth.tokens.tokenmanager.SimpleTokenManager;
 import org.apache.streams.util.oauth.tokens.tokenmanager.impl.BasicTokenManager;
 
-import org.apache.juneau.internal.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/provider/userinfo/InstagramUserInfoCollector.java b/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/provider/userinfo/InstagramUserInfoCollector.java
index 9b32c271b2..77e8d1e16b 100644
--- a/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/provider/userinfo/InstagramUserInfoCollector.java
+++ b/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/provider/userinfo/InstagramUserInfoCollector.java
@@ -15,6 +15,7 @@ under the License. */
 
 package org.apache.streams.instagram.provider.userinfo;
 
+import org.apache.commons.lang3.StringUtils;
 import org.apache.streams.core.StreamsDatum;
 import org.apache.streams.instagram.api.Instagram;
 import org.apache.streams.instagram.api.SearchUsersRequest;
@@ -25,7 +26,6 @@ import org.apache.streams.instagram.config.InstagramUserInfoProviderConfiguratio
 import org.apache.streams.instagram.pojo.UserInfo;
 import org.apache.streams.instagram.provider.InstagramDataCollector;
 
-import org.apache.juneau.internal.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/streams-contrib/streams-provider-sprinklr/src/main/java/org/apache/streams/sprinklr/Bootstrap.java b/streams-contrib/streams-provider-sprinklr/src/main/java/org/apache/streams/sprinklr/Bootstrap.java
index 5ea45e4895..82a8ca1775 100644
--- a/streams-contrib/streams-provider-sprinklr/src/main/java/org/apache/streams/sprinklr/Bootstrap.java
+++ b/streams-contrib/streams-provider-sprinklr/src/main/java/org/apache/streams/sprinklr/Bootstrap.java
@@ -18,16 +18,15 @@
 
 package org.apache.streams.sprinklr;
 
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.remoteable.QueryIfNE;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemoteGet;
 
 import org.apache.streams.sprinklr.api.PartnerAccountsResponse;
 
-@RemoteInterface(path = "https://api2.sprinklr.com/api/")
+@Remote(path = "https://api2.sprinklr.com/api/")
 public interface Bootstrap {
 
-  @RemoteMethod(method = "GET")
+  @RemoteGet
   public PartnerAccountsResponse getPartnerAccounts();
 
-}
\ No newline at end of file
+}
diff --git a/streams-contrib/streams-provider-sprinklr/src/main/java/org/apache/streams/sprinklr/Profiles.java b/streams-contrib/streams-provider-sprinklr/src/main/java/org/apache/streams/sprinklr/Profiles.java
index 6b2fba5906..2583d4881b 100644
--- a/streams-contrib/streams-provider-sprinklr/src/main/java/org/apache/streams/sprinklr/Profiles.java
+++ b/streams-contrib/streams-provider-sprinklr/src/main/java/org/apache/streams/sprinklr/Profiles.java
@@ -18,8 +18,8 @@
 
 package org.apache.streams.sprinklr;
 
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemoteGet;
 
 import org.apache.streams.sprinklr.api.ProfileConversationsRequest;
 import org.apache.streams.sprinklr.api.ProfileConversationsResponse;
@@ -28,15 +28,15 @@ import org.apache.streams.sprinklr.api.SocialProfileResponse;
 
 import java.util.List;
 
-@RemoteInterface(path = "https://api2.sprinklr.com/api/")
+@Remote(path = "https://api2.sprinklr.com/api/")
 public interface Profiles {
 
-  @RemoteMethod(method = "GET")
+  @RemoteGet
   public List<SocialProfileResponse> getSocialProfile(SocialProfileRequest request);
 
-  @RemoteMethod(method = "GET")
+  @RemoteGet
   public List<ProfileConversationsResponse> getProfileConversations(ProfileConversationsRequest request);
 
-  @RemoteMethod(method = "GET")
+  @RemoteGet
   public List<ProfileConversationsResponse> getAllProfileConversations(ProfileConversationsRequest request);
-}
\ No newline at end of file
+}
diff --git a/streams-contrib/streams-provider-sprinklr/src/main/java/org/apache/streams/sprinklr/Sprinklr.java b/streams-contrib/streams-provider-sprinklr/src/main/java/org/apache/streams/sprinklr/Sprinklr.java
index 75c3531e5d..264bf4e017 100644
--- a/streams-contrib/streams-provider-sprinklr/src/main/java/org/apache/streams/sprinklr/Sprinklr.java
+++ b/streams-contrib/streams-provider-sprinklr/src/main/java/org/apache/streams/sprinklr/Sprinklr.java
@@ -19,29 +19,20 @@
 package org.apache.streams.sprinklr;
 
 import com.google.common.util.concurrent.Uninterruptibles;
-import org.apache.http.Header;
-import org.apache.http.HttpResponse;
-import org.apache.http.message.BasicHeader;
-import org.apache.juneau.ObjectMap;
+import org.apache.juneau.collections.JsonMap;
 import org.apache.juneau.json.JsonParser;
 import org.apache.juneau.json.JsonSerializer;
-import org.apache.juneau.parser.ParseException;
-import org.apache.juneau.rest.client.RestCall;
 import org.apache.juneau.rest.client.RestClient;
-import org.apache.juneau.rest.client.RestClientBuilder;
-import org.apache.juneau.rest.client.RestCallException;
-
+import org.apache.juneau.rest.client.RestRequest;
 import org.apache.streams.config.ComponentConfigurator;
 import org.apache.streams.sprinklr.api.*;
 import org.apache.streams.sprinklr.config.SprinklrConfiguration;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.IOException;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-import java.util.ArrayList;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.TimeUnit;
 
@@ -58,7 +49,7 @@ public class Sprinklr implements Bootstrap, Profiles {
   JsonParser parser;
   JsonSerializer serializer;
 
-  RestClientBuilder restClientBuilder;
+  RestClient.Builder restClientBuilder;
   RestClient restClient;
 
   public static Map<SprinklrConfiguration, Sprinklr> INSTANCE_MAP = new ConcurrentHashMap<>();
@@ -79,10 +70,10 @@ public class Sprinklr implements Bootstrap, Profiles {
 
   private Sprinklr(SprinklrConfiguration configuration) {
     this.configuration = configuration;
-    this.parser = JsonParser.DEFAULT.builder()
-        .ignoreUnknownBeanProperties(true)
+    this.parser = JsonParser.DEFAULT.copy()
+        .ignoreUnknownBeanProperties()
         .build();
-    this.serializer = JsonSerializer.DEFAULT.builder()
+    this.serializer = JsonSerializer.DEFAULT.copy()
         .trimEmptyCollections(true)
         .trimEmptyMaps(true)
         .build();
@@ -98,11 +89,9 @@ public class Sprinklr implements Bootstrap, Profiles {
       this.restClientBuilder.debug();
     }
 
-    ArrayList<Header> defaultHeaders = new ArrayList<>();
-    defaultHeaders.add(new BasicHeader("key", configuration.getKey()));
-    defaultHeaders.add(new BasicHeader("Authorization", configuration.getAuthorization()));
+    restClientBuilder.header("key", configuration.getKey());
+    restClientBuilder.header("Authorization", configuration.getAuthorization());
 
-    restClientBuilder.setDefaultHeaders(defaultHeaders);
     this.restClient = restClientBuilder.build();
   }
 
@@ -113,11 +102,11 @@ public class Sprinklr implements Bootstrap, Profiles {
   @Override
   public PartnerAccountsResponse getPartnerAccounts() {
     try {
-      ObjectMap requestMap = new ObjectMap();
+      JsonMap requestMap = new JsonMap();
       requestMap.put("types", "PARTNER_ACCOUNTS");
-      RestCall call = restClient
-          .doGet(baseUrl() + "v1/bootstrap/resources")
-          .queryIfNE(requestMap)
+      RestRequest call = restClient
+          .get(baseUrl() + "v1/bootstrap/resources")
+          .queryDataBean(requestMap)
           .ignoreErrors();
       String responseJson = call.getResponseAsString();
       PartnerAccountsResponse response = parser.parse(responseJson, PartnerAccountsResponse.class);
@@ -134,13 +123,13 @@ public class Sprinklr implements Bootstrap, Profiles {
   public List<SocialProfileResponse> getSocialProfile(SocialProfileRequest request) {
     try {
       String requestJson = serializer.serialize(request);
-      ObjectMap requestParams = new ObjectMap(requestJson);
-      RestCall call = restClient
-          .doGet(baseUrl() + "v1/profile")
+      JsonMap requestParams = new JsonMap(requestJson);
+      RestRequest call = restClient
+          .get(baseUrl() + "v1/profile")
           .accept("application/json")
           .contentType("application/json")
           .ignoreErrors()
-          .queryIfNE(requestParams);
+          .queryDataBean(requestParams);
       String responseJson = call.getResponseAsString();
       List<SocialProfileResponse> result = parser.parse(responseJson, List.class, SocialProfileResponse.class);
       return result;
@@ -156,13 +145,13 @@ public class Sprinklr implements Bootstrap, Profiles {
   public List<ProfileConversationsResponse> getProfileConversations(ProfileConversationsRequest request) {
     try {
       String requestJson = serializer.serialize(request);
-      ObjectMap requestParams = new ObjectMap(requestJson);
-      RestCall call = restClient
-          .doGet(baseUrl() + "v1/profile/conversations")
+      JsonMap requestParams = new JsonMap(requestJson);
+      RestRequest call = restClient
+          .get(baseUrl() + "v1/profile/conversations")
           .accept("application/json")
           .contentType("application/json")
           .ignoreErrors()
-          .queryIfNE(requestParams);
+          .queryDataBean(requestParams);
       String responseJson = call.getResponseAsString();
       List<ProfileConversationsResponse> result = parser.parse(responseJson, List.class, ProfileConversationsResponse.class);
       return result;
@@ -199,4 +188,4 @@ public class Sprinklr implements Bootstrap, Profiles {
 
     return retList;
   }
-}
\ No newline at end of file
+}
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Account.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Account.java
index 9f7342e3f1..112a3e60e5 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Account.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Account.java
@@ -18,16 +18,16 @@
 
 package org.apache.streams.twitter.api;
 
+import org.apache.juneau.http.annotation.Content;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemoteGet;
+import org.apache.juneau.http.remote.RemotePost;
 import org.apache.streams.twitter.pojo.User;
 
-import org.apache.juneau.http.annotation.Body;
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
-
 /**
  * Interface for /account methods.
  */
-@RemoteInterface(path = "https://api.twitter.com/1.1/account")
+@Remote(path = "https://api.twitter.com/1.1/account")
 public interface Account {
 
   /**
@@ -37,7 +37,7 @@ public interface Account {
    * @see <a href=https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/get-account-settings">https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/get-account-settings</a>
    *
    */
-  @RemoteMethod(method = "GET", path = "/settings.json")
+  @RemoteGet(path = "/settings.json")
   public AccountSettings settings();
 
   /**
@@ -47,7 +47,7 @@ public interface Account {
    * @see <a href=https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/get-account-verify_credentials">https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/get-account-verify_credentials</a>
    *
    */
-  @RemoteMethod(method = "GET", path = "/verify_credentials.json")
+  @RemoteGet(path = "/verify_credentials.json")
   public User verifyCredentials();
 
   /**
@@ -57,8 +57,8 @@ public interface Account {
    * @see <a href=https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/post-account-update_profile">https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/post-account-update_profile</a>
    *
    */
-  @RemoteMethod(method = "POST", path = "/update_profile.json")
-  public User updateProfile(@Body UpdateProfileRequest parameters);
+  @RemotePost(path = "/update_profile.json")
+  public User updateProfile(@Content UpdateProfileRequest parameters);
 
   /**
    * Updates the authenticating user’s settings.
@@ -67,7 +67,7 @@ public interface Account {
    * @see <a href=https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/post-account-settings">https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/post-account-settings</a>
    *
    */
-  @RemoteMethod(method = "POST", path = "/update_settings.json")
-  public AccountSettings updateSettings(@Body UpdateProfileRequest parameters);
+  @RemotePost(path = "/update_settings.json")
+  public AccountSettings updateSettings(@Content UpdateProfileRequest parameters);
 
 }
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/AccountActivity.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/AccountActivity.java
index 25c758f4de..16f409e695 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/AccountActivity.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/AccountActivity.java
@@ -20,9 +20,8 @@ package org.apache.streams.twitter.api;
 
 import org.apache.juneau.http.annotation.Path;
 import org.apache.juneau.http.annotation.Query;
-import org.apache.juneau.remote.RemoteInterface;
+import org.apache.juneau.http.remote.*;
 import org.apache.juneau.rest.client.RestCallException;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
 
 import java.lang.reflect.InvocationTargetException;
 import java.util.List;
@@ -32,7 +31,7 @@ import java.util.List;
  *
  * @see <a href="https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/overview">https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/overview</a>
  */
-@RemoteInterface(path = "https://api.twitter.com/1.1/account_activity")
+@Remote(path = "https://api.twitter.com/1.1/account_activity")
 public interface AccountActivity {
 
   /**
@@ -44,7 +43,7 @@ public interface AccountActivity {
    * @see <a href=https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/get-webhook-config">https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/get-webhook-config</a>
    *
    */
-  @RemoteMethod(method = "GET", path = "/all/webhooks.json")
+  @RemoteGet(path = "/all/webhooks.json")
   public WebhooksResponse getWebhooks();
 
   /**
@@ -55,7 +54,7 @@ public interface AccountActivity {
    * @see <a href=https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/get-webhook-config">https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/get-webhook-config</a>
    *
    */
-  @RemoteMethod(method = "GET", path = "/all/{env_name}/webhooks.json")
+  @RemoteGet(path = "/all/{env_name}/webhooks.json")
   public List<Webhook> getWebhooks(@Path("env_name") String env_name);
 
   /**
@@ -69,7 +68,7 @@ public interface AccountActivity {
    * @see <a href=https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/new-webhook-config">https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/new-webhook-config</a>
    *
    */
-  @RemoteMethod(method = "POST", path = "/all/{env_name}/webhooks.json")
+  @RemotePost(path = "/all/{env_name}/webhooks.json")
   public Webhook registerWebhook(@Path("env_name") String env_name, @Query("url") String url);
 
   /**
@@ -81,7 +80,7 @@ public interface AccountActivity {
    * @see <a href=https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/delete-webhook-config">https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/delete-webhook-config</a>
    *
    */
-  @RemoteMethod(method = "DELETE", path = "/all/{env_name}/webhooks/{webhookId}.json")
+  @RemoteDelete(path = "/all/{env_name}/webhooks/{webhookId}.json")
   public Boolean deleteWebhook(@Path("env_name") String env_name, @Path("webhookId") Long webhookId);
 
   /**
@@ -93,7 +92,7 @@ public interface AccountActivity {
    * @see <a href=https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/aaa-premium</a>
    *
    */
-  @RemoteMethod(method = "PUT", path = "/all/{env_name}/webhooks/{webhookId}.json")
+  @RemotePut(path = "/all/{env_name}/webhooks/{webhookId}.json")
   public Boolean putWebhook(@Path("env_name") String env_name, @Path("webhookId") Long webhookId);
 
   /**
@@ -104,7 +103,7 @@ public interface AccountActivity {
    * @return Boolean
    * @see <a href=https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/validate-webhook-config">https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/validate-webhook-config</a>
    */
-  @RemoteMethod(method = "PUT", path = "/all/{env_name}/webhooks/{webhookId}.json")
+  @RemotePut(path = "/all/{env_name}/webhooks/{webhookId}.json")
   public Boolean reenableWebhook(@Path("env_name") String env_name, @Path("webhookId") Long webhookId) throws InvocationTargetException, RestCallException;
 
   /**
@@ -114,7 +113,7 @@ public interface AccountActivity {
    * @see <a href=https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/get-subscription">https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/get-subscription</a>
    *
    */
-  @RemoteMethod(method = "GET", path = "/all/subscriptions/count.json")
+  @RemoteGet(path = "/all/subscriptions/count.json")
   public SubscriptionsCountResponse getSubscriptionsCount() throws InvocationTargetException, RestCallException;
 
   /**
@@ -125,7 +124,7 @@ public interface AccountActivity {
    * @see <a href=https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/get-subscription">https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/get-subscription</a>
    *
    */
-  @RemoteMethod(method = "GET", path = "/all/{env_name}/subscriptions/list.json")
+  @RemoteGet(path = "/all/{env_name}/subscriptions/list.json")
   public SubscriptionsListResponse getSubscriptionsList(@Path("env_name") String env_name) throws InvocationTargetException, RestCallException;
 
   /**
@@ -136,7 +135,7 @@ public interface AccountActivity {
    * @see <a href=https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/get-subscription">https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/get-subscription</a>
    *
    */
-  @RemoteMethod(method = "GET", path = "/all/{env_name}/subscriptions.json")
+  @RemoteGet(path = "/all/{env_name}/subscriptions.json")
   public Boolean getSubscriptions(@Path("env_name") String env_name) throws InvocationTargetException, RestCallException;
 
   /**
@@ -147,7 +146,7 @@ public interface AccountActivity {
    * @see <a href=https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/new-subscription">https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/new-subscription</a>
    *
    */
-  @RemoteMethod(method = "POST", path = "/all/{env_name}/subscriptions.json")
+  @RemotePost(path = "/all/{env_name}/subscriptions.json")
   public Boolean newSubscription(@Path("env_name") String env_name) throws InvocationTargetException, RestCallException;
 
   /**
@@ -159,7 +158,7 @@ public interface AccountActivity {
    * @see <a href=https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/delete-subscription">https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/delete-subscription</a>
    *
    */
-  @RemoteMethod(method = "DELETE", path = "/all/{env_name}/subscriptions/{user_id}.json")
+  @RemoteDelete(path = "/all/{env_name}/subscriptions/{user_id}.json")
   public Boolean deleteWebhookSubscriptions(@Path("env_name") String env_name, @Path("user_id") String user_id) throws InvocationTargetException, RestCallException;
 
 }
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/DirectMessages.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/DirectMessages.java
index 4e86093717..21d68655c9 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/DirectMessages.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/DirectMessages.java
@@ -18,14 +18,14 @@
 
 package org.apache.streams.twitter.api;
 
+import org.apache.juneau.http.annotation.Content;
+import org.apache.juneau.http.annotation.Query;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemoteGet;
+import org.apache.juneau.http.remote.RemotePost;
 import org.apache.streams.twitter.pojo.DirectMessage;
 import org.apache.streams.twitter.pojo.DirectMessageEvent;
 
-import org.apache.juneau.http.annotation.Body;
-import org.apache.juneau.http.annotation.Query;
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
-
 import java.util.List;
 
 /**
@@ -33,7 +33,7 @@ import java.util.List;
  *
  * @see <a href="https://dev.twitter.com/rest/reference">https://dev.twitter.com/rest/reference</a>
  */
-@RemoteInterface(path = "https://api.twitter.com/1.1/direct_messages")
+@Remote(path = "https://api.twitter.com/1.1/direct_messages")
 public interface DirectMessages {
 
   /**
@@ -44,8 +44,8 @@ public interface DirectMessages {
    * @see <a href="https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/list-events">https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/list-events</a>
    *
    */
-  @RemoteMethod(method = "GET", path = "/events/list.json")
-  public EventsListResponse listEvents(@Query(name = "*", skipIfEmpty = true) EventsListRequest parameters);
+  @RemoteGet(path = "/events/list.json")
+  public EventsListResponse listEvents(@Query(name = "*") EventsListRequest parameters);
 
   /**
    * Returns a single Direct Message event by the given id.
@@ -54,7 +54,7 @@ public interface DirectMessages {
    * @see <a href="https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/get-event">https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/get-event</a>
    *
    */
-  @RemoteMethod(method = "GET", path = "/events/show.json")
+  @RemoteGet(path = "/events/show.json")
   public EventShowResponse showEvent(@Query("id") Long id);
 
   /**
@@ -65,8 +65,8 @@ public interface DirectMessages {
    * @see <a href="https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/new-event">https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/new-event</a>
    *
    */
-  @RemoteMethod(method = "POST", path = "/events/new.json")
-  public DirectMessageEvent newEvent(@Body MessageCreateRequest event);
+  @RemotePost(path = "/events/new.json")
+  public DirectMessageEvent newEvent(@Content MessageCreateRequest event);
 
   /**
    * Publishes a new message_create event resulting in a Direct Message sent to a specified user from the authenticating user. Returns an event in the requested format if successful.
@@ -76,7 +76,7 @@ public interface DirectMessages {
    * @see <a href="https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/new-event">https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/new-event</a>
    *
    */
-  @RemoteMethod(method = "POST", path = "/destroy.json")
+  @RemotePost(path = "/destroy.json")
   public DirectMessage destroy(@Query("id") Long id);
 
   /**
@@ -87,7 +87,7 @@ public interface DirectMessages {
    * @see <a href="https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/new-event">https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/new-event</a>
    *
    */
-  @RemoteMethod(method = "GET", path = "/show.json")
+  @RemoteGet(path = "/show.json")
   public DirectMessage show(@Query("id") Long id);
 
   /**
@@ -98,8 +98,8 @@ public interface DirectMessages {
    * @see <a href="https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/get-messages">https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/get-messages</a>
    *
    */
-  @RemoteMethod(method = "GET", path = ".json")
-  public List<DirectMessage> list(@Query(name = "*", skipIfEmpty = true) DirectMessagesListRequest parameters);
+  @RemoteGet(path = ".json")
+  public List<DirectMessage> list(@Query(name = "*") DirectMessagesListRequest parameters);
 
   /**
    * Returns the 20 most recent direct messages sent to the authenticating user. Includes detailed information about the sender and recipient user. You can request up to 200 direct messages per call, and only the most recent 200 DMs will be available using this endpoint.
@@ -109,8 +109,8 @@ public interface DirectMessages {
    * @see <a href="https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/get-sent-message">https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/get-sent-message</a>
    *
    */
-  @RemoteMethod(method = "GET", path = "/sent.json")
-  public List<DirectMessage> sent(@Query(name = "*", skipIfEmpty = true) DirectMessagesSentRequest parameters);
+  @RemoteGet(path = "/sent.json")
+  public List<DirectMessage> sent(@Query(name = "*") DirectMessagesSentRequest parameters);
 
   /**
    * Destroys the direct message specified in the required ID parameter. The authenticating user must be the recipient of the specified direct message.
@@ -120,6 +120,6 @@ public interface DirectMessages {
    * @see <a href="https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/new-event">https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/new-event</a>
    *
    */
-  @RemoteMethod(method = "POST", path = "/new.json")
-  public DirectMessage newDM(@Body DirectMessageNewRequest parameters);
+  @RemotePost(path = "/new.json")
+  public DirectMessage newDM(@Content DirectMessageNewRequest parameters);
 }
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Favorites.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Favorites.java
index 4b551c0c45..ef9eca673d 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Favorites.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Favorites.java
@@ -18,11 +18,10 @@
 
 package org.apache.streams.twitter.api;
 
-import org.apache.streams.twitter.pojo.Tweet;
-
 import org.apache.juneau.http.annotation.Query;
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemoteGet;
+import org.apache.streams.twitter.pojo.Tweet;
 
 import java.util.List;
 
@@ -31,7 +30,7 @@ import java.util.List;
  *
  * @see <a href="https://dev.twitter.com/rest/reference">https://dev.twitter.com/rest/reference</a>
  */
-@RemoteInterface(path = "https://api.twitter.com/1.1/favorites")
+@Remote(path = "https://api.twitter.com/1.1/favorites")
 public interface Favorites {
 
   /**
@@ -43,7 +42,7 @@ public interface Favorites {
    * @see <a href="https://dev.twitter.com/rest/reference/get/favorites/list">https://dev.twitter.com/rest/reference/get/favorites/list</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/list.json")
-  public List<Tweet> list( @Query(name = "*", skipIfEmpty = true) FavoritesListRequest parameters);
+  @RemoteGet(path = "/list.json")
+  public List<Tweet> list( @Query(name = "*") FavoritesListRequest parameters);
 
 }
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Followers.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Followers.java
index 03395f8f73..5ccb55144a 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Followers.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Followers.java
@@ -19,15 +19,15 @@
 package org.apache.streams.twitter.api;
 
 import org.apache.juneau.http.annotation.Query;
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemoteGet;
 
 /**
  * Interface for /followers methods.
  *
  * @see <a href="https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference">https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference</a>
  */
-@RemoteInterface(path = "https://api.twitter.com/1.1/followers")
+@Remote(path = "https://api.twitter.com/1.1/followers")
 public interface Followers {
 
   /**
@@ -38,8 +38,8 @@ public interface Followers {
    * @see <a href="https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-followers-ids">https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-followers-ids</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/ids.json")
-  public FollowersIdsResponse ids( @Query(name = "*", skipIfEmpty = true) FollowersIdsRequest parameters);
+  @RemoteGet(path = "/ids.json")
+  public FollowersIdsResponse ids( @Query(name = "*") FollowersIdsRequest parameters);
 
   /**
    * Returns a cursored collection of user objects for users following the specified user.
@@ -49,7 +49,7 @@ public interface Followers {
    * @see <a href="https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-followers-list">https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-followers-list</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/list.json")
-  public FollowersListResponse list( @Query(name = "*", skipIfEmpty = true) FollowersListRequest parameters);
+  @RemoteGet(path = "/list.json")
+  public FollowersListResponse list( @Query(name = "*") FollowersListRequest parameters);
 
 }
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Friends.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Friends.java
index 2430deb336..0da60e61a6 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Friends.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Friends.java
@@ -19,15 +19,15 @@
 package org.apache.streams.twitter.api;
 
 import org.apache.juneau.http.annotation.Query;
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemoteGet;
 
 /**
  * Interface for /friends methods.
  *
  * @see <a href="https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference">https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference</a>
  */
-@RemoteInterface(path = "https://api.twitter.com/1.1/friends")
+@Remote(path = "https://api.twitter.com/1.1/friends")
 public interface Friends {
 
   /**
@@ -38,8 +38,8 @@ public interface Friends {
    * @see <a href="https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friends-ids">https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friends-ids</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/ids.json")
-  public FriendsIdsResponse ids( @Query(name = "*", skipIfEmpty = true) FriendsIdsRequest parameters);
+  @RemoteGet(path = "/ids.json")
+  public FriendsIdsResponse ids( @Query(name = "*") FriendsIdsRequest parameters);
 
   /**
    * Returns a cursored collection of user objects for every user the specified user is following.
@@ -49,7 +49,7 @@ public interface Friends {
    * @see <a href="https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friends-list">https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friends-list</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/list.json")
-  public FriendsListResponse list( @Query(name = "*", skipIfEmpty = true) FriendsListRequest parameters);
+  @RemoteGet(path = "/list.json")
+  public FriendsListResponse list( @Query(name = "*") FriendsListRequest parameters);
 
 }
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Friendships.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Friendships.java
index a4a6f41860..4d85542ae0 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Friendships.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Friendships.java
@@ -18,13 +18,13 @@
 
 package org.apache.streams.twitter.api;
 
+import org.apache.juneau.http.annotation.Query;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemoteGet;
+import org.apache.juneau.http.remote.RemotePost;
 import org.apache.streams.twitter.pojo.Friendship;
 import org.apache.streams.twitter.pojo.User;
 
-import org.apache.juneau.http.annotation.Query;
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
-
 import java.util.List;
 
 /**
@@ -32,7 +32,7 @@ import java.util.List;
  *
  * @see <a href="https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/overview">https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/overview</a>
  */
-@RemoteInterface(path = "https://api.twitter.com/1.1/friendships")
+@Remote(path = "https://api.twitter.com/1.1/friendships")
 public interface Friendships {
 
   /**
@@ -43,8 +43,8 @@ public interface Friendships {
    * @see <a href="https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/post-friendships-create">https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/post-friendships-create</a>
    *
    */
-  @RemoteMethod(method ="POST", path = "/create.json")
-  public User create(@Query(name = "*", skipIfEmpty = true) FriendshipCreateRequest parameters);
+  @RemotePost(path = "/create.json")
+  public User create(@Query(name = "*") FriendshipCreateRequest parameters);
 
   /**
    * Allows the authenticating user to unfollow the user specified in the ID parameter.
@@ -54,8 +54,8 @@ public interface Friendships {
    * @see <a href="https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/post-friendships-destroy">https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/post-friendships-destroy</a>
    *
    */
-  @RemoteMethod(method ="POST", path = "/destroy.json")
-  public User destroy(@Query(name = "*", skipIfEmpty = true) FriendshipDestroyRequest parameters);
+  @RemotePost(path = "/destroy.json")
+  public User destroy(@Query(name = "*") FriendshipDestroyRequest parameters);
 
   /**
    * Returns a collection of numeric IDs for every user who has a pending request to follow the authenticating user.
@@ -65,8 +65,8 @@ public interface Friendships {
    * @see <a href="https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friendships-incoming">https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friendships-incoming</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/incoming.json")
-  public User incoming(@Query(name = "*", skipIfEmpty = true) FriendshipsIncomingRequest parameters);
+  @RemoteGet(path = "/incoming.json")
+  public User incoming(@Query(name = "*") FriendshipsIncomingRequest parameters);
 
   /**
    * Returns the relationships of the authenticating user to the comma-separated list of up to 100 screen_names or user_ids provided.
@@ -77,8 +77,8 @@ public interface Friendships {
    * @see <a href="https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friendships-lookup">https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friendships-lookup</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/lookup.json")
-  public List<Friendship> lookup(@Query(name = "*", skipIfEmpty = true) FriendshipsLookupRequest parameters);
+  @RemoteGet(path = "/lookup.json")
+  public List<Friendship> lookup(@Query(name = "*") FriendshipsLookupRequest parameters);
 
 
   /**
@@ -89,8 +89,8 @@ public interface Friendships {
    * @see <a href="https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friendships-incoming">https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friendships-incoming</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/outgoing.json")
-  public User outgoing(@Query(name = "*", skipIfEmpty = true) FriendshipsOutgoingRequest parameters);
+  @RemoteGet(path = "/outgoing.json")
+  public User outgoing(@Query(name = "*") FriendshipsOutgoingRequest parameters);
 
   /**
    * Returns detailed information about the relationship between two arbitrary users.
@@ -100,8 +100,8 @@ public interface Friendships {
    * @see <a href="https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friendships-show">https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friendships-show</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/show.json")
-  public FriendshipShowResponse show(@Query(name = "*", skipIfEmpty = true) FriendshipShowRequest parameters);
+  @RemoteGet(path = "/show.json")
+  public FriendshipShowResponse show(@Query(name = "*") FriendshipShowRequest parameters);
 
   /**
    * Allows one to enable or disable retweets and device notifications from the specified user.
@@ -111,7 +111,7 @@ public interface Friendships {
    * @see <a href="https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/post-friendships-update">https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/post-friendships-update</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/update.json")
-  public User update(@Query(name = "*", skipIfEmpty = true) FriendshipUpdateRequest parameters);
+  @RemoteGet(path = "/update.json")
+  public User update(@Query(name = "*") FriendshipUpdateRequest parameters);
 
 }
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Geo.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Geo.java
index 3bdaf411f1..bed9051e6e 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Geo.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Geo.java
@@ -18,11 +18,10 @@
 
 package org.apache.streams.twitter.api;
 
-import org.apache.streams.twitter.pojo.Place;
-
 import org.apache.juneau.http.annotation.Query;
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemoteGet;
+import org.apache.streams.twitter.pojo.Place;
 
 /**
  * Interface for /geo methods.
@@ -30,7 +29,7 @@ import org.apache.juneau.rest.client.remote.RemoteMethod;
  * @see <a href="https://developer.twitter.com/en/docs/geo/place-information/overview">https://developer.twitter.com/en/docs/geo/place-information/overview</a>
  * @see <a href="https://developer.twitter.com/en/docs/geo/places-near-location/overview">https://developer.twitter.com/en/docs/geo/places-near-location/overview</a>
  */
-@RemoteInterface(path = "https://api.twitter.com/1.1/geo")
+@Remote(path = "https://api.twitter.com/1.1/geo")
 public interface Geo {
 
   /**
@@ -41,7 +40,7 @@ public interface Geo {
    * @see <a href="https://developer.twitter.com/en/docs/geo/place-information/api-reference/get-geo-id-place_id">https://developer.twitter.com/en/docs/geo/place-information/api-reference/get-geo-id-place_id</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/id/{place_id}.json")
+  @RemoteGet(path = "/id/{place_id}.json")
   public Place geoid(@Query("place_id") String place_id);
 
   /**
@@ -52,8 +51,8 @@ public interface Geo {
    * @see <a href="https://developer.twitter.com/en/docs/geo/places-near-location/api-reference/get-geo-search">https://developer.twitter.com/en/docs/geo/places-near-location/api-reference/get-geo-search</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/search.json")
-  public GeoSearchResponse geosearch(@Query(name = "*", skipIfEmpty = true) GeoSearchRequest parameters);
+  @RemoteGet(path = "/search.json")
+  public GeoSearchResponse geosearch(@Query(name = "*") GeoSearchRequest parameters);
 
   /**
    * Given a latitude and a longitude, searches for up to 20 places that can be used as a place_id when updating a status.
@@ -63,7 +62,7 @@ public interface Geo {
    * @see <a href="https://developer.twitter.com/en/docs/geo/places-near-location/api-reference/get-geo-reverse_geocode">https://developer.twitter.com/en/docs/geo/places-near-location/api-reference/get-geo-reverse_geocode</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/reverse_geocode.json")
-  public GeoSearchResponse reverseGeocode(@Query(name = "*", skipIfEmpty = true) GeoSearchRequest parameters);
+  @RemoteGet(path = "/reverse_geocode.json")
+  public GeoSearchResponse reverseGeocode(@Query(name = "*") GeoSearchRequest parameters);
 
 }
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Media.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Media.java
index f47977125e..e871aba5fa 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Media.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Media.java
@@ -19,15 +19,15 @@
 package org.apache.streams.twitter.api;
 
 import org.apache.juneau.http.annotation.Query;
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemoteGet;
 
 /**
  * Interface for /media methods.
  *
  * @see <a href="https://dev.twitter.com/rest/reference">https://dev.twitter.com/rest/reference</a>
  */
-@RemoteInterface(path = "https://upload.twitter.com/1.1/media")
+@Remote(path = "https://upload.twitter.com/1.1/media")
 public interface Media {
 
   /**
@@ -38,7 +38,7 @@ public interface Media {
    * @see <a href="https://developer.twitter.com/en/docs/media/upload-media/api-reference/get-media-upload-status">https://developer.twitter.com/en/docs/media/upload-media/api-reference/get-media-upload-status</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/upload")
-  public MediaStatusResponse getMediaStatus(@Query(name = "*", skipIfEmpty = true) MediaStatusRequest parameters );
+  @RemoteGet(path = "/upload")
+  public MediaStatusResponse getMediaStatus(@Query(name = "*") MediaStatusRequest parameters );
 
 }
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/SevenDaySearch.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/SevenDaySearch.java
index 65d228dffc..495cf4d1f8 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/SevenDaySearch.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/SevenDaySearch.java
@@ -19,13 +19,13 @@
 package org.apache.streams.twitter.api;
 
 import org.apache.juneau.http.annotation.Query;
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemoteGet;
 
 /**
  * Interface for /search methods.
  */
-@RemoteInterface(path = "https://api.twitter.com/1.1/search")
+@Remote(path = "https://api.twitter.com/1.1/search")
 public interface SevenDaySearch {
 
   /**
@@ -35,8 +35,8 @@ public interface SevenDaySearch {
    * @see <a href=https://developer.twitter.com/en/docs/tweets/search/api-reference/get-search-tweets">https://developer.twitter.com/en/docs/tweets/search/api-reference/get-search-tweets</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/tweets.json")
-  public SevenDaySearchResponse sevenDaySearch(@Query(name = "*", skipIfEmpty = true) SevenDaySearchRequest parameters);
+  @RemoteGet(path = "/tweets.json")
+  public SevenDaySearchResponse sevenDaySearch(@Query(name = "*") SevenDaySearchRequest parameters);
 
 }
 
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Statuses.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Statuses.java
index fa77ef4cb2..a9b986bbfc 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Statuses.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Statuses.java
@@ -18,13 +18,12 @@
 
 package org.apache.streams.twitter.api;
 
-import org.apache.streams.twitter.pojo.Tweet;
-
 import org.apache.juneau.http.annotation.Path;
 import org.apache.juneau.http.annotation.Query;
 import org.apache.juneau.http.annotation.Request;
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemoteGet;
+import org.apache.streams.twitter.pojo.Tweet;
 
 import java.util.List;
 
@@ -34,7 +33,7 @@ import java.util.List;
  * @see <a href="https://developer.twitter.com/en/docs/tweets/post-and-engage/overview">https://developer.twitter.com/en/docs/tweets/post-and-engage/overview</a>
  * @see <a href="https://developer.twitter.com/en/docs/tweets/timelines/overview">https://developer.twitter.com/en/docs/tweets/timelines/overview</a>
  */
-@RemoteInterface(path = "https://api.twitter.com/1.1/statuses")
+@Remote(path = "https://api.twitter.com/1.1/statuses")
 public interface Statuses {
 
   /**
@@ -45,8 +44,8 @@ public interface Statuses {
    * @see <a href="https://developer.twitter.com/en/docs/tweets/timelines/api-reference/get-statuses-home_timeline">https://developer.twitter.com/en/docs/tweets/timelines/api-reference/get-statuses-home_timeline</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/home_timeline.json")
-  public List<Tweet> homeTimeline( @Query(name = "*", skipIfEmpty = true) StatusesHomeTimelineRequest parameters );
+  @RemoteGet(path = "/home_timeline.json")
+  public List<Tweet> homeTimeline( @Query(name = "*") StatusesHomeTimelineRequest parameters );
 
   /**
    * Returns fully-hydrated Tweet objects for up to 100 Tweets per request, as specified by comma-separated values passed to the id parameter.
@@ -56,8 +55,8 @@ public interface Statuses {
    * @see <a href="https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-lookup">https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-lookup</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/lookup.json")
-  public List<Tweet> lookup( @Query(name = "*", skipIfEmpty = true) StatusesLookupRequest parameters);
+  @RemoteGet(path = "/lookup.json")
+  public List<Tweet> lookup( @Query(name = "*") StatusesLookupRequest parameters);
 
   /**
    * Returns the 20 most recent mentions (Tweets containing a users’s @screen_name) for the authenticating user.
@@ -71,8 +70,8 @@ public interface Statuses {
    * @see <a href="https://developer.twitter.com/en/docs/tweets/timelines/api-reference/get-statuses-mentions_timeline">https://developer.twitter.com/en/docs/tweets/timelines/api-reference/get-statuses-mentions_timeline</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/mentions_timeline.json")
-  public List<Tweet> mentionsTimeline( @Query(name = "*", skipIfEmpty = true) StatusesMentionsTimelineRequest parameters);
+  @RemoteGet(path = "/mentions_timeline.json")
+  public List<Tweet> mentionsTimeline( @Query(name = "*") StatusesMentionsTimelineRequest parameters);
 
   /**
    * Returns a single Tweet, specified by the id parameter. The Tweet’s author will also be embedded within the Tweet.
@@ -82,7 +81,7 @@ public interface Statuses {
    * @see <a href="https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-show-id">https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-show-id</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/show/{id}")
+  @RemoteGet(path = "/show/{id}")
   public Tweet show( @Request StatusesShowRequest parameters);
 
   /**
@@ -93,8 +92,8 @@ public interface Statuses {
    * @see <a href="https://developer.twitter.com/en/docs/tweets/timelines/api-reference/get-statuses-user_timeline">https://developer.twitter.com/en/docs/tweets/timelines/api-reference/get-statuses-user_timeline</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/user_timeline.json")
-  public List<Tweet> userTimeline( @Query(name = "*", skipIfEmpty = true) StatusesUserTimelineRequest parameters);
+  @RemoteGet(path = "/user_timeline.json")
+  public List<Tweet> userTimeline( @Query(name = "*") StatusesUserTimelineRequest parameters);
 
   /**
    * Returns a collection of the 100 most recent retweets of the Tweet specified by the id parameter.
@@ -104,7 +103,7 @@ public interface Statuses {
    * @see <a href="https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-retweets-id">https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-retweets-id</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/retweets/{id}")
+  @RemoteGet(path = "/retweets/{id}")
   public List<Tweet> retweets( @Request RetweetsRequest parameters);
 
   /**
@@ -115,8 +114,8 @@ public interface Statuses {
    * @see <a href="https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-retweeters-ids">https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-retweeters-ids</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/retweeters/ids.json")
-  public RetweeterIdsResponse retweeterIds( @Query(name = "*", skipIfEmpty = true) RetweeterIdsRequest parameters);
+  @RemoteGet(path = "/retweeters/ids.json")
+  public RetweeterIdsResponse retweeterIds( @Query(name = "*") RetweeterIdsRequest parameters);
 
   interface StatusesShowRequestAnnotations {
 
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/SuggestedUsers.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/SuggestedUsers.java
index d4843f09a2..a430402d74 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/SuggestedUsers.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/SuggestedUsers.java
@@ -18,12 +18,11 @@
 
 package org.apache.streams.twitter.api;
 
-import org.apache.streams.twitter.pojo.User;
-
 import org.apache.juneau.http.annotation.Path;
 import org.apache.juneau.http.annotation.Query;
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemoteGet;
+import org.apache.streams.twitter.pojo.User;
 
 import java.util.List;
 
@@ -32,7 +31,7 @@ import java.util.List;
  *
  * @see <a href="https://dev.twitter.com/rest/reference">https://dev.twitter.com/rest/reference</a>
  */
-@RemoteInterface(path = "https://api.twitter.com/1.1/users")
+@Remote(path = "https://api.twitter.com/1.1/users")
 public interface SuggestedUsers {
 
   /**
@@ -43,8 +42,8 @@ public interface SuggestedUsers {
    * @see <a href="https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-suggestions">https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-suggestions</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/suggestions.json")
-  public List<SuggestedUserCategory> categories(@Query(name = "lang", skipIfEmpty = true) String lang);
+  @RemoteGet(path = "/suggestions.json")
+  public List<SuggestedUserCategory> categories(@Query(name = "lang") String lang);
 
   /**
    * Access the users in a given category of the Twitter suggested user list.
@@ -55,8 +54,8 @@ public interface SuggestedUsers {
    * @see <a href="https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-suggestions-slug">https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-suggestions-slug</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/suggestions/{slug}.json")
-  public SuggestedUserCategory suggestions(@Path("slug") String slug, @Query(name = "lang", skipIfEmpty = true) String lang);
+  @RemoteGet(path = "/suggestions/{slug}.json")
+  public SuggestedUserCategory suggestions(@Path("slug") String slug, @Query(name = "lang") String lang);
 
   /**
    * Access the users in a given category of the Twitter suggested user list and return their most recent status if they are not a protected user.
@@ -65,7 +64,7 @@ public interface SuggestedUsers {
    * @see <a href="https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-suggestions-slug">https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-suggestions-slug</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/suggestions/{slug}/members.json")
+  @RemoteGet(path = "/suggestions/{slug}/members.json")
   public List<User> members(@Path("slug") String slug);
 
 }
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/ThirtyDaySearch.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/ThirtyDaySearch.java
index 3814212553..a9f019a3a4 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/ThirtyDaySearch.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/ThirtyDaySearch.java
@@ -18,15 +18,15 @@
 
 package org.apache.streams.twitter.api;
 
-import org.apache.juneau.http.annotation.Body;
+import org.apache.juneau.http.annotation.Content;
 import org.apache.juneau.http.annotation.Path;
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemotePost;
 
 /**
  * Interface for /search methods.
  */
-@RemoteInterface(path = "https://api.twitter.com/1.1/"+ThirtyDaySearch.path)
+@Remote(path = "https://api.twitter.com/1.1/"+ThirtyDaySearch.path)
 public interface ThirtyDaySearch {
 
   String path = "tweets/search/30day";
@@ -40,7 +40,7 @@ public interface ThirtyDaySearch {
    * @see <a href=https://developer.twitter.com/en/docs/tweets/search/overview/premium">https://developer.twitter.com/en/docs/tweets/search/overview/premium</a>
    *
    */
-  @RemoteMethod(method ="POST", path = "/{environment}.json")
-  public ThirtyDaySearchResponse thirtyDaySearch(@Path("environment") String environment, @Body ThirtyDaySearchRequest searchRequest);
+  @RemotePost(path = "/{environment}.json")
+  public ThirtyDaySearchResponse thirtyDaySearch(@Path("environment") String environment, @Content ThirtyDaySearchRequest searchRequest);
 
 }
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/ThirtyDaySearchCounts.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/ThirtyDaySearchCounts.java
index 20064a7a03..e9c985912d 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/ThirtyDaySearchCounts.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/ThirtyDaySearchCounts.java
@@ -18,15 +18,15 @@
 
 package org.apache.streams.twitter.api;
 
-import org.apache.juneau.http.annotation.Body;
+import org.apache.juneau.http.annotation.Content;
 import org.apache.juneau.http.annotation.Path;
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemotePost;
 
 /**
  * Interface for /search methods.
  */
-@RemoteInterface(path = "https://api.twitter.com/1.1/"+ ThirtyDaySearch.path)
+@Remote(path = "https://api.twitter.com/1.1/"+ ThirtyDaySearch.path)
 public interface ThirtyDaySearchCounts {
 
   /**
@@ -38,7 +38,7 @@ public interface ThirtyDaySearchCounts {
    * @see <a href=https://developer.twitter.com/en/docs/tweets/search/api-reference/30-day-search">https://developer.twitter.com/en/docs/tweets/search/api-reference/30-day-search</a>
    *
    */
-  @RemoteMethod(method ="POST", path = "/{environment}/counts.json")
-  public ThirtyDaySearchCountsResponse thirtyDaySearchCounts(@Path("environment") String environment, @Body ThirtyDaySearchCountsRequest searchCountsRequest);
+  @RemotePost(path = "/{environment}/counts.json")
+  public ThirtyDaySearchCountsResponse thirtyDaySearchCounts(@Path("environment") String environment, @Content ThirtyDaySearchCountsRequest searchCountsRequest);
 
 }
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Twitter.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Twitter.java
index 96b8640603..79404884f2 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Twitter.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Twitter.java
@@ -18,22 +18,7 @@
 
 package org.apache.streams.twitter.api;
 
-import org.apache.streams.config.ComponentConfigurator;
-import org.apache.streams.jackson.StreamsJacksonMapper;
-import org.apache.streams.twitter.config.TwitterConfiguration;
-import org.apache.streams.twitter.converter.TwitterDateSwap;
-import org.apache.streams.twitter.converter.TwitterDateTimeFormat;
-import org.apache.streams.twitter.converter.TwitterJodaDateSwap;
-import org.apache.streams.twitter.pojo.DirectMessage;
-import org.apache.streams.twitter.pojo.DirectMessageEvent;
-import org.apache.streams.twitter.pojo.Tweet;
-import org.apache.streams.twitter.pojo.User;
-import org.apache.streams.twitter.pojo.WelcomeMessage;
-import org.apache.streams.twitter.pojo.WelcomeMessageRule;
-import org.apache.streams.twitter.provider.TwitterProviderUtil;
-
 import com.fasterxml.jackson.databind.ObjectMapper;
-
 import org.apache.commons.lang3.NotImplementedException;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.http.HttpRequestInterceptor;
@@ -44,21 +29,26 @@ import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClientBuilder;
 import org.apache.juneau.json.JsonParser;
 import org.apache.juneau.json.JsonSerializer;
-import org.apache.juneau.rest.client.RestCall;
+import org.apache.juneau.rest.client.BasicHttpRequestRetryHandler;
 import org.apache.juneau.rest.client.RestCallException;
 import org.apache.juneau.rest.client.RestClient;
-import org.apache.juneau.rest.client.RestClientBuilder;
+import org.apache.juneau.rest.client.RestRequest;
+import org.apache.streams.config.ComponentConfigurator;
+import org.apache.streams.jackson.StreamsJacksonMapper;
+import org.apache.streams.twitter.config.TwitterConfiguration;
+import org.apache.streams.twitter.converter.TwitterDateSwap;
+import org.apache.streams.twitter.converter.TwitterDateTimeFormat;
+import org.apache.streams.twitter.pojo.*;
+import org.apache.streams.twitter.provider.TwitterProviderUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.net.URISyntaxException;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
 /**
@@ -100,7 +90,7 @@ public class Twitter implements
     properties.put("format", TwitterDateTimeFormat.TWITTER_FORMAT);
   }
 
-  RestClientBuilder restClientBuilder;
+  RestClient.Builder restClientBuilder;
 
   RestClient restClient;
 
@@ -125,23 +115,25 @@ public class Twitter implements
       .build();
     this.restClientBuilder = RestClient.create()
       .executorService(Executors.newCachedThreadPool(), false)
-      .httpClient(httpclient, true)
+      .httpClient(httpclient)
       .parser(
-        JsonParser.DEFAULT.builder()
-          .ignoreUnknownBeanProperties(true)
-          .pojoSwaps(TwitterJodaDateSwap.class, TwitterDateSwap.class)
+        JsonParser.DEFAULT.copy()
+          .ignoreUnknownBeanProperties()
+          .swaps(TwitterDateSwap.class)
           .build())
       .serializer(
-        JsonSerializer.DEFAULT.builder()
-          .pojoSwaps(TwitterJodaDateSwap.class, TwitterDateSwap.class)
+        JsonSerializer.DEFAULT.copy()
+          .swaps(TwitterDateSwap.class)
           .trimEmptyCollections(true)
           .trimEmptyMaps(true)
           .build())
       .rootUrl(rootUrl)
-      .retryable(
-        configuration.getRetryMax().intValue(),
-        configuration.getRetrySleepMs().intValue(),
-        new TwitterRetryHandler()
+      .retryHandler(
+        new BasicHttpRequestRetryHandler(
+                configuration.getRetryMax().intValue(),
+                configuration.getRetrySleepMs().intValue(),
+                true
+        )
       );
     if( configuration.getDebug() ) {
       restClientBuilder = restClientBuilder.debug();
@@ -167,119 +159,119 @@ public class Twitter implements
 
   @Override
   public List<Tweet> userTimeline(StatusesUserTimelineRequest parameters) {
-    Statuses restStatuses = restClient.getRemoteResource(Statuses.class, TwitterProviderUtil.baseUrl(configuration)+"/statuses");
+    Statuses restStatuses = restClient.getRemote(Statuses.class, TwitterProviderUtil.baseUrl(configuration)+"/statuses");
     List<Tweet> result = restStatuses.userTimeline(parameters);
     return result;
   }
 
   @Override
   public List<Tweet> retweets(RetweetsRequest parameters) {
-    Statuses restStatuses = restClient.getRemoteResource(Statuses.class, TwitterProviderUtil.baseUrl(configuration)+"/statuses");
+    Statuses restStatuses = restClient.getRemote(Statuses.class, TwitterProviderUtil.baseUrl(configuration)+"/statuses");
     List<Tweet> result = restStatuses.retweets(parameters);
     return result;
   }
 
   @Override
   public RetweeterIdsResponse retweeterIds(RetweeterIdsRequest parameters) {
-    Statuses restStatuses = restClient.getRemoteResource(Statuses.class, TwitterProviderUtil.baseUrl(configuration)+"/statuses");
+    Statuses restStatuses = restClient.getRemote(Statuses.class, TwitterProviderUtil.baseUrl(configuration)+"/statuses");
     RetweeterIdsResponse result = restStatuses.retweeterIds(parameters);
     return result;
   }
 
   @Override
   public List<Tweet> homeTimeline(StatusesHomeTimelineRequest parameters) {
-    Statuses restStatuses = restClient.getRemoteResource(Statuses.class, TwitterProviderUtil.baseUrl(configuration)+"/statuses");
+    Statuses restStatuses = restClient.getRemote(Statuses.class, TwitterProviderUtil.baseUrl(configuration)+"/statuses");
     List<Tweet> result = restStatuses.homeTimeline(parameters);
     return result;
   }
 
   @Override
   public List<Tweet> lookup(StatusesLookupRequest parameters) {
-    Statuses restStatuses = restClient.getRemoteResource(Statuses.class, TwitterProviderUtil.baseUrl(configuration)+"/statuses");
+    Statuses restStatuses = restClient.getRemote(Statuses.class, TwitterProviderUtil.baseUrl(configuration)+"/statuses");
     List<Tweet> result = restStatuses.lookup(parameters);
     return result;
   }
 
   @Override
   public List<Tweet> mentionsTimeline(StatusesMentionsTimelineRequest parameters) {
-    Statuses restStatuses = restClient.getRemoteResource(Statuses.class, TwitterProviderUtil.baseUrl(configuration)+"/statuses");
+    Statuses restStatuses = restClient.getRemote(Statuses.class, TwitterProviderUtil.baseUrl(configuration)+"/statuses");
     List<Tweet> result = restStatuses.mentionsTimeline(parameters);
     return result;
   }
 
   @Override
   public Tweet show(StatusesShowRequest parameters) {
-    Statuses restStatuses = restClient.getRemoteResource(Statuses.class, TwitterProviderUtil.baseUrl(configuration)+"/statuses");
+    Statuses restStatuses = restClient.getRemote(Statuses.class, TwitterProviderUtil.baseUrl(configuration)+"/statuses");
     Tweet result = restStatuses.show(parameters);
     return result;
   }
 
   @Override
   public FriendsIdsResponse ids(FriendsIdsRequest parameters) {
-    Friends restFriends = restClient.getRemoteResource(Friends.class, TwitterProviderUtil.baseUrl(configuration)+"/friends");
+    Friends restFriends = restClient.getRemote(Friends.class, TwitterProviderUtil.baseUrl(configuration)+"/friends");
     FriendsIdsResponse result = restFriends.ids(parameters);
     return result;
   }
 
   @Override
   public FriendsListResponse list(FriendsListRequest parameters) {
-    Friends restFriends = restClient.getRemoteResource(Friends.class, TwitterProviderUtil.baseUrl(configuration)+"/friends");
+    Friends restFriends = restClient.getRemote(Friends.class, TwitterProviderUtil.baseUrl(configuration)+"/friends");
     FriendsListResponse result = restFriends.list(parameters);
     return result;
   }
 
   @Override
   public FollowersIdsResponse ids(FollowersIdsRequest parameters) {
-    Followers restFollowers = restClient.getRemoteResource(Followers.class, TwitterProviderUtil.baseUrl(configuration)+"/followers");
+    Followers restFollowers = restClient.getRemote(Followers.class, TwitterProviderUtil.baseUrl(configuration)+"/followers");
     FollowersIdsResponse result = restFollowers.ids(parameters);
     return result;
   }
 
   @Override
   public FollowersListResponse list(FollowersListRequest parameters) {
-    Followers restFollowers = restClient.getRemoteResource(Followers.class, TwitterProviderUtil.baseUrl(configuration)+"/followers");
+    Followers restFollowers = restClient.getRemote(Followers.class, TwitterProviderUtil.baseUrl(configuration)+"/followers");
     FollowersListResponse result = restFollowers.list(parameters);
     return result;
   }
 
   @Override
   public List<User> lookup(UsersLookupRequest parameters) {
-    Users restUsers = restClient.getRemoteResource(Users.class, TwitterProviderUtil.baseUrl(configuration)+"/users");
+    Users restUsers = restClient.getRemote(Users.class, TwitterProviderUtil.baseUrl(configuration)+"/users");
     List<User> result = restUsers.lookup(parameters);
     return result;
   }
 
   @Override
   public List<User> search(UsersSearchRequest parameters) {
-    Users proxy = restClient.getRemoteResource(Users.class, TwitterProviderUtil.baseUrl(configuration)+"/users");
+    Users proxy = restClient.getRemote(Users.class, TwitterProviderUtil.baseUrl(configuration)+"/users");
     List<User> result = proxy.search(parameters);
     return result;
   }
 
   @Override
   public User show(UsersShowRequest parameters) {
-    Users restUsers = restClient.getRemoteResource(Users.class, TwitterProviderUtil.baseUrl(configuration)+"/users");
+    Users restUsers = restClient.getRemote(Users.class, TwitterProviderUtil.baseUrl(configuration)+"/users");
     User result = restUsers.show(parameters);
     return result;
   }
 
   @Override
   public List<Tweet> list(FavoritesListRequest parameters) {
-    Favorites restFavorites = restClient.getRemoteResource(Favorites.class, TwitterProviderUtil.baseUrl(configuration)+"/favorites");
+    Favorites restFavorites = restClient.getRemote(Favorites.class, TwitterProviderUtil.baseUrl(configuration)+"/favorites");
     List<Tweet> result = restFavorites.list(parameters);
     return result;
   }
 
   @Override
   public AccountSettings settings() {
-    Account restAccount = restClient.getRemoteResource(Account.class, TwitterProviderUtil.baseUrl(configuration)+"/account");
+    Account restAccount = restClient.getRemote(Account.class, TwitterProviderUtil.baseUrl(configuration)+"/account");
     AccountSettings result = restAccount.settings();
     return result;
   }
 
   @Override
   public User verifyCredentials() {
-    Account restAccount = restClient.getRemoteResource(Account.class, TwitterProviderUtil.baseUrl(configuration)+"/account");
+    Account restAccount = restClient.getRemote(Account.class, TwitterProviderUtil.baseUrl(configuration)+"/account");
     User result = restAccount.verifyCredentials();
     return result;
   }
@@ -296,97 +288,92 @@ public class Twitter implements
 
   @Override
   public WelcomeMessagesListResponse listWelcomeMessages(WelcomeMessagesListRequest parameters) {
-    WelcomeMessages proxy = restClient.getRemoteResource(WelcomeMessages.class, TwitterProviderUtil.baseUrl(configuration)+"/direct_messages/welcome_messages");
+    WelcomeMessages proxy = restClient.getRemote(WelcomeMessages.class, TwitterProviderUtil.baseUrl(configuration)+"/direct_messages/welcome_messages");
     return proxy.listWelcomeMessages(parameters);
   }
 
   @Override
   public WelcomeMessage showWelcomeMessage(Long id) {
-    WelcomeMessages proxy = restClient.getRemoteResource(WelcomeMessages.class, TwitterProviderUtil.baseUrl(configuration)+"/direct_messages/welcome_messages");
+    WelcomeMessages proxy = restClient.getRemote(WelcomeMessages.class, TwitterProviderUtil.baseUrl(configuration)+"/direct_messages/welcome_messages");
     return proxy.showWelcomeMessage(id);
   }
 
   @Override
   public WelcomeMessageNewResponse newWelcomeMessage(WelcomeMessageNewRequest parameters) {
-    WelcomeMessages proxy = restClient.getRemoteResource(WelcomeMessages.class, TwitterProviderUtil.baseUrl(configuration)+"/direct_messages/welcome_messages");
+    WelcomeMessages proxy = restClient.getRemote(WelcomeMessages.class, TwitterProviderUtil.baseUrl(configuration)+"/direct_messages/welcome_messages");
     return proxy.newWelcomeMessage(parameters);
   }
 
   @Override
   public void destroyWelcomeMessage(Long id) {
-    WelcomeMessages proxy = restClient.getRemoteResource(WelcomeMessages.class, TwitterProviderUtil.baseUrl(configuration)+"/direct_messages/welcome_messages");
+    WelcomeMessages proxy = restClient.getRemote(WelcomeMessages.class, TwitterProviderUtil.baseUrl(configuration)+"/direct_messages/welcome_messages");
     proxy.destroyWelcomeMessage(id);
   }
 
   @Override
   public WelcomeMessageRulesListResponse listWelcomeMessageRules(WelcomeMessageRulesListRequest parameters) {
-    WelcomeMessageRules proxy = restClient.getRemoteResource(WelcomeMessageRules.class, TwitterProviderUtil.baseUrl(configuration)+"/direct_messages/welcome_messages/rules");
+    WelcomeMessageRules proxy = restClient.getRemote(WelcomeMessageRules.class, TwitterProviderUtil.baseUrl(configuration)+"/direct_messages/welcome_messages/rules");
     return proxy.listWelcomeMessageRules(parameters);
   }
 
   @Override
   public WelcomeMessageRule showWelcomeMessageRule(Long id) {
-    WelcomeMessageRules proxy = restClient.getRemoteResource(WelcomeMessageRules.class, TwitterProviderUtil.baseUrl(configuration)+"/direct_messages/welcome_messages/rules");
+    WelcomeMessageRules proxy = restClient.getRemote(WelcomeMessageRules.class, TwitterProviderUtil.baseUrl(configuration)+"/direct_messages/welcome_messages/rules");
     return proxy.showWelcomeMessageRule(id);
   }
 
   @Override
   public WelcomeMessageRule newWelcomeMessageRule(WelcomeMessageNewRuleRequest body) {
-    WelcomeMessageRules proxy = restClient.getRemoteResource(WelcomeMessageRules.class, TwitterProviderUtil.baseUrl(configuration)+"/direct_messages/welcome_messages/rules");
+    WelcomeMessageRules proxy = restClient.getRemote(WelcomeMessageRules.class, TwitterProviderUtil.baseUrl(configuration)+"/direct_messages/welcome_messages/rules");
     return proxy.newWelcomeMessageRule(body);
   }
 
   @Override
   public void destroyWelcomeMessageRule(Long id) {
-    WelcomeMessageRules proxy = restClient.getRemoteResource(WelcomeMessageRules.class, TwitterProviderUtil.baseUrl(configuration)+"/direct_messages/welcome_messages/rules");
+    WelcomeMessageRules proxy = restClient.getRemote(WelcomeMessageRules.class, TwitterProviderUtil.baseUrl(configuration)+"/direct_messages/welcome_messages/rules");
     proxy.destroyWelcomeMessageRule(id);
   }
 
   @Override
   public WebhooksResponse getWebhooks() {
-    AccountActivity proxy = restClient.getRemoteResource(AccountActivity.class, TwitterProviderUtil.baseUrl(configuration)+"/account_activity");
+    AccountActivity proxy = restClient.getRemote(AccountActivity.class, TwitterProviderUtil.baseUrl(configuration)+"/account_activity");
     return proxy.getWebhooks();
   }
 
   @Override
   public List<Webhook> getWebhooks(String env_name) {
-    AccountActivity proxy = restClient.getRemoteResource(AccountActivity.class, TwitterProviderUtil.baseUrl(configuration)+"/account_activity");
+    AccountActivity proxy = restClient.getRemote(AccountActivity.class, TwitterProviderUtil.baseUrl(configuration)+"/account_activity");
     return proxy.getWebhooks(env_name);
   }
 
   @Override
   public Webhook registerWebhook(String env_name, String url) {
-    AccountActivity proxy = restClient.getRemoteResource(AccountActivity.class, TwitterProviderUtil.baseUrl(configuration)+"/account_activity");
+    AccountActivity proxy = restClient.getRemote(AccountActivity.class, TwitterProviderUtil.baseUrl(configuration)+"/account_activity");
     return proxy.registerWebhook(env_name, url);
   }
 
   @Override
   public Boolean deleteWebhook(String env_name, Long webhookId) {
-    AccountActivity proxy = restClient.getRemoteResource(AccountActivity.class, TwitterProviderUtil.baseUrl(configuration)+"/account_activity");
+    AccountActivity proxy = restClient.getRemote(AccountActivity.class, TwitterProviderUtil.baseUrl(configuration)+"/account_activity");
     return proxy.deleteWebhook(env_name, webhookId);
   }
 
   @Override
   public Boolean putWebhook(String env_name, Long webhookId) {
-    AccountActivity proxy = restClient.getRemoteResource(AccountActivity.class, TwitterProviderUtil.baseUrl(configuration)+"/account_activity");
+    AccountActivity proxy = restClient.getRemote(AccountActivity.class, TwitterProviderUtil.baseUrl(configuration)+"/account_activity");
     return proxy.putWebhook(env_name, webhookId);
   }
 
   @Override
   public Boolean reenableWebhook(String env_name, Long webhookId) {
+    URIBuilder uriBuilder = new URIBuilder()
+            .setPath("/account_activity/all/"+env_name+"/webhooks/"+webhookId+".json");
     try {
-      URIBuilder uriBuilder = new URIBuilder()
-              .setPath("/account_activity/all/"+env_name+"/webhooks/"+webhookId+".json");
-      RestCall restCall = restClient.doPut(uriBuilder.build().toString());
-      try {
-        int statusCode = restCall
-                .getResponse().getStatusLine().getStatusCode();
-        return statusCode == 204;
-      } catch (RestCallException e) {
-        LOGGER.warn("RestCallException", e);
-      }
-    } catch (IOException e) {
-      LOGGER.warn("IOException", e);
+      RestRequest restCall = restClient.put(uriBuilder.build().toString());
+      int statusCode = restCall.run().getStatusLine().getStatusCode();
+      return statusCode == 204;
+    } catch (RestCallException e) {
+      LOGGER.warn("RestCallException", e);
     } catch (URISyntaxException e) {
       LOGGER.warn("URISyntaxException", e);
     }
@@ -395,33 +382,26 @@ public class Twitter implements
 
   @Override
   public SubscriptionsCountResponse getSubscriptionsCount() throws InvocationTargetException, RestCallException {
-    AccountActivity proxy = restClient.getRemoteResource(AccountActivity.class, TwitterProviderUtil.baseUrl(configuration)+"/account_activity");
+    AccountActivity proxy = restClient.getRemote(AccountActivity.class, TwitterProviderUtil.baseUrl(configuration)+"/account_activity");
     return proxy.getSubscriptionsCount();
   }
 
   @Override
   public SubscriptionsListResponse getSubscriptionsList(String env_name) throws InvocationTargetException, RestCallException {
-    AccountActivity proxy = restClient.getRemoteResource(AccountActivity.class, TwitterProviderUtil.baseUrl(configuration)+"/account_activity");
+    AccountActivity proxy = restClient.getRemote(AccountActivity.class, TwitterProviderUtil.baseUrl(configuration)+"/account_activity");
     return proxy.getSubscriptionsList(env_name);
   }
 
   @Override
   public Boolean getSubscriptions(String env_name) {
-//    AccountActivity proxy = restClient.getRemoteResource(AccountActivity.class, TwitterProviderUtil.baseUrl(configuration)+"/account_activity");
-//    return proxy.getSubscriptions(env_name);
+    URIBuilder uriBuilder = new URIBuilder()
+            .setPath("/account_activity/all/"+env_name+"/subscriptions.json");
     try {
-      URIBuilder uriBuilder = new URIBuilder()
-              .setPath("/account_activity/all/"+env_name+"/subscriptions.json");
-      RestCall restCall = restClient.doGet(uriBuilder.build().toString());
-      try {
-        int statusCode = restCall
-                .getResponse().getStatusLine().getStatusCode();
-        return statusCode == 204;
-      } catch (RestCallException e) {
-        LOGGER.warn("RestCallException", e);
-      }
-    } catch (IOException e) {
-      LOGGER.warn("IOException", e);
+      RestRequest restCall = restClient.get(uriBuilder.build().toString());
+      int statusCode = restCall.run().getStatusLine().getStatusCode();
+      return statusCode == 204;
+    } catch (RestCallException e) {
+      LOGGER.warn("RestCallException", e);
     } catch (URISyntaxException e) {
       LOGGER.warn("URISyntaxException", e);
     }
@@ -430,21 +410,14 @@ public class Twitter implements
 
   @Override
   public Boolean newSubscription(String env_name) {
-//    AccountActivity proxy = restClient.getRemoteResource(AccountActivity.class, TwitterProviderUtil.baseUrl(configuration)+"/account_activity");
-//    return proxy.newSubscription(env_name);
+    URIBuilder uriBuilder = new URIBuilder()
+            .setPath("/account_activity/all/"+env_name+"/subscriptions.json");
     try {
-      URIBuilder uriBuilder = new URIBuilder()
-              .setPath("/account_activity/all/"+env_name+"/subscriptions.json");
-      RestCall restCall = restClient.doPost(uriBuilder.build().toString());
-      try {
-        int statusCode = restCall
-                .getResponse().getStatusLine().getStatusCode();
-        return statusCode == 204;
-      } catch (RestCallException e) {
-        LOGGER.warn("RestCallException", e);
-      }
-    } catch (IOException e) {
-      LOGGER.warn("IOException", e);
+      RestRequest restCall = restClient.post(uriBuilder.build().toString());
+      int statusCode = restCall.run().getStatusLine().getStatusCode();
+      return statusCode == 204;
+    } catch (RestCallException e) {
+      LOGGER.warn("RestCallException", e);
     } catch (URISyntaxException e) {
       LOGGER.warn("URISyntaxException", e);
     }
@@ -453,21 +426,14 @@ public class Twitter implements
 
   @Override
   public Boolean deleteWebhookSubscriptions(String env_name, String user_id) {
-//    AccountActivity proxy = restClient.getRemoteResource(AccountActivity.class, TwitterProviderUtil.baseUrl(configuration)+"/account_activity");
-//    return proxy.deleteWebhookSubscriptions(env_name, user_id);
+    URIBuilder uriBuilder = new URIBuilder()
+        .setPath("/account_activity/all/"+env_name+"/subscriptions/"+user_id+".json");
     try {
-      URIBuilder uriBuilder = new URIBuilder()
-          .setPath("/account_activity/all/"+env_name+"/subscriptions/"+user_id+".json");
-      RestCall restCall = restClient.doDelete(uriBuilder.build().toString());
-      try {
-        int statusCode = restCall
-          .getResponse().getStatusLine().getStatusCode();
-        return statusCode == 204;
-      } catch (RestCallException e) {
-        LOGGER.warn("RestCallException", e);
-      }
-    } catch (IOException e) {
-      LOGGER.warn("IOException", e);
+      RestRequest restCall = restClient.delete(uriBuilder.build().toString());
+      int statusCode = restCall.run().getStatusLine().getStatusCode();
+      return statusCode == 204;
+    } catch (RestCallException e) {
+      LOGGER.warn("RestCallException", e);
     } catch (URISyntaxException e) {
       LOGGER.warn("URISyntaxException", e);
     }
@@ -476,38 +442,38 @@ public class Twitter implements
 
   @Override
   public EventsListResponse listEvents(EventsListRequest parameters) {
-    DirectMessages proxy = restClient.getRemoteResource(DirectMessages.class, TwitterProviderUtil.baseUrl(configuration)+"/direct_messages");
+    DirectMessages proxy = restClient.getRemote(DirectMessages.class, TwitterProviderUtil.baseUrl(configuration)+"/direct_messages");
     return proxy.listEvents(parameters);
   }
 
   @Override
   public EventShowResponse showEvent(Long id) {
-    DirectMessages proxy = restClient.getRemoteResource(DirectMessages.class, TwitterProviderUtil.baseUrl(configuration)+"/direct_messages");
+    DirectMessages proxy = restClient.getRemote(DirectMessages.class, TwitterProviderUtil.baseUrl(configuration)+"/direct_messages");
     return proxy.showEvent(id);
   }
 
   @Override
   public DirectMessageEvent newEvent(MessageCreateRequest event) {
-    DirectMessages proxy = restClient.getRemoteResource(DirectMessages.class, TwitterProviderUtil.baseUrl(configuration)+"/direct_messages");
+    DirectMessages proxy = restClient.getRemote(DirectMessages.class, TwitterProviderUtil.baseUrl(configuration)+"/direct_messages");
     return proxy.newEvent(event);
   }
 
   @Override
   public SevenDaySearchResponse sevenDaySearch(SevenDaySearchRequest event) {
-    SevenDaySearch proxy = restClient.getRemoteResource(SevenDaySearch.class, TwitterProviderUtil.baseUrl(configuration)+"/search");
+    SevenDaySearch proxy = restClient.getRemote(SevenDaySearch.class, TwitterProviderUtil.baseUrl(configuration)+"/search");
     return proxy.sevenDaySearch(event);
   }
 
   @Override
   public ThirtyDaySearchResponse thirtyDaySearch(String environment, ThirtyDaySearchRequest searchRequest) {
-    ThirtyDaySearch proxy = restClient.getRemoteResource(ThirtyDaySearch.class, TwitterProviderUtil.baseUrl(configuration)+"/"+ThirtyDaySearch.path);
+    ThirtyDaySearch proxy = restClient.getRemote(ThirtyDaySearch.class, TwitterProviderUtil.baseUrl(configuration)+"/"+ThirtyDaySearch.path);
     String env = StringUtils.defaultString(environment, configuration.getEnvironment());
     return proxy.thirtyDaySearch(env, searchRequest);
   }
 
   @Override
   public ThirtyDaySearchCountsResponse thirtyDaySearchCounts(String environment, ThirtyDaySearchCountsRequest searchCountsRequest) {
-    ThirtyDaySearchCounts proxy = restClient.getRemoteResource(ThirtyDaySearchCounts.class, TwitterProviderUtil.baseUrl(configuration)+"/"+ThirtyDaySearch.path);
+    ThirtyDaySearchCounts proxy = restClient.getRemote(ThirtyDaySearchCounts.class, TwitterProviderUtil.baseUrl(configuration)+"/"+ThirtyDaySearch.path);
     String env = StringUtils.defaultString(environment, configuration.getEnvironment());
     return proxy.thirtyDaySearchCounts(env, searchCountsRequest);
   }
@@ -539,19 +505,19 @@ public class Twitter implements
 
   @Override
   public List<SuggestedUserCategory> categories(String lang) {
-    SuggestedUsers proxy = restClient.getRemoteResource(SuggestedUsers.class, TwitterProviderUtil.baseUrl(configuration)+"/users");
+    SuggestedUsers proxy = restClient.getRemote(SuggestedUsers.class, TwitterProviderUtil.baseUrl(configuration)+"/users");
     return proxy.categories(lang);
   }
 
   @Override
   public SuggestedUserCategory suggestions(String slug, String lang) {
-    SuggestedUsers proxy = restClient.getRemoteResource(SuggestedUsers.class, TwitterProviderUtil.baseUrl(configuration)+"/users");
+    SuggestedUsers proxy = restClient.getRemote(SuggestedUsers.class, TwitterProviderUtil.baseUrl(configuration)+"/users");
     return proxy.suggestions(slug, lang);
   }
 
   @Override
   public List<User> members(String slug) {
-    SuggestedUsers proxy = restClient.getRemoteResource(SuggestedUsers.class, TwitterProviderUtil.baseUrl(configuration)+"/users");
+    SuggestedUsers proxy = restClient.getRemote(SuggestedUsers.class, TwitterProviderUtil.baseUrl(configuration)+"/users");
     return proxy.members(slug);
   }
 
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/TwitterOAuthRequestInterceptor.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/TwitterOAuthRequestInterceptor.java
index d1c54fff4e..08e6fecc09 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/TwitterOAuthRequestInterceptor.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/TwitterOAuthRequestInterceptor.java
@@ -18,18 +18,13 @@
 
 package org.apache.streams.twitter.api;
 
-import org.apache.streams.twitter.config.TwitterOAuthConfiguration;
-
 import org.apache.commons.codec.binary.Base64;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpEntityEnclosingRequest;
-import org.apache.http.HttpException;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpRequestInterceptor;
+import org.apache.http.*;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.methods.HttpRequestWrapper;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.util.EntityUtils;
+import org.apache.streams.twitter.config.TwitterOAuthConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/TwitterRetryHandler.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/TwitterRetryHandler.java
deleted file mode 100644
index f53d434ffb..0000000000
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/TwitterRetryHandler.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.apache.streams.twitter.api;
-
-import org.apache.http.HttpResponse;
-import org.apache.http.util.EntityUtils;
-import org.apache.juneau.json.JsonParser;
-import org.apache.juneau.parser.ParseException;
-import org.apache.juneau.rest.client.RetryOn;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-
-/**
- *  Handle expected and unexpected exceptions.
- */
-public class TwitterRetryHandler extends RetryOn {
-
-  private static final Logger LOGGER = LoggerFactory.getLogger(TwitterRetryHandler.class);
-
-  protected boolean onResponse(HttpResponse response) {
-    if( response == null ) return false;
-    LOGGER.debug(response.toString());
-    switch(response.getStatusLine().getStatusCode()) {
-      case 200: // Response.Status.OK
-      case 304: // Response.Status.NOT_MODIFIED
-      case 400: // Response.Status.BAD_REQUEST
-        return false;
-      case 401: // Response.Status.UNAUTHORIZED
-        return true;
-      case 403: // Response.Status.FORBIDDEN
-      case 404: // Response.Status.NOT_FOUND
-      case 406: // Response.Status.NOT_ACCEPTABLE
-      case 410: // Response.Status.GONE
-        return false;
-      case 420: // Enhance Your Calm
-      case 429: // Too Many Requests
-        return true;
-      case 500: // Response.Status.INTERNAL_SERVER_ERROR
-      case 502: // Bad Gateway
-      case 503: // Response.Status.SERVICE_UNAVAILABLE
-      case 504: // Gateway Timeout
-        return true;
-      default:
-        return false;
-    }
-  }
-
-  private ResponseErrors parseResponseErrors(HttpResponse response) {
-    ResponseErrors responseErrors = null;
-    if (response.getEntity() != null) {
-      try {
-        String responseEntity = EntityUtils.toString(response.getEntity());
-        LOGGER.debug(responseEntity);
-        responseErrors = JsonParser.DEFAULT.parse(responseEntity, ResponseErrors.class);
-      } catch (IOException ex) {
-        LOGGER.error("IOException", ex);
-      } catch (ParseException ex) {
-        LOGGER.error("ParseException", ex);
-      }
-    }
-    return responseErrors;
-  }
-}
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/TwitterSecurity.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/TwitterSecurity.java
index 5e351e9b19..89214fa587 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/TwitterSecurity.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/TwitterSecurity.java
@@ -22,18 +22,13 @@ import org.apache.commons.codec.binary.Base64;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.security.GeneralSecurityException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.StringJoiner;
-import java.util.TreeSet;
-
 import javax.crypto.Mac;
 import javax.crypto.SecretKey;
 import javax.crypto.spec.SecretKeySpec;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.security.GeneralSecurityException;
+import java.util.*;
 
 /**
  * Created by sblackmon on 6/15/17.
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Users.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Users.java
index c1f6f4e221..5b7ab122c8 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Users.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Users.java
@@ -18,11 +18,10 @@
 
 package org.apache.streams.twitter.api;
 
-import org.apache.streams.twitter.pojo.User;
-
 import org.apache.juneau.http.annotation.Query;
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemoteGet;
+import org.apache.streams.twitter.pojo.User;
 
 import java.util.List;
 
@@ -31,7 +30,7 @@ import java.util.List;
  *
  * @see <a href="https://dev.twitter.com/rest/reference">https://dev.twitter.com/rest/reference</a>
  */
-@RemoteInterface(path = "https://api.twitter.com/1.1/users")
+@Remote(path = "https://api.twitter.com/1.1/users")
 public interface Users {
 
   /**
@@ -42,8 +41,8 @@ public interface Users {
    * @see <a href="https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-lookup">https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-lookup</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/lookup.json")
-  public List<User> lookup( @Query(name = "*", skipIfEmpty = true) UsersLookupRequest parameters);
+  @RemoteGet(path = "/lookup.json")
+  public List<User> lookup( @Query(name = "*") UsersLookupRequest parameters);
 
   /**
    * Provides a simple, relevance-based search interface to public user accounts on Twitter. Try querying by topical interest, full name, company name, location, or other criteria. Exact match searches are not supported.
@@ -55,8 +54,8 @@ public interface Users {
    * @see <a href="https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-search">https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-search</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/search.json")
-  public List<User> search( @Query(name = "*", skipIfEmpty = true) UsersSearchRequest parameters);
+  @RemoteGet(path = "/search.json")
+  public List<User> search( @Query(name = "*") UsersSearchRequest parameters);
 
   /**
    * Returns a variety of information about the user specified by the required user_id or screen_name parameter. The author’s most recent Tweet will be returned inline when possible.
@@ -65,7 +64,7 @@ public interface Users {
    * @see <a href="https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-show">https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-show</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/show.json")
-  public User show( @Query(name = "*", skipIfEmpty = true) UsersShowRequest parameters);
+  @RemoteGet(path = "/show.json")
+  public User show( @Query(name = "*") UsersShowRequest parameters);
 
 }
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/WelcomeMessageRules.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/WelcomeMessageRules.java
index eb8eeadbfa..a6ceb29cda 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/WelcomeMessageRules.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/WelcomeMessageRules.java
@@ -18,19 +18,20 @@
 
 package org.apache.streams.twitter.api;
 
-import org.apache.streams.twitter.pojo.WelcomeMessageRule;
-
-import org.apache.juneau.http.annotation.Body;
+import org.apache.juneau.http.annotation.Content;
 import org.apache.juneau.http.annotation.Query;
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemoteDelete;
+import org.apache.juneau.http.remote.RemoteGet;
+import org.apache.juneau.http.remote.RemotePost;
+import org.apache.streams.twitter.pojo.WelcomeMessageRule;
 
 /**
  * Interface for /direct_messages/welcome_messages/rules methods.
  *
  * @see <a href="https://dev.twitter.com/rest/reference">https://dev.twitter.com/rest/reference</a>
  */
-@RemoteInterface(path = "https://api.twitter.com/1.1/direct_messages/welcome_messages/rules")
+@Remote(path = "https://api.twitter.com/1.1/direct_messages/welcome_messages/rules")
 public interface WelcomeMessageRules {
 
   /**
@@ -40,8 +41,8 @@ public interface WelcomeMessageRules {
    * @see <a href="https://developer.twitter.com/en/docs/direct-messages/welcome-messages/api-reference/list-welcome-message-rules">https://developer.twitter.com/en/docs/direct-messages/welcome-messages/api-reference/list-welcome-message-rules</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/list.json")
-  public WelcomeMessageRulesListResponse listWelcomeMessageRules(@Query(name = "*", skipIfEmpty = true) WelcomeMessageRulesListRequest parameters);
+  @RemoteGet(path = "/list.json")
+  public WelcomeMessageRulesListResponse listWelcomeMessageRules(@Query(name = "*") WelcomeMessageRulesListRequest parameters);
 
   /**
    * Returns a Welcome Message Rule by the given id.
@@ -50,7 +51,7 @@ public interface WelcomeMessageRules {
    * @see <a href="https://developer.twitter.com/en/docs/direct-messages/welcome-messages/api-reference/get-welcome-message-rule">https://developer.twitter.com/en/docs/direct-messages/welcome-messages/api-reference/get-welcome-message-rule</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/show.json")
+  @RemoteGet(path = "/show.json")
   public WelcomeMessageRule showWelcomeMessageRule(@Query("id") Long id);
 
   /**
@@ -64,8 +65,8 @@ public interface WelcomeMessageRules {
    * @see <a href="https://developer.twitter.com/en/docs/direct-messages/welcome-messages/api-reference/new-welcome-message-rule">https://developer.twitter.com/en/docs/direct-messages/welcome-messages/api-reference/new-welcome-message-rule</a>
    *
    */
-  @RemoteMethod(method ="POST", path = "/new.json")
-  public WelcomeMessageRule newWelcomeMessageRule(@Body WelcomeMessageNewRuleRequest body);
+  @RemotePost(path = "/new.json")
+  public WelcomeMessageRule newWelcomeMessageRule(@Content WelcomeMessageNewRuleRequest body);
 
   /**
    * Deletes a Welcome Message Rule by the given id.
@@ -73,7 +74,7 @@ public interface WelcomeMessageRules {
    * @see <a href="https://developer.twitter.com/en/docs/direct-messages/welcome-messages/api-reference/delete-welcome-message-rule">https://developer.twitter.com/en/docs/direct-messages/welcome-messages/api-reference/delete-welcome-message-rule</a>
    *
    */
-  @RemoteMethod(method ="DELETE", path = "/destroy.json")
+  @RemoteDelete(path = "/destroy.json")
   public void destroyWelcomeMessageRule(@Query("id") Long id);
 
 }
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/WelcomeMessages.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/WelcomeMessages.java
index 39314ac27e..de6670ffdc 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/WelcomeMessages.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/WelcomeMessages.java
@@ -18,19 +18,20 @@
 
 package org.apache.streams.twitter.api;
 
-import org.apache.streams.twitter.pojo.WelcomeMessage;
-
-import org.apache.juneau.http.annotation.Body;
+import org.apache.juneau.http.annotation.Content;
 import org.apache.juneau.http.annotation.Query;
-import org.apache.juneau.remote.RemoteInterface;
-import org.apache.juneau.rest.client.remote.RemoteMethod;
+import org.apache.juneau.http.remote.Remote;
+import org.apache.juneau.http.remote.RemoteDelete;
+import org.apache.juneau.http.remote.RemoteGet;
+import org.apache.juneau.http.remote.RemotePost;
+import org.apache.streams.twitter.pojo.WelcomeMessage;
 
 /**
  * Interface for /direct_messages/welcome_messages methods.
  *
  * @see <a href="https://developer.twitter.com/en/docs/direct-messages/welcome-messages/api-reference">https://developer.twitter.com/en/docs/direct-messages/welcome-messages/api-reference</a>
  */
-@RemoteInterface(path = "https://api.twitter.com/1.1/direct_messages/welcome_messages")
+@Remote(path = "https://api.twitter.com/1.1/direct_messages/welcome_messages")
 public interface WelcomeMessages {
 
   /**
@@ -40,8 +41,8 @@ public interface WelcomeMessages {
    * @see <a href="https://developer.twitter.com/en/docs/direct-messages/welcome-messages/api-reference/list-welcome-messages">https://developer.twitter.com/en/docs/direct-messages/welcome-messages/api-reference/list-welcome-messages</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/list.json")
-  public WelcomeMessagesListResponse listWelcomeMessages(@Query(name = "*", skipIfEmpty = true) WelcomeMessagesListRequest parameters);
+  @RemoteGet(path = "/list.json")
+  public WelcomeMessagesListResponse listWelcomeMessages(@Query(name = "*") WelcomeMessagesListRequest parameters);
 
   /**
    * Returns a Welcome Message by the given id.
@@ -50,7 +51,7 @@ public interface WelcomeMessages {
    * @see <a href="https://developer.twitter.com/en/docs/direct-messages/welcome-messages/api-reference/get-welcome-message">https://developer.twitter.com/en/docs/direct-messages/welcome-messages/api-reference/get-welcome-message</a>
    *
    */
-  @RemoteMethod(method ="GET", path = "/show.json")
+  @RemoteGet(path = "/show.json")
   public WelcomeMessage showWelcomeMessage(@Query("id") Long id);
 
   /**
@@ -60,15 +61,15 @@ public interface WelcomeMessages {
    * @see <a href="https://developer.twitter.com/en/docs/direct-messages/welcome-messages/api-reference/new-welcome-message">https://developer.twitter.com/en/docs/direct-messages/welcome-messages/api-reference/new-welcome-message</a>
    *
    */
-  @RemoteMethod(method ="POST", path = "/new.json")
-  public WelcomeMessageNewResponse newWelcomeMessage(@Body WelcomeMessageNewRequest messageNewRequest);
+  @RemotePost(path = "/new.json")
+  public WelcomeMessageNewResponse newWelcomeMessage(@Content WelcomeMessageNewRequest messageNewRequest);
 
   /**
    * Deletes a Welcome Message by the given id.
    *
    * @see <a href="https://developer.twitter.com/en/docs/direct-messages/welcome-messages/api-reference/delete-welcome-message">https://developer.twitter.com/en/docs/direct-messages/welcome-messages/api-reference/delete-welcome-message</a>
    */
-  @RemoteMethod(method ="DELETE", path = "/destroy.json")
+  @RemoteDelete(path = "/destroy.json")
   public void destroyWelcomeMessage(@Query("id") Long id);
 
 }
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/converter/TwitterDateSwap.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/converter/TwitterDateSwap.java
index f4d57059bf..8ecd97057e 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/converter/TwitterDateSwap.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/converter/TwitterDateSwap.java
@@ -18,34 +18,18 @@
 
 package org.apache.streams.twitter.converter;
 
-import org.apache.juneau.BeanSession;
-import org.apache.juneau.ClassMeta;
-import org.apache.juneau.parser.ParseException;
-import org.apache.juneau.transform.StringSwap;
-import org.apache.streams.data.util.RFC3339Utils;
+import org.apache.juneau.swaps.TemporalDateSwap;
 
-import java.time.LocalDateTime;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatter;
 import java.util.Date;
 
 /**
  * Transforms {@link Date} to {@link String Strings}.
  */
 
-public class TwitterDateSwap extends StringSwap<Date> {
-
-  DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(TwitterDateTimeFormat.TWITTER_FORMAT);
-
-  @Override /* PojoSwap */
-  public String swap(BeanSession session, Date o) {
-    return ZonedDateTime.ofInstant(o.toInstant(), ZoneOffset.UTC).format(dateTimeFormatter);
-  }
-
-  @Override /* PojoSwap */
-  public Date unswap(BeanSession session, String s, ClassMeta<?> hint) {
-    return Date.from(LocalDateTime.parse(s, dateTimeFormatter).atZone(ZoneOffset.UTC).toInstant());
+public class TwitterDateSwap extends TemporalDateSwap {
+  public TwitterDateSwap() {
+    super(TwitterDateTimeFormat.TWITTER_FORMAT);
   }
 
 }
+
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/converter/TwitterJodaDateSwap.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/converter/TwitterJodaDateSwap.java
deleted file mode 100644
index ccfb048e13..0000000000
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/converter/TwitterJodaDateSwap.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements.  See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership.  The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-*
-*   http://www.apache.org/licenses/LICENSE-2.0
-*
-* 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.apache.streams.twitter.converter;
-
-import org.apache.juneau.BeanSession;
-import org.apache.juneau.ClassMeta;
-import org.apache.juneau.parser.ParseException;
-import org.apache.juneau.transform.StringSwap;
-import org.joda.time.DateTime;
-import org.joda.time.format.DateTimeFormat;
-import org.joda.time.format.DateTimeFormatter;
-
-/**
- * Transforms {@link org.joda.time.DateTime} to {@link String Strings}.
- */
-
-public class TwitterJodaDateSwap extends StringSwap<DateTime> {
-
-  DateTimeFormatter dateFormatter = DateTimeFormat.forPattern(TwitterDateTimeFormat.TWITTER_FORMAT);
-
-  @Override /* PojoSwap */
-  public String swap(BeanSession session, DateTime o) {
-    return dateFormatter.print(o);
-  }
-
-  @Override /* PojoSwap */
-  public DateTime unswap(BeanSession session, String f, ClassMeta<?> hint) throws ParseException {
-    if( hint.equals("org.joda.time.DateTime"))
-      return dateFormatter.parseDateTime(f);
-    else return null;
-  }
-
-}
diff --git a/streams-plugins/streams-plugin-pojo/src/main/java/org/apache/streams/plugins/JuneauPojoAnnotator.java b/streams-plugins/streams-plugin-pojo/src/main/java/org/apache/streams/plugins/JuneauPojoAnnotator.java
index 437feb531b..eb5ad89bb9 100644
--- a/streams-plugins/streams-plugin-pojo/src/main/java/org/apache/streams/plugins/JuneauPojoAnnotator.java
+++ b/streams-plugins/streams-plugin-pojo/src/main/java/org/apache/streams/plugins/JuneauPojoAnnotator.java
@@ -23,7 +23,7 @@ import com.fasterxml.jackson.databind.JsonNode;
 import com.sun.codemodel.JDefinedClass;
 import com.sun.codemodel.JFieldVar;
 import com.sun.codemodel.JMethod;
-import org.apache.juneau.annotation.BeanProperty;
+import org.apache.juneau.annotation.Beanp;
 import org.jsonschema2pojo.AbstractAnnotator;
 
 /**
@@ -42,7 +42,7 @@ public class JuneauPojoAnnotator extends AbstractAnnotator {
    */
   public void propertyField(JFieldVar field, JDefinedClass clazz,
                             String propertyName, JsonNode propertyNode) {
-    field.annotate(BeanProperty.class).param("value", propertyName);
+    field.annotate(Beanp.class).param("value", propertyName);
   }
 
 
@@ -57,7 +57,7 @@ public class JuneauPojoAnnotator extends AbstractAnnotator {
    *            the name of the JSON property that this getter gets
    */
   public void propertyGetter(JMethod getter, String propertyName) {
-    getter.annotate(BeanProperty.class).param("value", propertyName);
+    getter.annotate(Beanp.class).param("value", propertyName);
   }
 
   /**
@@ -71,7 +71,7 @@ public class JuneauPojoAnnotator extends AbstractAnnotator {
    *            the name of the JSON property that this setter sets
    */
   public void propertySetter(JMethod setter, String propertyName) {
-    setter.annotate(BeanProperty.class).param("value", propertyName);
+    setter.annotate(Beanp.class).param("value", propertyName);
   }
 
   /**
@@ -84,7 +84,7 @@ public class JuneauPojoAnnotator extends AbstractAnnotator {
    *            properties
    */
   public void anyGetter(JMethod getter) {
-    getter.annotate(BeanProperty.class).param("name", "*");
+    getter.annotate(Beanp.class).param("name", "*");
   }
 
   /**
@@ -97,6 +97,6 @@ public class JuneauPojoAnnotator extends AbstractAnnotator {
    *            properties
    */
   public void anySetter(JMethod setter) {
-    setter.annotate(BeanProperty.class).param("name", "*");
+    setter.annotate(Beanp.class).param("name", "*");
   }
 }
diff --git a/streams-pojo/src/main/java/org/apache/streams/juneau/DateSwap.java b/streams-pojo/src/main/java/org/apache/streams/juneau/DateSwap.java
deleted file mode 100644
index 7e980f2411..0000000000
--- a/streams-pojo/src/main/java/org/apache/streams/juneau/DateSwap.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.apache.streams.juneau;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.juneau.BeanSession;
-import org.apache.juneau.ClassMeta;
-import org.apache.juneau.parser.ParseException;
-import org.apache.juneau.transform.StringSwap;
-import org.apache.streams.data.util.RFC3339Utils;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.Date;
-
-/**
- * Transforms {@link Date} to {@link String Strings}.
- */
-public class DateSwap extends StringSwap<Date> {
-
-  DateTimeFormatter dateTimeFormatter;
-
-  /**
-   * Constructor.
-   */
-  public DateSwap() {
-    dateTimeFormatter = DateTimeFormatter.ISO_INSTANT;
-  }
-
-  @Override /* PojoSwap */
-  public String swap(BeanSession session, Date o) {
-    DateTimeFormatter dateTimeFormatter = this.dateTimeFormatter;
-    if( StringUtils.isNotBlank(session.getProperty("format", String.class, RFC3339Utils.UTC_STANDARD_FMT.toString()))) {
-      dateTimeFormatter = DateTimeFormatter.ofPattern(session.getProperty("format", String.class, RFC3339Utils.UTC_STANDARD_FMT.toString()));
-    }
-    return ZonedDateTime.ofInstant(o.toInstant(), ZoneOffset.UTC).format(dateTimeFormatter);
-  }
-
-  @Override /* PojoSwap */
-  public Date unswap(BeanSession session, String s, ClassMeta<?> hint) {
-    DateTimeFormatter dateTimeFormatter = this.dateTimeFormatter;
-    if( StringUtils.isNotBlank(session.getProperty("format", String.class, RFC3339Utils.UTC_STANDARD_FMT.toString()))) {
-      dateTimeFormatter = DateTimeFormatter.ofPattern(session.getProperty("format", String.class, RFC3339Utils.UTC_STANDARD_FMT.toString()));
-    }
-    return Date.from(LocalDateTime.parse(s, dateTimeFormatter).atZone(ZoneOffset.UTC).toInstant());
-  }
-
-}
diff --git a/streams-pojo/src/main/java/org/apache/streams/juneau/JodaDateSwap.java b/streams-pojo/src/main/java/org/apache/streams/juneau/JodaDateSwap.java
deleted file mode 100644
index 5a37517941..0000000000
--- a/streams-pojo/src/main/java/org/apache/streams/juneau/JodaDateSwap.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.apache.streams.juneau;
-
-import org.apache.streams.data.util.RFC3339Utils;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.juneau.BeanSession;
-import org.apache.juneau.ClassMeta;
-import org.apache.juneau.parser.ParseException;
-import org.apache.juneau.transform.StringSwap;
-import org.joda.time.DateTime;
-import org.joda.time.format.DateTimeFormat;
-import org.joda.time.format.DateTimeFormatter;
-import org.joda.time.format.ISODateTimeFormat;
-
-/**
- * Transforms {@link org.joda.time.DateTime} to {@link String Strings}.
- */
-public class JodaDateSwap extends StringSwap<DateTime> {
-
-  DateTimeFormatter dateFormatter;
-
-  /**
-   * Constructor.
-   */
-  public JodaDateSwap() {
-    dateFormatter = ISODateTimeFormat.dateTime();
-  }
-
-  @Override /* PojoSwap */
-  public String swap(BeanSession session, DateTime o) {
-    DateTimeFormatter dateFormatter = this.dateFormatter;
-    if( StringUtils.isNotBlank(session.getProperty("format", String.class, RFC3339Utils.UTC_STANDARD_FMT.toString()))) {
-      dateFormatter = DateTimeFormat.forPattern(session.getProperty("format", String.class, RFC3339Utils.UTC_STANDARD_FMT.toString()));
-    }
-    return dateFormatter.print(o);
-  }
-
-  @Override /* PojoSwap */
-  public DateTime unswap(BeanSession session, String f, ClassMeta<?> hint) throws ParseException {
-    DateTimeFormatter dateFormatter = this.dateFormatter;
-    if( StringUtils.isNotBlank(session.getProperty("format", String.class, RFC3339Utils.UTC_STANDARD_FMT.toString()))) {
-      dateFormatter = DateTimeFormat.forPattern(session.getProperty("format", String.class, RFC3339Utils.UTC_STANDARD_FMT.toString()));
-    }
-    return dateFormatter.parseDateTime(f);
-  }
-
-}