Repository: hub4j/github-api
Pull request #1944 (2024-09-17 18:16:42)

Backport 2.0-alpha-2 changes 1.x
# Description

<!-- Describe your change here -->

# Before submitting a PR:

- [ ] Changes must not break binary backwards compatibility. If you are unclear on how to make the change you think is needed while maintaining backward compatibility, [CONTRIBUTING.md](CONTRIBUTING.md) for details.
- [ ] Add JavaDocs and other comments explaining the behavior. 
- [ ] When adding or updating methods that fetch entities, add `@link` JavaDoc entries to the relevant documentation on https://docs.github.com/en/rest . 
- [ ] Add tests that cover any added or changed code. This generally requires capturing snapshot test data. See [CONTRIBUTING.md](CONTRIBUTING.md) for details.
- [ ] Run `mvn -D enable-ci clean install site` locally. If this command doesn't succeed, your change will not pass CI.
- [ ] Push your changes to a branch other than `main`. You will create your PR from that branch.

# When creating a PR: 

- [ ] Fill in the "Description" above with clear summary of the changes. This includes:
  - [ ] If this PR fixes one or more issues, include "Fixes #<issue number>" lines for each issue. 
  - [ ] Provide links to relevant documentation on https://docs.github.com/en/rest where possible. If not including links, explain why not.
- [ ] All lines of new code should be covered by tests as reported by code coverage. Any lines that are not covered must have PR comments explaining why they cannot be covered. For example, "Reaching this particular exception is hard and is not a particular common scenario."
- [ ] Enable "Allow edits from maintainers".



Patch:
diff --git a/.github/workflows/maven-build.yml b/.github/workflows/maven-build.yml
index 5ce3de342..acbcaba2f 100644
--- a/.github/workflows/maven-build.yml
+++ b/.github/workflows/maven-build.yml
@@ -57,7 +57,9 @@ jobs:
     - name: Maven Site
       env:
         MAVEN_OPTS: ${{ env.JAVA_11_PLUS_MAVEN_OPTS }}
-      run: mvn -B clean site -D enable-ci --file pom.xml
+      # running install site seems to more closely imitate real site deployment,
+      # more likely to prevent failed deployment
+      run: mvn -B clean install site -DskipTests --file pom.xml
   test:
     name: test (${{ matrix.os }}, Java ${{ matrix.java }})
     # Does not require build output, but orders execution to prevent launching test workflows when simple build fails 
@@ -144,7 +146,7 @@ jobs:
     - name: Set up JDK
       uses: actions/setup-java@v4
       with:
-        java-version: 8
+        java-version: 11
         distribution: 'temurin'
         cache: 'maven'
     - name: Maven Test (no build) Java 11
diff --git a/.github/workflows/publish_release_branch.yml b/.github/workflows/publish_release_branch.yml
index 897878363..6e3041a43 100644
--- a/.github/workflows/publish_release_branch.yml
+++ b/.github/workflows/publish_release_branch.yml
@@ -59,7 +59,7 @@ jobs:
   publish_gh_pages:
     runs-on: ubuntu-latest
     needs: build
-    if:  ${{ github.ref == 'refs/heads/release/v1.x' }}
+    if:  ${{ github.ref == 'refs/heads/release/v2.x' }}
     steps:
       - uses: actions/checkout@v4
         with:
diff --git a/pom.xml b/pom.xml
index b0622b27e..b0e5f99c7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -34,7 +34,7 @@
   <properties>
     <spring.boot.version>3.3.3</spring.boot.version>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    <spotbugs-maven-plugin.version>4.8.6.1</spotbugs-maven-plugin.version>
+    <spotbugs-maven-plugin.version>4.8.6.3</spotbugs-maven-plugin.version>
     <spotbugs.version>4.8.6</spotbugs.version>
     <spotbugs-maven-plugin.failOnError>true</spotbugs-maven-plugin.failOnError>
     <hamcrest.version>3.0</hamcrest.version>
@@ -94,7 +94,7 @@
         </plugin>
         <plugin>
           <artifactId>maven-surefire-plugin</artifactId>
-          <version>3.2.3</version>
+          <version>3.5.0</version>
           <configuration>
             <!-- SUREFIRE-1226 workaround -->
             <trimStackTrace>false</trimStackTrace>
@@ -108,7 +108,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-gpg-plugin</artifactId>
-          <version>3.2.4</version>
+          <version>3.2.6</version>
         </plugin>
         <plugin>
           <groupId>org.jacoco</groupId>
@@ -223,7 +223,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-javadoc-plugin</artifactId>
-          <version>3.8.0</version>
+          <version>3.10.0</version>
           <configuration>
             <release>8</release>
             <failOnWarnings>true</failOnWarnings>
@@ -247,7 +247,7 @@
       <!--
       This plugin is used to generate AOT metadata during tests so that it can be
       compared against those in META-INF/native-image/org.kohsuke/github-api/*.
-      The tests are located in src/test/java/org.kohsuke.aot
+      The tests are start with the name "Aot..." 
       -->
       <plugin>
         <groupId>org.springframework.boot</groupId>
@@ -290,7 +290,7 @@
           <dependency>
             <groupId>org.apache.bcel</groupId>
             <artifactId>bcel</artifactId>
-            <version>6.9.0</version>
+            <version>6.10.0</version>
           </dependency>
         </dependencies>
       </plugin>
@@ -436,8 +436,16 @@
       <plugin>
         <groupId>com.github.siom79.japicmp</groupId>
         <artifactId>japicmp-maven-plugin</artifactId>
-        <version>0.17.2</version>
+        <version>0.23.0</version>
         <configuration>
+          <oldVersion>
+            <dependency>
+              <groupId>${project.groupId}</groupId>
+              <artifactId>${project.artifactId}</artifactId>
+              <version>1.325</version>
+              <type>jar</type>
+            </dependency>
+          </oldVersion>
           <parameter>
             <breakBuildOnBinaryIncompatibleModifications>true</breakBuildOnBinaryIncompatibleModifications>
             <onlyModified>true</onlyModified>
@@ -478,7 +486,7 @@
     <dependency>
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-lang3</artifactId>
-      <version>3.14.0</version>
+      <version>3.17.0</version>
     </dependency>
     <dependency>
       <groupId>com.tngtech.archunit</groupId>
diff --git a/src/main/java/org/kohsuke/github/AbstractBuilder.java b/src/main/java/org/kohsuke/github/AbstractBuilder.java
index 189d3f7a5..8a581270e 100644
--- a/src/main/java/org/kohsuke/github/AbstractBuilder.java
+++ b/src/main/java/org/kohsuke/github/AbstractBuilder.java
@@ -7,7 +7,6 @@ import java.io.IOException;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 
-// TODO: Auto-generated Javadoc
 /**
  * An abstract data object builder/updater.
  *
@@ -42,7 +41,7 @@ import javax.annotation.Nonnull;
  *            Intermediate return type for this builder returned by calls to {@link #with(String, Object)}. If {@link S}
  *            the same as {@link R}, this builder will commit changes after each call to {@link #with(String, Object)}.
  */
-abstract class AbstractBuilder<R, S> extends GitHubInteractiveObject {
+abstract class AbstractBuilder<R, S> extends GitHubInteractiveObject implements GitHubRequestBuilderDone<R> {
 
     @Nonnull
     private final Class<R> returnType;
@@ -58,9 +57,9 @@ abstract class AbstractBuilder<R, S> extends GitHubInteractiveObject {
 
     // TODO: Not sure how update-in-place behavior should be controlled
     // However, it certainly can be controlled dynamically down to the instance level or inherited for all children of
-    // some
+    // some connection.
+
     /** The update in place. */
-    // connection.
     protected boolean updateInPlace;
 
     /**
@@ -96,14 +95,9 @@ abstract class AbstractBuilder<R, S> extends GitHubInteractiveObject {
     }
 
     /**
-     * Finishes an update, committing changes.
-     *
-     * This method may update-in-place or not. Either way it returns the resulting instance.
-     *
-     * @return an instance with updated current data
-     * @throws IOException
-     *             if there is an I/O Exception
+     * {@inheritDoc}
      */
+    @Override
     @Nonnull
     @BetaApi
     public R done() throws IOException {
diff --git a/src/main/java/org/kohsuke/github/AbuseLimitHandler.java b/src/main/java/org/kohsuke/github/AbuseLimitHandler.java
index 09084080a..288a1542b 100644
--- a/src/main/java/org/kohsuke/github/AbuseLimitHandler.java
+++ b/src/main/java/org/kohsuke/github/AbuseLimitHandler.java
@@ -25,6 +25,12 @@ import javax.annotation.Nonnull;
 @Deprecated
 public abstract class AbuseLimitHandler extends GitHubAbuseLimitHandler {
 
+    /**
+     * Create default AbuseLimitHandler instance
+     */
+    public AbuseLimitHandler() {
+    }
+
     /**
      * Called when the library encounters HTTP error indicating that the API abuse limit is reached.
      *
@@ -102,6 +108,9 @@ public abstract class AbuseLimitHandler extends GitHubAbuseLimitHandler {
         }
     };
 
+    // If "Retry-After" missing, wait for unambiguously over one minute per GitHub guidance
+    static long DEFAULT_WAIT_MILLIS = 61 * 1000;
+
     /*
      * Exposed for testability. Given an http response, find the retry-after header field and parse it as either a
      * number or a date (the spec allows both). If no header is found, wait for a reasonably amount of time.
@@ -110,7 +119,7 @@ public abstract class AbuseLimitHandler extends GitHubAbuseLimitHandler {
         String v = uc.getHeaderField("Retry-After");
         if (v == null) {
             // can't tell, wait for unambiguously over one minute per GitHub guidance
-            return 61 * 1000;
+            return DEFAULT_WAIT_MILLIS;
         }
 
         try {
diff --git a/src/main/java/org/kohsuke/github/GHApp.java b/src/main/java/org/kohsuke/github/GHApp.java
index 904b7c369..49f1bb5b3 100644
--- a/src/main/java/org/kohsuke/github/GHApp.java
+++ b/src/main/java/org/kohsuke/github/GHApp.java
@@ -20,6 +20,12 @@ import java.util.stream.Collectors;
  */
 public class GHApp extends GHObject {
 
+    /**
+     * Create default GHApp instance
+     */
+    public GHApp() {
+    }
+
     private GHUser owner;
     private String name;
     private String slug;
diff --git a/src/main/java/org/kohsuke/github/GHAppFromManifest.java b/src/main/java/org/kohsuke/github/GHAppFromManifest.java
index ed58423bb..3d6c4cdf2 100644
--- a/src/main/java/org/kohsuke/github/GHAppFromManifest.java
+++ b/src/main/java/org/kohsuke/github/GHAppFromManifest.java
@@ -8,6 +8,12 @@ package org.kohsuke.github;
  */
 public class GHAppFromManifest extends GHApp {
 
+    /**
+     * Create default GHAppFromManifest instance
+     */
+    public GHAppFromManifest() {
+    }
+
     private String clientId;
     private String clientSecret;
     private String webhookSecret;
diff --git a/src/main/java/org/kohsuke/github/GHAppInstallation.java b/src/main/java/org/kohsuke/github/GHAppInstallation.java
index 0e18ec680..b33595a1b 100644
--- a/src/main/java/org/kohsuke/github/GHAppInstallation.java
+++ b/src/main/java/org/kohsuke/github/GHAppInstallation.java
@@ -24,6 +24,13 @@ import java.util.stream.Collectors;
  * @see GHApp#getInstallationByUser(String) GHApp#getInstallationByUser(String)
  */
 public class GHAppInstallation extends GHObject {
+
+    /**
+     * Create default GHAppInstallation instance
+     */
+    public GHAppInstallation() {
+    }
+
     private GHUser account;
 
     @JsonProperty("access_tokens_url")
diff --git a/src/main/java/org/kohsuke/github/GHAppInstallationToken.java b/src/main/java/org/kohsuke/github/GHAppInstallationToken.java
index 415cc996b..11a01bfdd 100644
--- a/src/main/java/org/kohsuke/github/GHAppInstallationToken.java
+++ b/src/main/java/org/kohsuke/github/GHAppInstallationToken.java
@@ -14,6 +14,13 @@ import java.util.*;
  * @see GHAppInstallation#createToken(Map) GHAppInstallation#createToken(Map)
  */
 public class GHAppInstallationToken extends GitHubInteractiveObject {
+
+    /**
+     * Create default GHAppInstallationToken instance
+     */
+    public GHAppInstallationToken() {
+    }
+
     private String token;
 
     /** The expires at. */
diff --git a/src/main/java/org/kohsuke/github/GHArtifact.java b/src/main/java/org/kohsuke/github/GHArtifact.java
index a50454d0d..f1b96e052 100644
--- a/src/main/java/org/kohsuke/github/GHArtifact.java
+++ b/src/main/java/org/kohsuke/github/GHArtifact.java
@@ -20,6 +20,12 @@ import static java.util.Objects.requireNonNull;
  */
 public class GHArtifact extends GHObject {
 
+    /**
+     * Create default GHArtifact instance
+     */
+    public GHArtifact() {
+    }
+
     // Not provided by the API.
     @JsonIgnore
     private GHRepository owner;
diff --git a/src/main/java/org/kohsuke/github/GHAsset.java b/src/main/java/org/kohsuke/github/GHAsset.java
index d64116f5e..0f73ddc7e 100644
--- a/src/main/java/org/kohsuke/github/GHAsset.java
+++ b/src/main/java/org/kohsuke/github/GHAsset.java
@@ -13,6 +13,12 @@ import java.net.URL;
  */
 public class GHAsset extends GHObject {
 
+    /**
+     * Create default GHAsset instance
+     */
+    public GHAsset() {
+    }
+
     /** The owner. */
     GHRepository owner;
     private String name;
diff --git a/src/main/java/org/kohsuke/github/GHAuthorization.java b/src/main/java/org/kohsuke/github/GHAuthorization.java
index 5286750ed..d7b38da1f 100644
--- a/src/main/java/org/kohsuke/github/GHAuthorization.java
+++ b/src/main/java/org/kohsuke/github/GHAuthorization.java
@@ -17,6 +17,12 @@ import java.util.List;
  */
 public class GHAuthorization extends GHObject {
 
+    /**
+     * Create default GHAuthorization instance
+     */
+    public GHAuthorization() {
+    }
+
     /** The Constant USER. */
     public static final String USER = "user";
 
diff --git a/src/main/java/org/kohsuke/github/GHBlob.java b/src/main/java/org/kohsuke/github/GHBlob.java
index 0f109d38a..2fc168ec6 100644
--- a/src/main/java/org/kohsuke/github/GHBlob.java
+++ b/src/main/java/org/kohsuke/github/GHBlob.java
@@ -16,6 +16,13 @@ import java.util.Base64;
  * @see <a href="https://developer.github.com/v3/git/blobs/#get-a-blob">Get a blob</a>
  */
 public class GHBlob {
+
+    /**
+     * Create default GHBlob instance
+     */
+    public GHBlob() {
+    }
+
     private String content, encoding, url, sha;
     private long size;
 
diff --git a/src/main/java/org/kohsuke/github/GHBranch.java b/src/main/java/org/kohsuke/github/GHBranch.java
index 21dc55717..207cb6abd 100644
--- a/src/main/java/org/kohsuke/github/GHBranch.java
+++ b/src/main/java/org/kohsuke/github/GHBranch.java
@@ -49,6 +49,12 @@ public class GHBranch extends GitHubInteractiveObject {
      */
     public static class Commit {
 
+        /**
+         * Create default Commit instance
+         */
+        public Commit() {
+        }
+
         /** The sha. */
         String sha;
 
diff --git a/src/main/java/org/kohsuke/github/GHBranchProtection.java b/src/main/java/org/kohsuke/github/GHBranchProtection.java
index 1b0ee3f3e..8fbdc0d23 100644
--- a/src/main/java/org/kohsuke/github/GHBranchProtection.java
+++ b/src/main/java/org/kohsuke/github/GHBranchProtection.java
@@ -19,6 +19,13 @@ import java.util.Collections;
                 "URF_UNREAD_FIELD" },
         justification = "JSON API")
 public class GHBranchProtection extends GitHubInteractiveObject {
+
+    /**
+     * Create default GHBranchProtection instance
+     */
+    public GHBranchProtection() {
+    }
+
     private static final String REQUIRE_SIGNATURES_URI = "/required_signatures";
 
     @JsonProperty
@@ -204,6 +211,13 @@ public class GHBranchProtection extends GitHubInteractiveObject {
      * The type AllowDeletions.
      */
     public static class AllowDeletions {
+
+        /**
+         * Create default AllowDeletions instance
+         */
+        public AllowDeletions() {
+        }
+
         @JsonProperty
         private boolean enabled;
 
@@ -270,6 +284,13 @@ public class GHBranchProtection extends GitHubInteractiveObject {
      * The type AllowForcePushes.
      */
     public static class AllowForcePushes {
+
+        /**
+         * Create default AllowForcePushes instance
+         */
+        public AllowForcePushes() {
+        }
+
         @JsonProperty
         private boolean enabled;
 
@@ -287,6 +308,13 @@ public class GHBranchProtection extends GitHubInteractiveObject {
      * The type AllowForkSyncing.
      */
     public static class AllowForkSyncing {
+
+        /**
+         * Create default AllowForkSyncing instance
+         */
+        public AllowForkSyncing() {
+        }
+
         @JsonProperty
         private boolean enabled;
 
@@ -304,6 +332,13 @@ public class GHBranchProtection extends GitHubInteractiveObject {
      * The type BlockCreations.
      */
     public static class BlockCreations {
+
+        /**
+         * Create default BlockCreations instance
+         */
+        public BlockCreations() {
+        }
+
         @JsonProperty
         private boolean enabled;
 
@@ -321,6 +356,13 @@ public class GHBranchProtection extends GitHubInteractiveObject {
      * The type EnforceAdmins.
      */
     public static class EnforceAdmins {
+
+        /**
+         * Create default EnforceAdmins instance
+         */
+        public EnforceAdmins() {
+        }
+
         @JsonProperty
         private boolean enabled;
 
@@ -350,6 +392,13 @@ public class GHBranchProtection extends GitHubInteractiveObject {
      * The type LockBranch.
      */
     public static class LockBranch {
+
+        /**
+         * Create default LockBranch instance
+         */
+        public LockBranch() {
+        }
+
         @JsonProperty
         private boolean enabled;
 
@@ -367,6 +416,13 @@ public class GHBranchProtection extends GitHubInteractiveObject {
      * The type RequiredConversationResolution.
      */
     public static class RequiredConversationResolution {
+
+        /**
+         * Create default RequiredConversationResolution instance
+         */
+        public RequiredConversationResolution() {
+        }
+
         @JsonProperty
         private boolean enabled;
 
@@ -384,6 +440,13 @@ public class GHBranchProtection extends GitHubInteractiveObject {
      * The type RequiredLinearHistory.
      */
     public static class RequiredLinearHistory {
+
+        /**
+         * Create default RequiredLinearHistory instance
+         */
+        public RequiredLinearHistory() {
+        }
+
         @JsonProperty
         private boolean enabled;
 
@@ -401,6 +464,13 @@ public class GHBranchProtection extends GitHubInteractiveObject {
      * The type RequiredReviews.
      */
     public static class RequiredReviews {
+
+        /**
+         * Create default RequiredReviews instance
+         */
+        public RequiredReviews() {
+        }
+
         @JsonProperty("dismissal_restrictions")
         private Restrictions dismissalRestriction;
 
@@ -504,6 +574,13 @@ public class GHBranchProtection extends GitHubInteractiveObject {
      * The type RequiredStatusChecks.
      */
     public static class RequiredStatusChecks {
+
+        /**
+         * Create default RequiredStatusChecks instance
+         */
+        public RequiredStatusChecks() {
+        }
+
         @JsonProperty
         private Collection<String> contexts;
 
@@ -557,6 +634,13 @@ public class GHBranchProtection extends GitHubInteractiveObject {
      * The type Restrictions.
      */
     public static class Restrictions {
+
+        /**
+         * Create default Restrictions instance
+         */
+        public Restrictions() {
+        }
+
         @JsonProperty
         private Collection<GHTeam> teams;
 
diff --git a/src/main/java/org/kohsuke/github/GHBranchSync.java b/src/main/java/org/kohsuke/github/GHBranchSync.java
index d03f4a79b..c6823abd5 100644
--- a/src/main/java/org/kohsuke/github/GHBranchSync.java
+++ b/src/main/java/org/kohsuke/github/GHBranchSync.java
@@ -7,6 +7,12 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
  */
 public class GHBranchSync extends GitHubInteractiveObject {
 
+    /**
+     * Create default GHBranchSync instance
+     */
+    public GHBranchSync() {
+    }
+
     /**
      * The Repository that this branch is in.
      */
diff --git a/src/main/java/org/kohsuke/github/GHCheckRun.java b/src/main/java/org/kohsuke/github/GHCheckRun.java
index 0593656cf..0ea03f495 100644
--- a/src/main/java/org/kohsuke/github/GHCheckRun.java
+++ b/src/main/java/org/kohsuke/github/GHCheckRun.java
@@ -24,6 +24,12 @@ import java.util.Locale;
         justification = "JSON API")
 public class GHCheckRun extends GHObject {
 
+    /**
+     * Create default GHCheckRun instance
+     */
+    public GHCheckRun() {
+    }
+
     /** The owner. */
     @JsonProperty("repository")
     GHRepository owner;
@@ -326,6 +332,13 @@ public class GHCheckRun extends GHObject {
      * @see <a href="https://developer.github.com/v3/checks/runs/#output-object">documentation</a>
      */
     public static class Output {
+
+        /**
+         * Create default Output instance
+         */
+        public Output() {
+        }
+
         private String title;
         private String summary;
         private String text;
diff --git a/src/main/java/org/kohsuke/github/GHCheckSuite.java b/src/main/java/org/kohsuke/github/GHCheckSuite.java
index ee70b4c74..9e358fbd8 100644
--- a/src/main/java/org/kohsuke/github/GHCheckSuite.java
+++ b/src/main/java/org/kohsuke/github/GHCheckSuite.java
@@ -20,6 +20,12 @@ import java.util.List;
         justification = "JSON API")
 public class GHCheckSuite extends GHObject {
 
+    /**
+     * Create default GHCheckSuite instance
+     */
+    public GHCheckSuite() {
+    }
+
     /** The owner. */
     @JsonProperty("repository")
     GHRepository owner;
@@ -215,6 +221,13 @@ public class GHCheckSuite extends GHObject {
      * The Class HeadCommit.
      */
     public static class HeadCommit {
+
+        /**
+         * Create default HeadCommit instance
+         */
+        public HeadCommit() {
+        }
+
         private String id;
         private String treeId;
         private String message;
diff --git a/src/main/java/org/kohsuke/github/GHCodeownersError.java b/src/main/java/org/kohsuke/github/GHCodeownersError.java
index 8d5662700..49654263b 100644
--- a/src/main/java/org/kohsuke/github/GHCodeownersError.java
+++ b/src/main/java/org/kohsuke/github/GHCodeownersError.java
@@ -8,6 +8,13 @@ package org.kohsuke.github;
  * @author Michael Grant
  */
 public class GHCodeownersError {
+
+    /**
+     * Create default GHCodeownersError instance
+     */
+    public GHCodeownersError() {
+    }
+
     private int line, column;
 
     private String kind, source, suggestion, message, path;
diff --git a/src/main/java/org/kohsuke/github/GHCommit.java b/src/main/java/org/kohsuke/github/GHCommit.java
index acdf94399..c75f24ffe 100644
--- a/src/main/java/org/kohsuke/github/GHCommit.java
+++ b/src/main/java/org/kohsuke/github/GHCommit.java
@@ -116,6 +116,12 @@ public class GHCommit {
      */
     public static class Stats {
 
+        /**
+         * Create default Stats instance
+         */
+        public Stats() {
+        }
+
         /** The deletions. */
         int total, additions, deletions;
     }
@@ -126,6 +132,12 @@ public class GHCommit {
     @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "It's being initialized by JSON deserialization")
     public static class File {
 
+        /**
+         * Create default File instance
+         */
+        public File() {
+        }
+
         /** The status. */
         String status;
 
@@ -240,6 +252,12 @@ public class GHCommit {
      */
     public static class Parent {
 
+        /**
+         * Create default Parent instance
+         */
+        public Parent() {
+        }
+
         /** The url. */
         @SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "We don't provide it in API now")
         String url;
diff --git a/src/main/java/org/kohsuke/github/GHCommitComment.java b/src/main/java/org/kohsuke/github/GHCommitComment.java
index 1ce023e31..40427b41e 100644
--- a/src/main/java/org/kohsuke/github/GHCommitComment.java
+++ b/src/main/java/org/kohsuke/github/GHCommitComment.java
@@ -18,6 +18,13 @@ import java.net.URL;
 @SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
         justification = "JSON API")
 public class GHCommitComment extends GHObject implements Reactable {
+
+    /**
+     * Create default GHCommitComment instance
+     */
+    public GHCommitComment() {
+    }
+
     private GHRepository owner;
 
     /** The commit id. */
diff --git a/src/main/java/org/kohsuke/github/GHCommitPointer.java b/src/main/java/org/kohsuke/github/GHCommitPointer.java
index 870872ad6..f56c214a5 100644
--- a/src/main/java/org/kohsuke/github/GHCommitPointer.java
+++ b/src/main/java/org/kohsuke/github/GHCommitPointer.java
@@ -34,6 +34,13 @@ import java.io.IOException;
  * @author Kohsuke Kawaguchi
  */
 public class GHCommitPointer {
+
+    /**
+     * Create default GHCommitPointer instance
+     */
+    public GHCommitPointer() {
+    }
+
     private String ref, sha, label;
     private GHUser user;
     private GHRepository repo;
diff --git a/src/main/java/org/kohsuke/github/GHCommitStatus.java b/src/main/java/org/kohsuke/github/GHCommitStatus.java
index 45a5d9436..718a33e13 100644
--- a/src/main/java/org/kohsuke/github/GHCommitStatus.java
+++ b/src/main/java/org/kohsuke/github/GHCommitStatus.java
@@ -15,6 +15,12 @@ import java.net.URL;
  */
 public class GHCommitStatus extends GHObject {
 
+    /**
+     * Create default GHCommitStatus instance
+     */
+    public GHCommitStatus() {
+    }
+
     /** The state. */
     String state;
 
diff --git a/src/main/java/org/kohsuke/github/GHCompare.java b/src/main/java/org/kohsuke/github/GHCompare.java
index 08c6f051b..afb95e667 100644
--- a/src/main/java/org/kohsuke/github/GHCompare.java
+++ b/src/main/java/org/kohsuke/github/GHCompare.java
@@ -19,6 +19,12 @@ import javax.annotation.Nonnull;
  */
 public class GHCompare {
 
+    /**
+     * Create default GHCompare instance
+     */
+    public GHCompare() {
+    }
+
     private String url, html_url, permalink_url, diff_url, patch_url;
     private Status status;
     private int ahead_by, behind_by, total_commits;
@@ -235,6 +241,12 @@ public class GHCompare {
             justification = "JSON API")
     public static class Commit extends GHCommit {
 
+        /**
+         * Create default Commit instance
+         */
+        public Commit() {
+        }
+
         private InnerCommit commit;
 
         /**
@@ -251,6 +263,13 @@ public class GHCompare {
      * The type InnerCommit.
      */
     public static class InnerCommit {
+
+        /**
+         * Create default InnerCommit instance
+         */
+        public InnerCommit() {
+        }
+
         private String url, sha, message;
         private User author, committer;
         private Tree tree;
@@ -316,6 +335,13 @@ public class GHCompare {
      * The type Tree.
      */
     public static class Tree {
+
+        /**
+         * Create default Tree instance
+         */
+        public Tree() {
+        }
+
         private String url, sha;
 
         /**
@@ -343,6 +369,11 @@ public class GHCompare {
      * @deprecated use {@link GitUser} instead.
      */
     public static class User extends GitUser {
+        /**
+         * Create default User instance
+         */
+        public User() {
+        }
     }
 
     /**
diff --git a/src/main/java/org/kohsuke/github/GHContent.java b/src/main/java/org/kohsuke/github/GHContent.java
index c476a89d8..0140aff87 100644
--- a/src/main/java/org/kohsuke/github/GHContent.java
+++ b/src/main/java/org/kohsuke/github/GHContent.java
@@ -17,6 +17,13 @@ import java.util.Base64;
  */
 @SuppressWarnings({ "UnusedDeclaration" })
 public class GHContent extends GitHubInteractiveObject implements Refreshable {
+
+    /**
+     * Create default GHContent instance
+     */
+    public GHContent() {
+    }
+
     /*
      * In normal use of this class, repository field is set via wrap(), but in the code search API, there's a nested
      * 'repository' field that gets populated from JSON.
diff --git a/src/main/java/org/kohsuke/github/GHContentUpdateResponse.java b/src/main/java/org/kohsuke/github/GHContentUpdateResponse.java
index 5da5ecf7c..f6d1207ab 100644
--- a/src/main/java/org/kohsuke/github/GHContentUpdateResponse.java
+++ b/src/main/java/org/kohsuke/github/GHContentUpdateResponse.java
@@ -8,6 +8,13 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
  * The response that is returned when updating repository content.
  */
 public class GHContentUpdateResponse {
+
+    /**
+     * Create default GHContentUpdateResponse instance
+     */
+    public GHContentUpdateResponse() {
+    }
+
     private GHContent content;
     private GitCommit commit;
 
diff --git a/src/main/java/org/kohsuke/github/GHCreateRepositoryBuilder.java b/src/main/java/org/kohsuke/github/GHCreateRepositoryBuilder.java
index e50ff7aa8..1c5fecbdf 100644
--- a/src/main/java/org/kohsuke/github/GHCreateRepositoryBuilder.java
+++ b/src/main/java/org/kohsuke/github/GHCreateRepositoryBuilder.java
@@ -94,7 +94,7 @@ public class GHCreateRepositoryBuilder extends GHRepositoryBuilder<GHCreateRepos
      * @return a builder to continue with building
      * @throws IOException
      *             In case of any networking error or error from the server.
-     * @deprecated Use {@link #isTemplate(boolean)} method instead
+     * @deprecated Use {@link GHCreateRepositoryBuilder#isTemplate(boolean)} method instead
      */
     @Deprecated
     public GHCreateRepositoryBuilder templateRepository(boolean enabled) throws IOException {
diff --git a/src/main/java/org/kohsuke/github/GHDeployKey.java b/src/main/java/org/kohsuke/github/GHDeployKey.java
index 2af3b9d7e..9f4a34513 100644
--- a/src/main/java/org/kohsuke/github/GHDeployKey.java
+++ b/src/main/java/org/kohsuke/github/GHDeployKey.java
@@ -11,6 +11,12 @@ import java.util.Date;
  */
 public class GHDeployKey {
 
+    /**
+     * Create default GHDeployKey instance
+     */
+    public GHDeployKey() {
+    }
+
     /** The title. */
     protected String url, key, title;
 
diff --git a/src/main/java/org/kohsuke/github/GHDeployment.java b/src/main/java/org/kohsuke/github/GHDeployment.java
index 62152485f..b537414cd 100644
--- a/src/main/java/org/kohsuke/github/GHDeployment.java
+++ b/src/main/java/org/kohsuke/github/GHDeployment.java
@@ -15,6 +15,13 @@ import java.util.Map;
  * @see GHRepository#getDeployment(long) GHRepository#getDeployment(long)
  */
 public class GHDeployment extends GHObject {
+
+    /**
+     * Create default GHDeployment instance
+     */
+    public GHDeployment() {
+    }
+
     private GHRepository owner;
 
     /** The sha. */
diff --git a/src/main/java/org/kohsuke/github/GHDeploymentStatus.java b/src/main/java/org/kohsuke/github/GHDeploymentStatus.java
index 80a222173..9e74dafb8 100644
--- a/src/main/java/org/kohsuke/github/GHDeploymentStatus.java
+++ b/src/main/java/org/kohsuke/github/GHDeploymentStatus.java
@@ -8,6 +8,13 @@ import java.util.Locale;
  * The type GHDeploymentStatus.
  */
 public class GHDeploymentStatus extends GHObject {
+
+    /**
+     * Create default GHDeploymentStatus instance
+     */
+    public GHDeploymentStatus() {
+    }
+
     private GHRepository owner;
 
     /** The creator. */
diff --git a/src/main/java/org/kohsuke/github/GHDiscussion.java b/src/main/java/org/kohsuke/github/GHDiscussion.java
index 88f851b28..b46c7ae34 100644
--- a/src/main/java/org/kohsuke/github/GHDiscussion.java
+++ b/src/main/java/org/kohsuke/github/GHDiscussion.java
@@ -19,6 +19,12 @@ import javax.annotation.Nonnull;
  */
 public class GHDiscussion extends GHObject {
 
+    /**
+     * Create default GHDiscussion instance
+     */
+    public GHDiscussion() {
+    }
+
     private GHTeam team;
     private long number;
     private String body, title, htmlUrl;
@@ -196,7 +202,7 @@ public class GHDiscussion extends GHObject {
     /**
      * A {@link GHLabelBuilder} that updates a single property per request
      *
-     * {@link #done()} is called automatically after the property is set.
+     * {@link GitHubRequestBuilderDone#done()} is called automatically after the property is set.
      */
     public static class Setter extends GHDiscussionBuilder<GHDiscussion> {
         private Setter(@Nonnull GHDiscussion base) {
@@ -208,7 +214,7 @@ public class GHDiscussion extends GHObject {
     /**
      * A {@link GHLabelBuilder} that allows multiple properties to be updated per request.
      *
-     * Consumer must call {@link #done()} to commit changes.
+     * Consumer must call {@link Updater#done()} to commit changes.
      */
     public static class Updater extends GHDiscussionBuilder<Updater> {
         private Updater(@Nonnull GHDiscussion base) {
@@ -220,7 +226,7 @@ public class GHDiscussion extends GHObject {
     /**
      * A {@link GHLabelBuilder} that creates a new {@link GHLabel}
      *
-     * Consumer must call {@link #done()} to create the new instance.
+     * Consumer must call {@link Creator#done()} to create the new instance.
      */
     public static class Creator extends GHDiscussionBuilder<Creator> {
 
diff --git a/src/main/java/org/kohsuke/github/GHEmail.java b/src/main/java/org/kohsuke/github/GHEmail.java
index 270f09baf..75dcc0b6b 100644
--- a/src/main/java/org/kohsuke/github/GHEmail.java
+++ b/src/main/java/org/kohsuke/github/GHEmail.java
@@ -37,6 +37,12 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
         justification = "JSON API")
 public class GHEmail {
 
+    /**
+     * Create default GHEmail instance
+     */
+    public GHEmail() {
+    }
+
     /** The email. */
     protected String email;
 
diff --git a/src/main/java/org/kohsuke/github/GHError.java b/src/main/java/org/kohsuke/github/GHError.java
index ed2e52502..9455ff31f 100644
--- a/src/main/java/org/kohsuke/github/GHError.java
+++ b/src/main/java/org/kohsuke/github/GHError.java
@@ -13,6 +13,12 @@ import java.net.URL;
  */
 public class GHError implements Serializable {
 
+    /**
+     * Create default GHError instance
+     */
+    public GHError() {
+    }
+
     /**
      * The serial version UID of the error
      */
diff --git a/src/main/java/org/kohsuke/github/GHEventInfo.java b/src/main/java/org/kohsuke/github/GHEventInfo.java
index a781cb566..551b6cb2e 100644
--- a/src/main/java/org/kohsuke/github/GHEventInfo.java
+++ b/src/main/java/org/kohsuke/github/GHEventInfo.java
@@ -14,6 +14,13 @@ import java.util.*;
  */
 @SuppressFBWarnings(value = "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", justification = "JSON API")
 public class GHEventInfo extends GitHubInteractiveObject {
+
+    /**
+     * Create default GHEventInfo instance
+     */
+    public GHEventInfo() {
+    }
+
     // we don't want to expose Jackson dependency to the user. This needs databinding
     private ObjectNode payload;
 
@@ -44,6 +51,13 @@ public class GHEventInfo extends GitHubInteractiveObject {
                     "UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR" },
             justification = "JSON API")
     public static class GHEventRepository {
+
+        /**
+         * Create default GHEventRepository instance
+         */
+        public GHEventRepository() {
+        }
+
         @SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "We don't provide it in API now")
         private long id;
         @SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "We don't provide it in API now")
diff --git a/src/main/java/org/kohsuke/github/GHEventPayload.java b/src/main/java/org/kohsuke/github/GHEventPayload.java
index 2e34daa29..5e5c00e8b 100644
--- a/src/main/java/org/kohsuke/github/GHEventPayload.java
+++ b/src/main/java/org/kohsuke/github/GHEventPayload.java
@@ -145,6 +145,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      * @see <a href="https://docs.github.com/en/rest/reference/checks#check-runs">Check Runs</a>
      */
     public static class CheckRun extends GHEventPayload {
+
+        /**
+         * Create default CheckRun instance
+         */
+        public CheckRun() {
+        }
+
         private int number;
         private GHCheckRun checkRun;
         private GHRequestedAction requestedAction;
@@ -228,6 +235,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      * @see <a href="https://docs.github.com/en/rest/reference/checks#check-suites">Check Suites</a>
      */
     public static class CheckSuite extends GHEventPayload {
+
+        /**
+         * Create default CheckSuite instance
+         */
+        public CheckSuite() {
+        }
+
         private GHCheckSuite checkSuite;
 
         /**
@@ -268,6 +282,12 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      */
     public static class Installation extends GHEventPayload {
 
+        /**
+         * Create default Installation instance
+         */
+        public Installation() {
+        }
+
         private List<Repository> repositories;
         private List<GHRepository> ghRepositories = null;
 
@@ -327,6 +347,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
          * "https://docs.github.com/en/webhooks-and-events/webhooks/webhook-events-and-payloads#installation">here</a>
          */
         public static class Repository {
+
+            /**
+             * Create default Repository instance
+             */
+            public Repository() {
+            }
+
             private long id;
             private String fullName;
             private String name;
@@ -390,6 +417,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      * @see <a href="https://docs.github.com/en/rest/reference/apps#installations">GitHub App installation</a>
      */
     public static class InstallationRepositories extends GHEventPayload {
+
+        /**
+         * Create default InstallationRepositories instance
+         */
+        public InstallationRepositories() {
+        }
+
         private String repositorySelection;
         private List<GHRepository> repositoriesAdded;
         private List<GHRepository> repositoriesRemoved;
@@ -459,6 +493,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      */
     @SuppressFBWarnings(value = { "NP_UNWRITTEN_FIELD" }, justification = "JSON API")
     public static class PullRequest extends GHEventPayload {
+
+        /**
+         * Create default PullRequest instance
+         */
+        public PullRequest() {
+        }
+
         private int number;
         private GHPullRequest pullRequest;
         private GHLabel label;
@@ -528,6 +569,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      * @see <a href="https://docs.github.com/en/rest/reference/pulls#reviews">Pull Request Reviews</a>
      */
     public static class PullRequestReview extends GHEventPayload {
+
+        /**
+         * Create default PullRequestReview instance
+         */
+        public PullRequestReview() {
+        }
+
         private GHPullRequestReview review;
         private GHPullRequest pullRequest;
 
@@ -579,6 +627,12 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
     @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "JSON API")
     public static class CommentChanges {
 
+        /**
+         * Create default CommentChanges instance
+         */
+        public CommentChanges() {
+        }
+
         private GHFrom body;
 
         /**
@@ -594,6 +648,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
          * Wrapper for changed values.
          */
         public static class GHFrom {
+
+            /**
+             * Create default GHFrom instance
+             */
+            public GHFrom() {
+            }
+
             private String from;
 
             /**
@@ -616,6 +677,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      * @see <a href="https://docs.github.com/en/rest/reference/pulls#review-comments">Pull Request Review Comments</a>
      */
     public static class PullRequestReviewComment extends GHEventPayload {
+
+        /**
+         * Create default PullRequestReviewComment instance
+         */
+        public PullRequestReviewComment() {
+        }
+
         private GHPullRequestReviewComment comment;
         private GHPullRequest pullRequest;
         private CommentChanges changes;
@@ -676,6 +744,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      * @see <a href="https://docs.github.com/en/rest/reference/issues#comments">Issues Comments</a>
      */
     public static class Issue extends GHEventPayload {
+
+        /**
+         * Create default Issue instance
+         */
+        public Issue() {
+        }
+
         private GHIssue issue;
 
         private GHLabel label;
@@ -746,6 +821,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      * @see <a href="https://docs.github.com/en/rest/reference/issues#comments">Issue Comments</a>
      */
     public static class IssueComment extends GHEventPayload {
+
+        /**
+         * Create default IssueComment instance
+         */
+        public IssueComment() {
+        }
+
         private GHIssueComment comment;
         private GHIssue issue;
         private CommentChanges changes;
@@ -826,6 +908,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      * @see <a href="https://docs.github.com/en/rest/reference/repos#comments">Comments</a>
      */
     public static class CommitComment extends GHEventPayload {
+
+        /**
+         * Create default CommitComment instance
+         */
+        public CommitComment() {
+        }
+
         private GHCommitComment comment;
 
         /**
@@ -871,6 +960,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      * @see <a href="https://docs.github.com/en/rest/reference/git">Git data</a>
      */
     public static class Create extends GHEventPayload {
+
+        /**
+         * Create default Create instance
+         */
+        public Create() {
+        }
+
         private String ref;
         private String refType;
         private String masterBranch;
@@ -923,6 +1019,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      * @see <a href="https://docs.github.com/en/rest/reference/git">Git data</a>
      */
     public static class Delete extends GHEventPayload {
+
+        /**
+         * Create default Delete instance
+         */
+        public Delete() {
+        }
+
         private String ref;
         private String refType;
 
@@ -953,6 +1056,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      * @see <a href="https://docs.github.com/en/rest/reference/repos#deployments">Deployments</a>
      */
     public static class Deployment extends GHEventPayload {
+
+        /**
+         * Create default Deployment instance
+         */
+        public Deployment() {
+        }
+
         private GHDeployment deployment;
 
         /**
@@ -999,6 +1109,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      * @see <a href="https://docs.github.com/en/rest/reference/repos#deployments">Deployments</a>
      */
     public static class DeploymentStatus extends GHEventPayload {
+
+        /**
+         * Create default DeploymentStatus instance
+         */
+        public DeploymentStatus() {
+        }
+
         private GHDeploymentStatus deploymentStatus;
         private GHDeployment deployment;
 
@@ -1068,6 +1185,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      * @see <a href="https://docs.github.com/en/rest/reference/repos#forks">Forks</a>
      */
     public static class Fork extends GHEventPayload {
+
+        /**
+         * Create default Fork instance
+         */
+        public Fork() {
+        }
+
         private GHRepository forkee;
 
         /**
@@ -1100,6 +1224,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      * event</a>
      */
     public static class Ping extends GHEventPayload {
+
+        /**
+         * Create default Ping instance
+         */
+        public Ping() {
+        }
+
     }
 
     /**
@@ -1109,6 +1240,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      *      public event</a>
      */
     public static class Public extends GHEventPayload {
+
+        /**
+         * Create default Public instance
+         */
+        public Public() {
+        }
+
     }
 
     /**
@@ -1118,6 +1256,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      *      event</a>
      */
     public static class Push extends GHEventPayload {
+
+        /**
+         * Create default Push instance
+         */
+        public Push() {
+        }
+
         private String head, before;
         private boolean created, deleted, forced;
         private String ref;
@@ -1250,6 +1395,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
          * The type Pusher.
          */
         public static class Pusher {
+
+            /**
+             * Create default Pusher instance
+             */
+            public Pusher() {
+            }
+
             private String name, email;
 
             /**
@@ -1299,6 +1451,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
          * Commit in a push. Note: sha is an alias for id.
          */
         public static class PushCommit {
+
+            /**
+             * Create default PushCommit instance
+             */
+            public PushCommit() {
+            }
+
             private GitUser author;
             private GitUser committer;
             private String url, sha, message, timestamp;
@@ -1412,6 +1571,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
     @SuppressFBWarnings(value = { "UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR", "NP_UNWRITTEN_FIELD" },
             justification = "Constructed by JSON deserialization")
     public static class Release extends GHEventPayload {
+
+        /**
+         * Create default Release instance
+         */
+        public Release() {
+        }
+
         private GHRelease release;
 
         /**
@@ -1445,6 +1611,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      * @see <a href="https://docs.github.com/en/rest/reference/repos">Repositories</a>
      */
     public static class Repository extends GHEventPayload {
+
+        /**
+         * Create default Repository instance
+         */
+        public Repository() {
+        }
+
         private GHRepositoryChanges changes;
 
         /**
@@ -1466,6 +1639,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      * @see <a href="https://docs.github.com/en/rest/reference/repos#statuses">Repository Statuses</a>
      */
     public static class Status extends GHEventPayload {
+
+        /**
+         * Create default Status instance
+         */
+        public Status() {
+        }
+
         private String context;
         private String description;
         private GHCommitState state;
@@ -1573,6 +1753,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      *      trigger workflows</a>
      */
     public static class WorkflowDispatch extends GHEventPayload {
+
+        /**
+         * Create default WorkflowDispatch instance
+         */
+        public WorkflowDispatch() {
+        }
+
         private Map<String, Object> inputs;
         private String ref;
         private String workflow;
@@ -1614,6 +1801,13 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      * @see <a href="https://docs.github.com/en/rest/reference/actions#workflow-runs">Actions Workflow Runs</a>
      */
     public static class WorkflowRun extends GHEventPayload {
+
+        /**
+         * Create default WorkflowRun instance
+         */
+        public WorkflowRun() {
+        }
+
         private GHWorkflowRun workflowRun;
         private GHWorkflow workflow;
 
@@ -1666,6 +1860,12 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      */
     public static class WorkflowJob extends GHEventPayload {
 
+        /**
+         * Create default WorkflowJob instance
+         */
+        public WorkflowJob() {
+        }
+
         private GHWorkflowJob workflowJob;
 
         /**
@@ -1704,6 +1904,12 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      */
     public static class Label extends GHEventPayload {
 
+        /**
+         * Create default Label instance
+         */
+        public Label() {
+        }
+
         private GHLabel label;
 
         private GHLabelChanges changes;
@@ -1738,6 +1944,12 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      */
     public static class Discussion extends GHEventPayload {
 
+        /**
+         * Create default Discussion instance
+         */
+        public Discussion() {
+        }
+
         private GHRepositoryDiscussion discussion;
 
         private GHLabel label;
@@ -1772,6 +1984,12 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      */
     public static class DiscussionComment extends GHEventPayload {
 
+        /**
+         * Create default DiscussionComment instance
+         */
+        public DiscussionComment() {
+        }
+
         private GHRepositoryDiscussion discussion;
 
         private GHRepositoryDiscussionComment comment;
@@ -1806,6 +2024,12 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      */
     public static class Star extends GHEventPayload {
 
+        /**
+         * Create default Star instance
+         */
+        public Star() {
+        }
+
         private String starredAt;
 
         /**
@@ -1827,6 +2051,12 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      */
     public static class ProjectsV2Item extends GHEventPayload {
 
+        /**
+         * Create default ProjectsV2Item instance
+         */
+        public ProjectsV2Item() {
+        }
+
         private GHProjectsV2Item projectsV2Item;
         private GHProjectsV2ItemChanges changes;
 
@@ -1857,6 +2087,12 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      */
     public static class TeamAdd extends GHEventPayload {
 
+        /**
+         * Create default TeamAdd instance
+         */
+        public TeamAdd() {
+        }
+
         private GHTeam team;
 
         /**
@@ -1894,6 +2130,12 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      */
     public static class Team extends GHEventPayload {
 
+        /**
+         * Create default Team instance
+         */
+        public Team() {
+        }
+
         private GHTeam team;
 
         private GHTeamChanges changes;
@@ -1942,6 +2184,12 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      */
     public static class Member extends GHEventPayload {
 
+        /**
+         * Create default Member instance
+         */
+        public Member() {
+        }
+
         private GHUser member;
 
         private GHMemberChanges changes;
@@ -1973,6 +2221,12 @@ public abstract class GHEventPayload extends GitHubInteractiveObject {
      */
     public static class Membership extends GHEventPayload {
 
+        /**
+         * Create default Membership instance
+         */
+        public Membership() {
+        }
+
         private GHTeam team;
 
         private GHUser member;
diff --git a/src/main/java/org/kohsuke/github/GHExternalGroup.java b/src/main/java/org/kohsuke/github/GHExternalGroup.java
index b5bba0f26..01d997b62 100644
--- a/src/main/java/org/kohsuke/github/GHExternalGroup.java
+++ b/src/main/java/org/kohsuke/github/GHExternalGroup.java
@@ -21,6 +21,12 @@ public class GHExternalGroup extends GitHubInteractiveObject implements Refresha
      */
     public static class GHLinkedTeam {
 
+        /**
+         * Create default GHLinkedTeam instance
+         */
+        public GHLinkedTeam() {
+        }
+
         /**
          * The identifier of the team
          */
@@ -58,6 +64,12 @@ public class GHExternalGroup extends GitHubInteractiveObject implements Refresha
      */
     public static class GHLinkedExternalMember {
 
+        /**
+         * Create default GHLinkedExternalMember instance
+         */
+        public GHLinkedExternalMember() {
+        }
+
         /**
          * The internal user ID of the identity
          */
diff --git a/src/main/java/org/kohsuke/github/GHGistFile.java b/src/main/java/org/kohsuke/github/GHGistFile.java
index 67237094d..8a4b8f48e 100644
--- a/src/main/java/org/kohsuke/github/GHGistFile.java
+++ b/src/main/java/org/kohsuke/github/GHGistFile.java
@@ -10,6 +10,12 @@ package org.kohsuke.github;
  */
 public class GHGistFile {
 
+    /**
+     * Create default GHGistFile instance
+     */
+    public GHGistFile() {
+    }
+
     /** The file name. */
     /* package almost final */ String fileName;
 
diff --git a/src/main/java/org/kohsuke/github/GHHook.java b/src/main/java/org/kohsuke/github/GHHook.java
index 08f2b9e79..345f1f8e6 100644
--- a/src/main/java/org/kohsuke/github/GHHook.java
+++ b/src/main/java/org/kohsuke/github/GHHook.java
@@ -20,6 +20,12 @@ import java.util.Map;
         justification = "JSON API")
 public abstract class GHHook extends GHObject {
 
+    /**
+     * Create default GHHook instance
+     */
+    public GHHook() {
+    }
+
     /** The name. */
     String name;
 
diff --git a/src/main/java/org/kohsuke/github/GHInvitation.java b/src/main/java/org/kohsuke/github/GHInvitation.java
index 4985bb9c1..d32ea0b51 100644
--- a/src/main/java/org/kohsuke/github/GHInvitation.java
+++ b/src/main/java/org/kohsuke/github/GHInvitation.java
@@ -18,6 +18,12 @@ import java.net.URL;
         justification = "JSON API")
 public class GHInvitation extends GHObject {
 
+    /**
+     * Create default GHInvitation instance
+     */
+    public GHInvitation() {
+    }
+
     private int id;
     private GHRepository repository;
     private GHUser invitee, inviter;
diff --git a/src/main/java/org/kohsuke/github/GHIssue.java b/src/main/java/org/kohsuke/github/GHIssue.java
index 2adeb20b1..7083b12e6 100644
--- a/src/main/java/org/kohsuke/github/GHIssue.java
+++ b/src/main/java/org/kohsuke/github/GHIssue.java
@@ -53,6 +53,13 @@ import java.util.Objects;
  * @see GHIssueSearchBuilder
  */
 public class GHIssue extends GHObject implements Reactable {
+
+    /**
+     * Create default GHIssue instance
+     */
+    public GHIssue() {
+    }
+
     private static final String ASSIGNEES = "assignees";
 
     /** The owner. */
@@ -821,6 +828,13 @@ public class GHIssue extends GHObject implements Reactable {
      */
     @SuppressFBWarnings(value = { "UWF_UNWRITTEN_FIELD" }, justification = "JSON API")
     public static class PullRequest {
+
+        /**
+         * Create default PullRequest instance
+         */
+        public PullRequest() {
+        }
+
         private String diff_url, patch_url, html_url;
 
         /**
diff --git a/src/main/java/org/kohsuke/github/GHIssueChanges.java b/src/main/java/org/kohsuke/github/GHIssueChanges.java
index 41d948cda..d47b8cdcc 100644
--- a/src/main/java/org/kohsuke/github/GHIssueChanges.java
+++ b/src/main/java/org/kohsuke/github/GHIssueChanges.java
@@ -11,6 +11,12 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 @SuppressFBWarnings("UWF_UNWRITTEN_FIELD")
 public class GHIssueChanges {
 
+    /**
+     * Create default GHIssueChanges instance
+     */
+    public GHIssueChanges() {
+    }
+
     private GHFrom title;
     private GHFrom body;
 
@@ -36,6 +42,13 @@ public class GHIssueChanges {
      * Wrapper for changed values.
      */
     public static class GHFrom {
+
+        /**
+         * Create default GHFrom instance
+         */
+        public GHFrom() {
+        }
+
         private String from;
 
         /**
diff --git a/src/main/java/org/kohsuke/github/GHIssueComment.java b/src/main/java/org/kohsuke/github/GHIssueComment.java
index 013cd5f85..b38a7b50a 100644
--- a/src/main/java/org/kohsuke/github/GHIssueComment.java
+++ b/src/main/java/org/kohsuke/github/GHIssueComment.java
@@ -38,6 +38,12 @@ import java.net.URL;
  */
 public class GHIssueComment extends GHObject implements Reactable {
 
+    /**
+     * Create default GHIssueComment instance
+     */
+    public GHIssueComment() {
+    }
+
     /** The owner. */
     GHIssue owner;
 
diff --git a/src/main/java/org/kohsuke/github/GHIssueEvent.java b/src/main/java/org/kohsuke/github/GHIssueEvent.java
index 6026e43ad..726a59098 100644
--- a/src/main/java/org/kohsuke/github/GHIssueEvent.java
+++ b/src/main/java/org/kohsuke/github/GHIssueEvent.java
@@ -12,6 +12,13 @@ import java.util.Date;
  * @see <a href="https://developer.github.com/v3/issues/events/">Github documentation for issue events</a>
  */
 public class GHIssueEvent extends GitHubInteractiveObject {
+
+    /**
+     * Create default GHIssueEvent instance
+     */
+    public GHIssueEvent() {
+    }
+
     private long id;
     private String node_id;
     private String url;
diff --git a/src/main/java/org/kohsuke/github/GHIssueRename.java b/src/main/java/org/kohsuke/github/GHIssueRename.java
index e1bcf0211..cd20c86a1 100644
--- a/src/main/java/org/kohsuke/github/GHIssueRename.java
+++ b/src/main/java/org/kohsuke/github/GHIssueRename.java
@@ -9,6 +9,13 @@ package org.kohsuke.github;
  *      documentation for renamed event</a>
  */
 public class GHIssueRename {
+
+    /**
+     * Create default GHIssueRename instance
+     */
+    public GHIssueRename() {
+    }
+
     private String from = "";
     private String to = "";
 
diff --git a/src/main/java/org/kohsuke/github/GHKey.java b/src/main/java/org/kohsuke/github/GHKey.java
index 01c73819b..d0e90a203 100644
--- a/src/main/java/org/kohsuke/github/GHKey.java
+++ b/src/main/java/org/kohsuke/github/GHKey.java
@@ -14,6 +14,12 @@ import java.io.IOException;
 @SuppressFBWarnings(value = "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", justification = "JSON API")
 public class GHKey extends GitHubInteractiveObject {
 
+    /**
+     * Create default GHKey instance
+     */
+    public GHKey() {
+    }
+
     /** The title. */
     protected String url, key, title;
 
diff --git a/src/main/java/org/kohsuke/github/GHLabel.java b/src/main/java/org/kohsuke/github/GHLabel.java
index 46c5af206..ac8ca3ce4 100644
--- a/src/main/java/org/kohsuke/github/GHLabel.java
+++ b/src/main/java/org/kohsuke/github/GHLabel.java
@@ -278,7 +278,7 @@ public class GHLabel extends GitHubInteractiveObject {
     /**
      * A {@link GHLabelBuilder} that updates a single property per request
      *
-     * {@link #done()} is called automatically after the property is set.
+     * {@link Setter#done()} is called automatically after the property is set.
      */
     @BetaApi
     public static class Setter extends GHLabelBuilder<GHLabel> {
@@ -291,7 +291,7 @@ public class GHLabel extends GitHubInteractiveObject {
     /**
      * A {@link GHLabelBuilder} that allows multiple properties to be updated per request.
      *
-     * Consumer must call {@link #done()} to commit changes.
+     * Consumer must call {@link Updater#done()} to commit changes.
      */
     @BetaApi
     public static class Updater extends GHLabelBuilder<Updater> {
@@ -304,7 +304,7 @@ public class GHLabel extends GitHubInteractiveObject {
     /**
      * A {@link GHLabelBuilder} that creates a new {@link GHLabel}
      *
-     * Consumer must call {@link #done()} to create the new instance.
+     * Consumer must call {@link Creator#done()} to create the new instance.
      */
     @BetaApi
     public static class Creator extends GHLabelBuilder<Creator> {
diff --git a/src/main/java/org/kohsuke/github/GHLabelChanges.java b/src/main/java/org/kohsuke/github/GHLabelChanges.java
index 7048acd93..a3880dcbf 100644
--- a/src/main/java/org/kohsuke/github/GHLabelChanges.java
+++ b/src/main/java/org/kohsuke/github/GHLabelChanges.java
@@ -11,6 +11,12 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 @SuppressFBWarnings("UWF_UNWRITTEN_FIELD")
 public class GHLabelChanges {
 
+    /**
+     * Create default GHLabelChanges instance
+     */
+    public GHLabelChanges() {
+    }
+
     private GHFrom name;
     private GHFrom color;
 
@@ -36,6 +42,13 @@ public class GHLabelChanges {
      * Wrapper for changed values.
      */
     public static class GHFrom {
+
+        /**
+         * Create default GHFrom instance
+         */
+        public GHFrom() {
+        }
+
         private String from;
 
         /**
diff --git a/src/main/java/org/kohsuke/github/GHLicense.java b/src/main/java/org/kohsuke/github/GHLicense.java
index be9bb48fd..9a66ad3a9 100644
--- a/src/main/java/org/kohsuke/github/GHLicense.java
+++ b/src/main/java/org/kohsuke/github/GHLicense.java
@@ -47,6 +47,12 @@ import java.util.Objects;
         justification = "JSON API")
 public class GHLicense extends GHObject {
 
+    /**
+     * Create default GHLicense instance
+     */
+    public GHLicense() {
+    }
+
     /** The name. */
     // these fields are always present, even in the short form
     protected String key, name, spdxId;
diff --git a/src/main/java/org/kohsuke/github/GHMarketplaceAccount.java b/src/main/java/org/kohsuke/github/GHMarketplaceAccount.java
index 19a71b68f..df0261e88 100644
--- a/src/main/java/org/kohsuke/github/GHMarketplaceAccount.java
+++ b/src/main/java/org/kohsuke/github/GHMarketplaceAccount.java
@@ -12,6 +12,13 @@ import java.net.URL;
  * @see GHMarketplaceListAccountBuilder#createRequest()
  */
 public class GHMarketplaceAccount extends GitHubInteractiveObject {
+
+    /**
+     * Create default GHMarketplaceAccount instance
+     */
+    public GHMarketplaceAccount() {
+    }
+
     private String url;
     private long id;
     private String login;
diff --git a/src/main/java/org/kohsuke/github/GHMarketplaceAccountPlan.java b/src/main/java/org/kohsuke/github/GHMarketplaceAccountPlan.java
index b2df88e8d..c780aa4dd 100644
--- a/src/main/java/org/kohsuke/github/GHMarketplaceAccountPlan.java
+++ b/src/main/java/org/kohsuke/github/GHMarketplaceAccountPlan.java
@@ -11,6 +11,12 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
  */
 public class GHMarketplaceAccountPlan extends GHMarketplaceAccount {
 
+    /**
+     * Create default GHMarketplaceAccountPlan instance
+     */
+    public GHMarketplaceAccountPlan() {
+    }
+
     @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Field comes from JSON deserialization")
     private GHMarketplacePendingChange marketplacePendingChange;
     @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Field comes from JSON deserialization")
diff --git a/src/main/java/org/kohsuke/github/GHMarketplacePendingChange.java b/src/main/java/org/kohsuke/github/GHMarketplacePendingChange.java
index d8bb2ebc3..d91e6e541 100644
--- a/src/main/java/org/kohsuke/github/GHMarketplacePendingChange.java
+++ b/src/main/java/org/kohsuke/github/GHMarketplacePendingChange.java
@@ -12,6 +12,13 @@ import java.util.Date;
  * @see GHMarketplaceListAccountBuilder#createRequest()
  */
 public class GHMarketplacePendingChange extends GitHubInteractiveObject {
+
+    /**
+     * Create default GHMarketplacePendingChange instance
+     */
+    public GHMarketplacePendingChange() {
+    }
+
     private long id;
     @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Field comes from JSON deserialization")
     private Long unitCount;
diff --git a/src/main/java/org/kohsuke/github/GHMarketplacePlan.java b/src/main/java/org/kohsuke/github/GHMarketplacePlan.java
index 95a405bfa..43bcfe3be 100644
--- a/src/main/java/org/kohsuke/github/GHMarketplacePlan.java
+++ b/src/main/java/org/kohsuke/github/GHMarketplacePlan.java
@@ -14,6 +14,13 @@ import java.util.List;
  * @see GitHub#listMarketplacePlans()
  */
 public class GHMarketplacePlan extends GitHubInteractiveObject {
+
+    /**
+     * Create default GHMarketplacePlan instance
+     */
+    public GHMarketplacePlan() {
+    }
+
     private String url;
     private String accountsUrl;
     private long id;
diff --git a/src/main/java/org/kohsuke/github/GHMarketplacePurchase.java b/src/main/java/org/kohsuke/github/GHMarketplacePurchase.java
index f4de6c42e..a0c149e15 100644
--- a/src/main/java/org/kohsuke/github/GHMarketplacePurchase.java
+++ b/src/main/java/org/kohsuke/github/GHMarketplacePurchase.java
@@ -13,6 +13,12 @@ import java.util.Date;
  */
 public class GHMarketplacePurchase extends GitHubInteractiveObject {
 
+    /**
+     * Create default GHMarketplacePurchase instance
+     */
+    public GHMarketplacePurchase() {
+    }
+
     private String billingCycle;
     private String nextBillingDate;
     private boolean onFreeTrial;
diff --git a/src/main/java/org/kohsuke/github/GHMarketplaceUserPurchase.java b/src/main/java/org/kohsuke/github/GHMarketplaceUserPurchase.java
index 8802f5a8f..fb2b21051 100644
--- a/src/main/java/org/kohsuke/github/GHMarketplaceUserPurchase.java
+++ b/src/main/java/org/kohsuke/github/GHMarketplaceUserPurchase.java
@@ -12,6 +12,13 @@ import java.util.Date;
  * @see GitHub#getMyMarketplacePurchases()
  */
 public class GHMarketplaceUserPurchase extends GitHubInteractiveObject {
+
+    /**
+     * Create default GHMarketplaceUserPurchase instance
+     */
+    public GHMarketplaceUserPurchase() {
+    }
+
     private String billingCycle;
     private String nextBillingDate;
     private boolean onFreeTrial;
diff --git a/src/main/java/org/kohsuke/github/GHMemberChanges.java b/src/main/java/org/kohsuke/github/GHMemberChanges.java
index 6de93c5dc..376de0fa5 100644
--- a/src/main/java/org/kohsuke/github/GHMemberChanges.java
+++ b/src/main/java/org/kohsuke/github/GHMemberChanges.java
@@ -10,6 +10,12 @@ import org.kohsuke.github.internal.EnumUtils;
 @SuppressFBWarnings(value = { "UWF_UNWRITTEN_FIELD" }, justification = "JSON API")
 public class GHMemberChanges {
 
+    /**
+     * Create default GHMemberChanges instance
+     */
+    public GHMemberChanges() {
+    }
+
     private FromToPermission permission;
 
     private FromRoleName roleName;
@@ -40,6 +46,12 @@ public class GHMemberChanges {
      */
     public static class FromToPermission {
 
+        /**
+         * Create default FromToPermission instance
+         */
+        public FromToPermission() {
+        }
+
         private String from;
 
         private String to;
@@ -86,6 +98,12 @@ public class GHMemberChanges {
      */
     public static class FromRoleName {
 
+        /**
+         * Create default FromRoleName instance
+         */
+        public FromRoleName() {
+        }
+
         private String to;
 
         /**
diff --git a/src/main/java/org/kohsuke/github/GHMembership.java b/src/main/java/org/kohsuke/github/GHMembership.java
index a4cca63f5..e6b7e2e09 100644
--- a/src/main/java/org/kohsuke/github/GHMembership.java
+++ b/src/main/java/org/kohsuke/github/GHMembership.java
@@ -17,6 +17,12 @@ import java.util.Locale;
         justification = "JSON API")
 public class GHMembership extends GitHubInteractiveObject {
 
+    /**
+     * Create default GHMembership instance
+     */
+    public GHMembership() {
+    }
+
     /** The url. */
     String url;
 
diff --git a/src/main/java/org/kohsuke/github/GHMeta.java b/src/main/java/org/kohsuke/github/GHMeta.java
index 7d667f87c..bfa900f7e 100644
--- a/src/main/java/org/kohsuke/github/GHMeta.java
+++ b/src/main/java/org/kohsuke/github/GHMeta.java
@@ -16,6 +16,12 @@ import java.util.List;
  */
 public class GHMeta {
 
+    /**
+     * Create default GHMeta instance
+     */
+    public GHMeta() {
+    }
+
     @JsonProperty("verifiable_password_authentication")
     private boolean verifiablePasswordAuthentication;
     private List<String> hooks;
diff --git a/src/main/java/org/kohsuke/github/GHMilestone.java b/src/main/java/org/kohsuke/github/GHMilestone.java
index 0bb7481a1..8528661f5 100644
--- a/src/main/java/org/kohsuke/github/GHMilestone.java
+++ b/src/main/java/org/kohsuke/github/GHMilestone.java
@@ -15,6 +15,12 @@ import java.util.Locale;
  */
 public class GHMilestone extends GHObject {
 
+    /**
+     * Create default GHMilestone instance
+     */
+    public GHMilestone() {
+    }
+
     /** The owner. */
     GHRepository owner;
 
diff --git a/src/main/java/org/kohsuke/github/GHMyself.java b/src/main/java/org/kohsuke/github/GHMyself.java
index 43914f2bd..a4a695b4a 100644
--- a/src/main/java/org/kohsuke/github/GHMyself.java
+++ b/src/main/java/org/kohsuke/github/GHMyself.java
@@ -1,13 +1,13 @@
 package org.kohsuke.github;
 
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
+import java.util.stream.Collectors;
 
 // TODO: Auto-generated Javadoc
 /**
@@ -17,6 +17,12 @@ import java.util.TreeMap;
  */
 public class GHMyself extends GHUser {
 
+    /**
+     * Create default GHMyself instance
+     */
+    public GHMyself() {
+    }
+
     /**
      * Type of repositories returned during listing.
      */
@@ -44,15 +50,11 @@ public class GHMyself extends GHUser {
      * @return the emails
      * @throws IOException
      *             the io exception
-     * @deprecated Use {@link #getEmails2()}
+     * @deprecated Use {@link #listEmails()}
      */
+    @Deprecated
     public List<String> getEmails() throws IOException {
-        List<GHEmail> src = getEmails2();
-        List<String> r = new ArrayList<String>(src.size());
-        for (GHEmail e : src) {
-            r.add(e.getEmail());
-        }
-        return r;
+        return getEmails2().stream().map(email -> email.getEmail()).collect(Collectors.toList());
     }
 
     /**
@@ -65,8 +67,21 @@ public class GHMyself extends GHUser {
      * @throws IOException
      *             the io exception
      */
+    @Deprecated
     public List<GHEmail> getEmails2() throws IOException {
-        return root().createRequest().withUrlPath("/user/emails").toIterable(GHEmail[].class, null).toList();
+        return listEmails().toList();
+    }
+
+    /**
+     * Returns the read-only list of e-mail addresses configured for you.
+     * <p>
+     * This corresponds to the stuff you configure in https://github.com/settings/emails, and not to be confused with
+     * {@link #getEmail()} that shows your public e-mail address set in https://github.com/settings/profile
+     *
+     * @return Always non-null.
+     */
+    public PagedIterable<GHEmail> listEmails() {
+        return root().createRequest().withUrlPath("/user/emails").toIterable(GHEmail[].class, null);
     }
 
     /**
diff --git a/src/main/java/org/kohsuke/github/GHOTPRequiredException.java b/src/main/java/org/kohsuke/github/GHOTPRequiredException.java
index b577d3784..dd12d2fca 100644
--- a/src/main/java/org/kohsuke/github/GHOTPRequiredException.java
+++ b/src/main/java/org/kohsuke/github/GHOTPRequiredException.java
@@ -6,5 +6,12 @@ package org.kohsuke.github;
  * @author Kevin Harrington mad.hephaestus@gmail.com
  */
 public class GHOTPRequiredException extends GHIOException {
+
+    /**
+     * Create default GHOTPRequiredException instance
+     */
+    public GHOTPRequiredException() {
+    }
+
     // ...
 }
diff --git a/src/main/java/org/kohsuke/github/GHOrganization.java b/src/main/java/org/kohsuke/github/GHOrganization.java
index ee5f84334..d843e99a5 100644
--- a/src/main/java/org/kohsuke/github/GHOrganization.java
+++ b/src/main/java/org/kohsuke/github/GHOrganization.java
@@ -13,6 +13,12 @@ import java.util.*;
  */
 public class GHOrganization extends GHPerson {
 
+    /**
+     * Create default GHOrganization instance
+     */
+    public GHOrganization() {
+    }
+
     private boolean has_organization_projects;
 
     /**
diff --git a/src/main/java/org/kohsuke/github/GHPerson.java b/src/main/java/org/kohsuke/github/GHPerson.java
index addcebfea..d77546f8e 100644
--- a/src/main/java/org/kohsuke/github/GHPerson.java
+++ b/src/main/java/org/kohsuke/github/GHPerson.java
@@ -19,6 +19,12 @@ import java.util.TreeMap;
  */
 public abstract class GHPerson extends GHObject {
 
+    /**
+     * Create default GHPerson instance
+     */
+    public GHPerson() {
+    }
+
     /** The avatar url. */
     // core data fields that exist even for "small" user data (such as the user info in pull request)
     protected String login, avatar_url;
diff --git a/src/main/java/org/kohsuke/github/GHProject.java b/src/main/java/org/kohsuke/github/GHProject.java
index e86115add..82ec47fd5 100644
--- a/src/main/java/org/kohsuke/github/GHProject.java
+++ b/src/main/java/org/kohsuke/github/GHProject.java
@@ -39,6 +39,12 @@ import java.util.Locale;
  */
 public class GHProject extends GHObject {
 
+    /**
+     * Create default GHProject instance
+     */
+    public GHProject() {
+    }
+
     /** The owner. */
     protected GHObject owner;
 
diff --git a/src/main/java/org/kohsuke/github/GHProjectCard.java b/src/main/java/org/kohsuke/github/GHProjectCard.java
index 45da83d70..7361df947 100644
--- a/src/main/java/org/kohsuke/github/GHProjectCard.java
+++ b/src/main/java/org/kohsuke/github/GHProjectCard.java
@@ -14,6 +14,13 @@ import java.net.URL;
  * @author Gunnar Skjold
  */
 public class GHProjectCard extends GHObject {
+
+    /**
+     * Create default GHProjectCard instance
+     */
+    public GHProjectCard() {
+    }
+
     private GHProject project;
     private GHProjectColumn column;
 
diff --git a/src/main/java/org/kohsuke/github/GHProjectColumn.java b/src/main/java/org/kohsuke/github/GHProjectColumn.java
index f05cc4f75..63aa83c9a 100644
--- a/src/main/java/org/kohsuke/github/GHProjectColumn.java
+++ b/src/main/java/org/kohsuke/github/GHProjectColumn.java
@@ -14,6 +14,12 @@ import java.net.URL;
  */
 public class GHProjectColumn extends GHObject {
 
+    /**
+     * Create default GHProjectColumn instance
+     */
+    public GHProjectColumn() {
+    }
+
     /** The project. */
     protected GHProject project;
 
diff --git a/src/main/java/org/kohsuke/github/GHProjectsV2Item.java b/src/main/java/org/kohsuke/github/GHProjectsV2Item.java
index ea6c7006b..43d022448 100644
--- a/src/main/java/org/kohsuke/github/GHProjectsV2Item.java
+++ b/src/main/java/org/kohsuke/github/GHProjectsV2Item.java
@@ -23,6 +23,12 @@ import java.util.Date;
  */
 public class GHProjectsV2Item extends GHObject {
 
+    /**
+     * Create default GHProjectsV2Item instance
+     */
+    public GHProjectsV2Item() {
+    }
+
     private String projectNodeId;
     private String contentNodeId;
     private String contentType;
diff --git a/src/main/java/org/kohsuke/github/GHProjectsV2ItemChanges.java b/src/main/java/org/kohsuke/github/GHProjectsV2ItemChanges.java
index 2e96fa4c2..d9636537e 100644
--- a/src/main/java/org/kohsuke/github/GHProjectsV2ItemChanges.java
+++ b/src/main/java/org/kohsuke/github/GHProjectsV2ItemChanges.java
@@ -14,6 +14,12 @@ import java.util.Date;
 @SuppressFBWarnings(value = { "UWF_UNWRITTEN_FIELD" }, justification = "JSON API")
 public class GHProjectsV2ItemChanges {
 
+    /**
+     * Create default GHProjectsV2ItemChanges instance
+     */
+    public GHProjectsV2ItemChanges() {
+    }
+
     private FieldValue fieldValue;
 
     private FromToDate archivedAt;
@@ -52,6 +58,12 @@ public class GHProjectsV2ItemChanges {
      */
     public static class FieldValue {
 
+        /**
+         * Create default FieldValue instance
+         */
+        public FieldValue() {
+        }
+
         private String fieldNodeId;
         private String fieldType;
 
@@ -79,6 +91,12 @@ public class GHProjectsV2ItemChanges {
      */
     public static class FromTo {
 
+        /**
+         * Create default FromTo instance
+         */
+        public FromTo() {
+        }
+
         private String from;
         private String to;
 
@@ -106,6 +124,12 @@ public class GHProjectsV2ItemChanges {
      */
     public static class FromToDate {
 
+        /**
+         * Create default FromToDate instance
+         */
+        public FromToDate() {
+        }
+
         private String from;
         private String to;
 
diff --git a/src/main/java/org/kohsuke/github/GHPullRequest.java b/src/main/java/org/kohsuke/github/GHPullRequest.java
index 4d6e30fc0..d7a2ea500 100644
--- a/src/main/java/org/kohsuke/github/GHPullRequest.java
+++ b/src/main/java/org/kohsuke/github/GHPullRequest.java
@@ -47,6 +47,12 @@ import javax.annotation.CheckForNull;
 @SuppressWarnings({ "UnusedDeclaration" })
 public class GHPullRequest extends GHIssue implements Refreshable {
 
+    /**
+     * Create default GHPullRequest instance
+     */
+    public GHPullRequest() {
+    }
+
     private static final String COMMENTS_ACTION = "/comments";
     private static final String REQUEST_REVIEWERS = "/requested_reviewers";
 
@@ -695,6 +701,12 @@ public class GHPullRequest extends GHIssue implements Refreshable {
     @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Field comes from JSON deserialization")
     public static class AutoMerge {
 
+        /**
+         * Create default AutoMerge instance
+         */
+        public AutoMerge() {
+        }
+
         private GHUser enabled_by;
         private MergeMethod merge_method;
         private String commit_title;
diff --git a/src/main/java/org/kohsuke/github/GHPullRequestChanges.java b/src/main/java/org/kohsuke/github/GHPullRequestChanges.java
index 24dde41a0..a866b33b3 100644
--- a/src/main/java/org/kohsuke/github/GHPullRequestChanges.java
+++ b/src/main/java/org/kohsuke/github/GHPullRequestChanges.java
@@ -11,6 +11,12 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 @SuppressFBWarnings("UWF_UNWRITTEN_FIELD")
 public class GHPullRequestChanges {
 
+    /**
+     * Create default GHPullRequestChanges instance
+     */
+    public GHPullRequestChanges() {
+    }
+
     private GHCommitPointer base;
     private GHFrom title;
     private GHFrom body;
@@ -48,6 +54,13 @@ public class GHPullRequestChanges {
      * @see org.kohsuke.github.GHCommitPointer
      */
     public static class GHCommitPointer {
+
+        /**
+         * Create default GHCommitPointer instance
+         */
+        public GHCommitPointer() {
+        }
+
         private GHFrom ref;
         private GHFrom sha;
 
@@ -75,6 +88,13 @@ public class GHPullRequestChanges {
      * Wrapper for changed values.
      */
     public static class GHFrom {
+
+        /**
+         * Create default GHFrom instance
+         */
+        public GHFrom() {
+        }
+
         private String from;
 
         /**
diff --git a/src/main/java/org/kohsuke/github/GHPullRequestCommitDetail.java b/src/main/java/org/kohsuke/github/GHPullRequestCommitDetail.java
index c3faccbfa..3a3da61e8 100644
--- a/src/main/java/org/kohsuke/github/GHPullRequestCommitDetail.java
+++ b/src/main/java/org/kohsuke/github/GHPullRequestCommitDetail.java
@@ -40,6 +40,13 @@ import java.net.URL;
                 "URF_UNREAD_FIELD" },
         justification = "JSON API")
 public class GHPullRequestCommitDetail {
+
+    /**
+     * Create default GHPullRequestCommitDetail instance
+     */
+    public GHPullRequestCommitDetail() {
+    }
+
     private GHPullRequest owner;
 
     /**
@@ -58,6 +65,11 @@ public class GHPullRequestCommitDetail {
      * @deprecated Use {@link GitUser}
      */
     public static class Authorship extends GitUser {
+        /**
+         * Create default Authorship instance
+         */
+        public Authorship() {
+        }
     }
 
     /**
@@ -65,6 +77,12 @@ public class GHPullRequestCommitDetail {
      */
     public static class Tree {
 
+        /**
+         * Create default Tree instance
+         */
+        public Tree() {
+        }
+
         /** The sha. */
         String sha;
 
@@ -95,6 +113,12 @@ public class GHPullRequestCommitDetail {
      */
     public static class Commit {
 
+        /**
+         * Create default Commit instance
+         */
+        public Commit() {
+        }
+
         /** The author. */
         Authorship author;
 
@@ -175,6 +199,12 @@ public class GHPullRequestCommitDetail {
      */
     public static class CommitPointer {
 
+        /**
+         * Create default CommitPointer instance
+         */
+        public CommitPointer() {
+        }
+
         /** The sha. */
         String sha;
 
diff --git a/src/main/java/org/kohsuke/github/GHPullRequestFileDetail.java b/src/main/java/org/kohsuke/github/GHPullRequestFileDetail.java
index ba6e89d32..2a316f49e 100644
--- a/src/main/java/org/kohsuke/github/GHPullRequestFileDetail.java
+++ b/src/main/java/org/kohsuke/github/GHPullRequestFileDetail.java
@@ -35,6 +35,12 @@ import java.net.URL;
  */
 public class GHPullRequestFileDetail {
 
+    /**
+     * Create default GHPullRequestFileDetail instance
+     */
+    public GHPullRequestFileDetail() {
+    }
+
     /** The sha. */
     String sha;
 
diff --git a/src/main/java/org/kohsuke/github/GHPullRequestReview.java b/src/main/java/org/kohsuke/github/GHPullRequestReview.java
index a72f462f1..a0d05aaf9 100644
--- a/src/main/java/org/kohsuke/github/GHPullRequestReview.java
+++ b/src/main/java/org/kohsuke/github/GHPullRequestReview.java
@@ -41,6 +41,12 @@ import javax.annotation.CheckForNull;
 @SuppressFBWarnings(value = { "UWF_UNWRITTEN_FIELD" }, justification = "JSON API")
 public class GHPullRequestReview extends GHObject {
 
+    /**
+     * Create default GHPullRequestReview instance
+     */
+    public GHPullRequestReview() {
+    }
+
     /** The owner. */
     GHPullRequest owner;
 
diff --git a/src/main/java/org/kohsuke/github/GHPullRequestReviewComment.java b/src/main/java/org/kohsuke/github/GHPullRequestReviewComment.java
index c59d7acf8..ce52d2962 100644
--- a/src/main/java/org/kohsuke/github/GHPullRequestReviewComment.java
+++ b/src/main/java/org/kohsuke/github/GHPullRequestReviewComment.java
@@ -42,6 +42,12 @@ import javax.annotation.CheckForNull;
  */
 public class GHPullRequestReviewComment extends GHObject implements Reactable {
 
+    /**
+     * Create default GHPullRequestReviewComment instance
+     */
+    public GHPullRequestReviewComment() {
+    }
+
     /** The owner. */
     GHPullRequest owner;
 
diff --git a/src/main/java/org/kohsuke/github/GHPullRequestReviewCommentReactions.java b/src/main/java/org/kohsuke/github/GHPullRequestReviewCommentReactions.java
index bd90cec86..8a9624d69 100644
--- a/src/main/java/org/kohsuke/github/GHPullRequestReviewCommentReactions.java
+++ b/src/main/java/org/kohsuke/github/GHPullRequestReviewCommentReactions.java
@@ -14,6 +14,12 @@ import java.net.URL;
  */
 public class GHPullRequestReviewCommentReactions {
 
+    /**
+     * Create default GHPullRequestReviewCommentReactions instance
+     */
+    public GHPullRequestReviewCommentReactions() {
+    }
+
     private String url;
 
     private int total_count = -1;
diff --git a/src/main/java/org/kohsuke/github/GHReaction.java b/src/main/java/org/kohsuke/github/GHReaction.java
index 6a0cadcbc..759504fbb 100644
--- a/src/main/java/org/kohsuke/github/GHReaction.java
+++ b/src/main/java/org/kohsuke/github/GHReaction.java
@@ -14,6 +14,12 @@ import java.net.URL;
  */
 public class GHReaction extends GHObject {
 
+    /**
+     * Create default GHReaction instance
+     */
+    public GHReaction() {
+    }
+
     private GHUser user;
     private ReactionContent content;
 
diff --git a/src/main/java/org/kohsuke/github/GHRef.java b/src/main/java/org/kohsuke/github/GHRef.java
index 429dcfbf0..4db5e1c67 100644
--- a/src/main/java/org/kohsuke/github/GHRef.java
+++ b/src/main/java/org/kohsuke/github/GHRef.java
@@ -13,6 +13,13 @@ import java.net.URL;
  * @author Michael Clarke
  */
 public class GHRef extends GitHubInteractiveObject {
+
+    /**
+     * Create default GHRef instance
+     */
+    public GHRef() {
+    }
+
     private String ref, url;
     private GHObject object;
 
@@ -161,6 +168,13 @@ public class GHRef extends GitHubInteractiveObject {
             value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
             justification = "JSON API")
     public static class GHObject {
+
+        /**
+         * Create default GHObject instance
+         */
+        public GHObject() {
+        }
+
         private String type, sha, url;
 
         /**
diff --git a/src/main/java/org/kohsuke/github/GHRelease.java b/src/main/java/org/kohsuke/github/GHRelease.java
index 712255c01..24579eb0b 100644
--- a/src/main/java/org/kohsuke/github/GHRelease.java
+++ b/src/main/java/org/kohsuke/github/GHRelease.java
@@ -24,6 +24,12 @@ import static java.lang.String.*;
  */
 public class GHRelease extends GHObject {
 
+    /**
+     * Create default GHRelease instance
+     */
+    public GHRelease() {
+    }
+
     /** The owner. */
     GHRepository owner;
 
diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java
index d13a3c7cd..aeb4db5b1 100644
--- a/src/main/java/org/kohsuke/github/GHRepository.java
+++ b/src/main/java/org/kohsuke/github/GHRepository.java
@@ -73,6 +73,12 @@ import static java.util.Objects.requireNonNull;
         justification = "JSON API")
 public class GHRepository extends GHObject {
 
+    /**
+     * Create default GHRepository instance
+     */
+    public GHRepository() {
+    }
+
     private String nodeId, description, homepage, name, full_name;
 
     private String html_url; // this is the UI
@@ -3084,6 +3090,13 @@ public class GHRepository extends GHObject {
      * The type Contributor.
      */
     public static class Contributor extends GHUser {
+
+        /**
+         * Create default Contributor instance
+         */
+        public Contributor() {
+        }
+
         private int contributions;
 
         /**
diff --git a/src/main/java/org/kohsuke/github/GHRepositoryChanges.java b/src/main/java/org/kohsuke/github/GHRepositoryChanges.java
index 9c9aa578d..c3792f181 100644
--- a/src/main/java/org/kohsuke/github/GHRepositoryChanges.java
+++ b/src/main/java/org/kohsuke/github/GHRepositoryChanges.java
@@ -7,6 +7,13 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
  */
 @SuppressFBWarnings(value = { "UWF_UNWRITTEN_FIELD" }, justification = "JSON API")
 public class GHRepositoryChanges {
+
+    /**
+     * Create default GHRepositoryChanges instance
+     */
+    public GHRepositoryChanges() {
+    }
+
     private FromRepository repository;
     private Owner owner;
 
@@ -23,6 +30,13 @@ public class GHRepositoryChanges {
      * Outer object of owner from whom this repository was transferred.
      */
     public static class Owner {
+
+        /**
+         * Create default Owner instance
+         */
+        public Owner() {
+        }
+
         private FromOwner from;
 
         /**
@@ -39,6 +53,13 @@ public class GHRepositoryChanges {
      * Owner from whom this repository was transferred.
      */
     public static class FromOwner {
+
+        /**
+         * Create default FromOwner instance
+         */
+        public FromOwner() {
+        }
+
         private GHUser user;
         private GHOrganization organization;
 
@@ -76,6 +97,13 @@ public class GHRepositoryChanges {
      * Repository object from which the name was changed.
      */
     public static class FromRepository {
+
+        /**
+         * Create default FromRepository instance
+         */
+        public FromRepository() {
+        }
+
         private FromName name;
 
         /**
@@ -92,6 +120,13 @@ public class GHRepositoryChanges {
      * Repository name that was changed.
      */
     public static class FromName {
+
+        /**
+         * Create default FromName instance
+         */
+        public FromName() {
+        }
+
         private String from;
 
         /**
diff --git a/src/main/java/org/kohsuke/github/GHRepositoryDiscussion.java b/src/main/java/org/kohsuke/github/GHRepositoryDiscussion.java
index 39033d0a9..2c1bc4b27 100644
--- a/src/main/java/org/kohsuke/github/GHRepositoryDiscussion.java
+++ b/src/main/java/org/kohsuke/github/GHRepositoryDiscussion.java
@@ -22,6 +22,12 @@ import java.util.Date;
  */
 public class GHRepositoryDiscussion extends GHObject {
 
+    /**
+     * Create default GHRepositoryDiscussion instance
+     */
+    public GHRepositoryDiscussion() {
+    }
+
     private Category category;
 
     private String answerHtmlUrl;
@@ -192,6 +198,12 @@ public class GHRepositoryDiscussion extends GHObject {
      */
     public static class Category {
 
+        /**
+         * Create default Category instance
+         */
+        public Category() {
+        }
+
         private long id;
         private String nodeId;
         private long repositoryId;
diff --git a/src/main/java/org/kohsuke/github/GHRepositoryDiscussionComment.java b/src/main/java/org/kohsuke/github/GHRepositoryDiscussionComment.java
index e2dd60471..b16f61a98 100644
--- a/src/main/java/org/kohsuke/github/GHRepositoryDiscussionComment.java
+++ b/src/main/java/org/kohsuke/github/GHRepositoryDiscussionComment.java
@@ -18,6 +18,12 @@ import java.net.URL;
  */
 public class GHRepositoryDiscussionComment extends GHObject {
 
+    /**
+     * Create default GHRepositoryDiscussionComment instance
+     */
+    public GHRepositoryDiscussionComment() {
+    }
+
     private String htmlUrl;
 
     private Long parentId;
diff --git a/src/main/java/org/kohsuke/github/GHRepositoryPublicKey.java b/src/main/java/org/kohsuke/github/GHRepositoryPublicKey.java
index 9d7ab86c7..f596ab359 100644
--- a/src/main/java/org/kohsuke/github/GHRepositoryPublicKey.java
+++ b/src/main/java/org/kohsuke/github/GHRepositoryPublicKey.java
@@ -12,6 +12,13 @@ import java.net.URL;
  * @author Aditya Bansal
  */
 public class GHRepositoryPublicKey extends GHObject {
+
+    /**
+     * Create default GHRepositoryPublicKey instance
+     */
+    public GHRepositoryPublicKey() {
+    }
+
     // Not provided by the API.
     @JsonIgnore
     private GHRepository owner;
diff --git a/src/main/java/org/kohsuke/github/GHRepositoryRule.java b/src/main/java/org/kohsuke/github/GHRepositoryRule.java
index 0c1b9c5d5..2db05c705 100644
--- a/src/main/java/org/kohsuke/github/GHRepositoryRule.java
+++ b/src/main/java/org/kohsuke/github/GHRepositoryRule.java
@@ -16,6 +16,13 @@ import java.util.Optional;
 @SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
         justification = "JSON API")
 public class GHRepositoryRule extends GitHubInteractiveObject {
+
+    /**
+     * Create default GHRepositoryRule instance
+     */
+    public GHRepositoryRule() {
+    }
+
     private String type;
     private String rulesetSourceType;
     private String rulesetSource;
@@ -424,6 +431,13 @@ public class GHRepositoryRule extends GitHubInteractiveObject {
      * Status check configuration parameter.
      */
     public static class StatusCheckConfiguration {
+
+        /**
+         * Create default StatusCheckConfiguration instance
+         */
+        public StatusCheckConfiguration() {
+        }
+
         private String context;
         private Integer integrationId;
 
@@ -475,6 +489,13 @@ public class GHRepositoryRule extends GitHubInteractiveObject {
      * Workflow file reference parameter.
      */
     public static class WorkflowFileReference {
+
+        /**
+         * Create default WorkflowFileReference instance
+         */
+        public WorkflowFileReference() {
+        }
+
         private String path;
         private String ref;
         private long repositoryId;
@@ -521,6 +542,13 @@ public class GHRepositoryRule extends GitHubInteractiveObject {
      * Code scanning tool parameter.
      */
     public static class CodeScanningTool {
+
+        /**
+         * Create default CodeScanningTool instance
+         */
+        public CodeScanningTool() {
+        }
+
         private AlertsThreshold alertsThreshold;
         private SecurityAlertsThreshold securityAlertsThreshold;
         private String tool;
diff --git a/src/main/java/org/kohsuke/github/GHRepositoryStatistics.java b/src/main/java/org/kohsuke/github/GHRepositoryStatistics.java
index 35c8bfea5..8b686f62f 100644
--- a/src/main/java/org/kohsuke/github/GHRepositoryStatistics.java
+++ b/src/main/java/org/kohsuke/github/GHRepositoryStatistics.java
@@ -99,6 +99,13 @@ public class GHRepositoryStatistics extends GitHubInteractiveObject {
                     "URF_UNREAD_FIELD" },
             justification = "JSON API")
     public static class ContributorStats extends GHObject {
+
+        /**
+         * Create default ContributorStats instance
+         */
+        public ContributorStats() {
+        }
+
         private GHUser author;
         private int total;
         private List<Week> weeks;
@@ -184,6 +191,12 @@ public class GHRepositoryStatistics extends GitHubInteractiveObject {
                 justification = "JSON API")
         public static class Week {
 
+            /**
+             * Create default Week instance
+             */
+            public Week() {
+            }
+
             private long w;
             private int a;
             private int d;
@@ -258,6 +271,13 @@ public class GHRepositoryStatistics extends GitHubInteractiveObject {
             value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
             justification = "JSON API")
     public static class CommitActivity extends GHObject {
+
+        /**
+         * Create default CommitActivity instance
+         */
+        public CommitActivity() {
+        }
+
         private List<Integer> days;
         private int total;
         private long week;
@@ -398,6 +418,13 @@ public class GHRepositoryStatistics extends GitHubInteractiveObject {
      * The type Participation.
      */
     public static class Participation extends GHObject {
+
+        /**
+         * Create default Participation instance
+         */
+        public Participation() {
+        }
+
         private List<Integer> all;
         private List<Integer> owner;
 
diff --git a/src/main/java/org/kohsuke/github/GHRepositoryVariable.java b/src/main/java/org/kohsuke/github/GHRepositoryVariable.java
index cc71f38a4..6a45c6cf9 100644
--- a/src/main/java/org/kohsuke/github/GHRepositoryVariable.java
+++ b/src/main/java/org/kohsuke/github/GHRepositoryVariable.java
@@ -12,6 +12,12 @@ import javax.annotation.Nonnull;
  */
 public class GHRepositoryVariable extends GitHubInteractiveObject {
 
+    /**
+     * Create default GHRepositoryVariable instance
+     */
+    public GHRepositoryVariable() {
+    }
+
     private static final String SLASH = "/";
 
     private static final String VARIABLE_NAMESPACE = "actions/variables";
diff --git a/src/main/java/org/kohsuke/github/GHRequestedAction.java b/src/main/java/org/kohsuke/github/GHRequestedAction.java
index db87a833b..2e1f44a2e 100644
--- a/src/main/java/org/kohsuke/github/GHRequestedAction.java
+++ b/src/main/java/org/kohsuke/github/GHRequestedAction.java
@@ -11,6 +11,13 @@ import java.net.URL;
 @SuppressFBWarnings(value = { "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD", "URF_UNREAD_FIELD" },
         justification = "JSON API")
 public class GHRequestedAction extends GHObject {
+
+    /**
+     * Create default GHRequestedAction instance
+     */
+    public GHRequestedAction() {
+    }
+
     private GHRepository owner;
     private String identifier;
     private String label;
diff --git a/src/main/java/org/kohsuke/github/GHStargazer.java b/src/main/java/org/kohsuke/github/GHStargazer.java
index ff6327d31..1b9862295 100644
--- a/src/main/java/org/kohsuke/github/GHStargazer.java
+++ b/src/main/java/org/kohsuke/github/GHStargazer.java
@@ -13,6 +13,12 @@ import java.util.Date;
 @SuppressFBWarnings(value = { "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" }, justification = "JSON API")
 public class GHStargazer {
 
+    /**
+     * Create default GHStargazer instance
+     */
+    public GHStargazer() {
+    }
+
     private GHRepository repository;
     private String starred_at;
     private GHUser user;
diff --git a/src/main/java/org/kohsuke/github/GHSubscription.java b/src/main/java/org/kohsuke/github/GHSubscription.java
index 9f84161cc..1066d51b7 100644
--- a/src/main/java/org/kohsuke/github/GHSubscription.java
+++ b/src/main/java/org/kohsuke/github/GHSubscription.java
@@ -14,6 +14,13 @@ import java.util.Date;
  * @see GHThread#getSubscription() GHThread#getSubscription()
  */
 public class GHSubscription extends GitHubInteractiveObject {
+
+    /**
+     * Create default GHSubscription instance
+     */
+    public GHSubscription() {
+    }
+
     private String created_at, url, repository_url, reason;
     private boolean subscribed, ignored;
 
diff --git a/src/main/java/org/kohsuke/github/GHTag.java b/src/main/java/org/kohsuke/github/GHTag.java
index b40c49133..1487256d2 100644
--- a/src/main/java/org/kohsuke/github/GHTag.java
+++ b/src/main/java/org/kohsuke/github/GHTag.java
@@ -11,6 +11,13 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 @SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
         justification = "JSON API")
 public class GHTag extends GitHubInteractiveObject {
+
+    /**
+     * Create default GHTag instance
+     */
+    public GHTag() {
+    }
+
     private GHRepository owner;
 
     private String name;
diff --git a/src/main/java/org/kohsuke/github/GHTagObject.java b/src/main/java/org/kohsuke/github/GHTagObject.java
index efd38a391..fbf255e7c 100644
--- a/src/main/java/org/kohsuke/github/GHTagObject.java
+++ b/src/main/java/org/kohsuke/github/GHTagObject.java
@@ -11,6 +11,13 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 @SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
         justification = "JSON API")
 public class GHTagObject extends GitHubInteractiveObject {
+
+    /**
+     * Create default GHTagObject instance
+     */
+    public GHTagObject() {
+    }
+
     private GHRepository owner;
 
     private String tag;
diff --git a/src/main/java/org/kohsuke/github/GHTeam.java b/src/main/java/org/kohsuke/github/GHTeam.java
index 4d94735ae..d24d8fbdb 100644
--- a/src/main/java/org/kohsuke/github/GHTeam.java
+++ b/src/main/java/org/kohsuke/github/GHTeam.java
@@ -20,6 +20,12 @@ import static org.kohsuke.github.GitHubRequest.transformEnum;
  */
 public class GHTeam extends GHObject implements Refreshable {
 
+    /**
+     * Create default GHTeam instance
+     */
+    public GHTeam() {
+    }
+
     /**
      * Path for external group-related operations
      */
diff --git a/src/main/java/org/kohsuke/github/GHTeamChanges.java b/src/main/java/org/kohsuke/github/GHTeamChanges.java
index dfcbfca26..30962bd3b 100644
--- a/src/main/java/org/kohsuke/github/GHTeamChanges.java
+++ b/src/main/java/org/kohsuke/github/GHTeamChanges.java
@@ -14,6 +14,12 @@ import org.kohsuke.github.internal.EnumUtils;
 @SuppressFBWarnings(value = { "UWF_UNWRITTEN_FIELD" }, justification = "JSON API")
 public class GHTeamChanges {
 
+    /**
+     * Create default GHTeamChanges instance
+     */
+    public GHTeamChanges() {
+    }
+
     private FromString description;
     private FromString name;
     private FromPrivacy privacy;
@@ -60,6 +66,12 @@ public class GHTeamChanges {
      */
     public static class FromString {
 
+        /**
+         * Create default FromString instance
+         */
+        public FromString() {
+        }
+
         private String from;
 
         /**
@@ -77,6 +89,12 @@ public class GHTeamChanges {
      */
     public static class FromPrivacy {
 
+        /**
+         * Create default FromPrivacy instance
+         */
+        public FromPrivacy() {
+        }
+
         private String from;
 
         /**
@@ -94,6 +112,12 @@ public class GHTeamChanges {
      */
     public static class FromRepository {
 
+        /**
+         * Create default FromRepository instance
+         */
+        public FromRepository() {
+        }
+
         private FromRepositoryPermissions permissions;
 
         /**
@@ -111,6 +135,12 @@ public class GHTeamChanges {
      */
     public static class FromRepositoryPermissions {
 
+        /**
+         * Create default FromRepositoryPermissions instance
+         */
+        public FromRepositoryPermissions() {
+        }
+
         private GHRepoPermission from;
 
         /**
diff --git a/src/main/java/org/kohsuke/github/GHTree.java b/src/main/java/org/kohsuke/github/GHTree.java
index 11f35cee4..867fa4531 100644
--- a/src/main/java/org/kohsuke/github/GHTree.java
+++ b/src/main/java/org/kohsuke/github/GHTree.java
@@ -20,6 +20,12 @@ import java.util.List;
         justification = "JSON API")
 public class GHTree {
 
+    /**
+     * Create default GHTree instance
+     */
+    public GHTree() {
+    }
+
     /** The repo. */
     /* package almost final */GHRepository repo;
 
diff --git a/src/main/java/org/kohsuke/github/GHTreeEntry.java b/src/main/java/org/kohsuke/github/GHTreeEntry.java
index 4941365f3..6759378e1 100644
--- a/src/main/java/org/kohsuke/github/GHTreeEntry.java
+++ b/src/main/java/org/kohsuke/github/GHTreeEntry.java
@@ -13,6 +13,12 @@ import java.net.URL;
  */
 public class GHTreeEntry {
 
+    /**
+     * Create default GHTreeEntry instance
+     */
+    public GHTreeEntry() {
+    }
+
     /** The tree. */
     /* package almost final */GHTree tree;
 
diff --git a/src/main/java/org/kohsuke/github/GHUser.java b/src/main/java/org/kohsuke/github/GHUser.java
index dc25a3fd5..58c9471f1 100644
--- a/src/main/java/org/kohsuke/github/GHUser.java
+++ b/src/main/java/org/kohsuke/github/GHUser.java
@@ -36,6 +36,12 @@ import java.util.*;
  */
 public class GHUser extends GHPerson {
 
+    /**
+     * Create default GHUser instance
+     */
+    public GHUser() {
+    }
+
     /** The ldap dn. */
     protected String ldap_dn;
 
diff --git a/src/main/java/org/kohsuke/github/GHVerification.java b/src/main/java/org/kohsuke/github/GHVerification.java
index 2a759ea5a..6fb5493e8 100644
--- a/src/main/java/org/kohsuke/github/GHVerification.java
+++ b/src/main/java/org/kohsuke/github/GHVerification.java
@@ -16,6 +16,13 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 @SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
         justification = "JSON API")
 public class GHVerification {
+
+    /**
+     * Create default GHVerification instance
+     */
+    public GHVerification() {
+    }
+
     private String signature, payload;
     private boolean verified;
     private Reason reason;
diff --git a/src/main/java/org/kohsuke/github/GHWorkflow.java b/src/main/java/org/kohsuke/github/GHWorkflow.java
index b016e5d6b..f5072ae32 100644
--- a/src/main/java/org/kohsuke/github/GHWorkflow.java
+++ b/src/main/java/org/kohsuke/github/GHWorkflow.java
@@ -19,6 +19,12 @@ import java.util.Objects;
  */
 public class GHWorkflow extends GHObject {
 
+    /**
+     * Create default GHWorkflow instance
+     */
+    public GHWorkflow() {
+    }
+
     // Not provided by the API.
     @JsonIgnore
     private GHRepository owner;
diff --git a/src/main/java/org/kohsuke/github/GHWorkflowJob.java b/src/main/java/org/kohsuke/github/GHWorkflowJob.java
index 82a487d72..080c60afb 100644
--- a/src/main/java/org/kohsuke/github/GHWorkflowJob.java
+++ b/src/main/java/org/kohsuke/github/GHWorkflowJob.java
@@ -25,6 +25,12 @@ import static java.util.Objects.requireNonNull;
  */
 public class GHWorkflowJob extends GHObject {
 
+    /**
+     * Create default GHWorkflowJob instance
+     */
+    public GHWorkflowJob() {
+    }
+
     // Not provided by the API.
     @JsonIgnore
     private GHRepository owner;
@@ -259,6 +265,12 @@ public class GHWorkflowJob extends GHObject {
      */
     public static class Step {
 
+        /**
+         * Create default Step instance
+         */
+        public Step() {
+        }
+
         private String name;
         private int number;
 
diff --git a/src/main/java/org/kohsuke/github/GHWorkflowRun.java b/src/main/java/org/kohsuke/github/GHWorkflowRun.java
index b12e8f005..03ee257a6 100644
--- a/src/main/java/org/kohsuke/github/GHWorkflowRun.java
+++ b/src/main/java/org/kohsuke/github/GHWorkflowRun.java
@@ -26,6 +26,12 @@ import static java.util.Objects.requireNonNull;
  */
 public class GHWorkflowRun extends GHObject {
 
+    /**
+     * Create default GHWorkflowRun instance
+     */
+    public GHWorkflowRun() {
+    }
+
     @JsonProperty("repository")
     private GHRepository owner;
 
@@ -429,6 +435,13 @@ public class GHWorkflowRun extends GHObject {
      * The Class HeadCommit.
      */
     public static class HeadCommit {
+
+        /**
+         * Create default HeadCommit instance
+         */
+        public HeadCommit() {
+        }
+
         private String id;
         private String treeId;
         private String message;
diff --git a/src/main/java/org/kohsuke/github/GitHubAbuseLimitHandler.java b/src/main/java/org/kohsuke/github/GitHubAbuseLimitHandler.java
index e76960452..076f6fcc1 100644
--- a/src/main/java/org/kohsuke/github/GitHubAbuseLimitHandler.java
+++ b/src/main/java/org/kohsuke/github/GitHubAbuseLimitHandler.java
@@ -18,6 +18,12 @@ import javax.annotation.Nonnull;
  */
 public abstract class GitHubAbuseLimitHandler extends GitHubConnectorResponseErrorHandler {
 
+    /**
+     * Create default GitHubAbuseLimitHandler instance
+     */
+    public GitHubAbuseLimitHandler() {
+    }
+
     /**
      * Checks if is error.
      *
diff --git a/src/main/java/org/kohsuke/github/GitHubInteractiveObject.java b/src/main/java/org/kohsuke/github/GitHubInteractiveObject.java
index 036b53f7c..9528f9f98 100644
--- a/src/main/java/org/kohsuke/github/GitHubInteractiveObject.java
+++ b/src/main/java/org/kohsuke/github/GitHubInteractiveObject.java
@@ -7,7 +7,6 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 
 import java.util.Objects;
 
-// TODO: Auto-generated Javadoc
 /**
  * Defines a base class that all classes in this library that interact with GitHub inherit from.
  *
diff --git a/src/main/java/org/kohsuke/github/GitHubRateLimitHandler.java b/src/main/java/org/kohsuke/github/GitHubRateLimitHandler.java
index da4f6ad10..0af46e8e5 100644
--- a/src/main/java/org/kohsuke/github/GitHubRateLimitHandler.java
+++ b/src/main/java/org/kohsuke/github/GitHubRateLimitHandler.java
@@ -19,6 +19,12 @@ import javax.annotation.Nonnull;
  */
 public abstract class GitHubRateLimitHandler extends GitHubConnectorResponseErrorHandler {
 
+    /**
+     * Create default GitHubRateLimitHandler instance
+     */
+    public GitHubRateLimitHandler() {
+    }
+
     /**
      * Checks if is error.
      *
diff --git a/src/main/java/org/kohsuke/github/GitHubRequestBuilderDone.java b/src/main/java/org/kohsuke/github/GitHubRequestBuilderDone.java
new file mode 100644
index 000000000..2ace9de44
--- /dev/null
+++ b/src/main/java/org/kohsuke/github/GitHubRequestBuilderDone.java
@@ -0,0 +1,42 @@
+package org.kohsuke.github;
+
+import java.io.IOException;
+
+/**
+ * The done method for data object builder/updater.
+ *
+ * This interface can be used to make a Builder that supports both batch and single property changes.
+ * <p>
+ * Batching looks like this:
+ * </p>
+ *
+ * <pre>
+ * update().someName(value).otherName(value).done()
+ * </pre>
+ * <p>
+ * Single changes look like this:
+ * </p>
+ *
+ * <pre>
+ * set().someName(value);
+ * set().otherName(value);
+ * </pre>
+ *
+ * @author Liam Newman
+ * @param <R>
+ *            Final return type built by this builder returned when {@link #done()}} is called.
+ */
+public interface GitHubRequestBuilderDone<R> {
+
+    /**
+     * Finishes a create or update request, committing changes.
+     *
+     * This method may update-in-place or not. Either way it returns the resulting instance.
+     *
+     * @return an instance with updated current data
+     * @throws IOException
+     *             if there is an I/O Exception
+     */
+    @BetaApi
+    R done() throws IOException;
+}
diff --git a/src/main/java/org/kohsuke/github/PagedIterable.java b/src/main/java/org/kohsuke/github/PagedIterable.java
index fc3528492..122be5cef 100644
--- a/src/main/java/org/kohsuke/github/PagedIterable.java
+++ b/src/main/java/org/kohsuke/github/PagedIterable.java
@@ -26,6 +26,12 @@ public abstract class PagedIterable<T> implements Iterable<T> {
      */
     private int pageSize = 0;
 
+    /**
+     * Instantiate a PagedIterable.
+     */
+    public PagedIterable() {
+    }
+
     /**
      * Sets the pagination size.
      *
diff --git a/src/main/java/org/kohsuke/github/RateLimitChecker.java b/src/main/java/org/kohsuke/github/RateLimitChecker.java
index fbfdabd93..5b848cd17 100644
--- a/src/main/java/org/kohsuke/github/RateLimitChecker.java
+++ b/src/main/java/org/kohsuke/github/RateLimitChecker.java
@@ -22,6 +22,12 @@ import java.util.logging.Logger;
  */
 public abstract class RateLimitChecker {
 
+    /**
+     * Create default RateLimitChecker instance
+     */
+    public RateLimitChecker() {
+    }
+
     private static final Logger LOGGER = Logger.getLogger(RateLimitChecker.class.getName());
 
     /** The Constant NONE. */
diff --git a/src/main/java/org/kohsuke/github/RateLimitHandler.java b/src/main/java/org/kohsuke/github/RateLimitHandler.java
index a17e9a33b..bc22b43d5 100644
--- a/src/main/java/org/kohsuke/github/RateLimitHandler.java
+++ b/src/main/java/org/kohsuke/github/RateLimitHandler.java
@@ -21,6 +21,12 @@ import javax.annotation.Nonnull;
 @Deprecated
 public abstract class RateLimitHandler extends GitHubRateLimitHandler {
 
+    /**
+     * Create default RateLimitHandler instance
+     */
+    public RateLimitHandler() {
+    }
+
     /**
      * Called when the library encounters HTTP error indicating that the API rate limit has been exceeded.
      *
diff --git a/src/main/java/org/kohsuke/github/authorization/AnonymousAuthorizationProvider.java b/src/main/java/org/kohsuke/github/authorization/AnonymousAuthorizationProvider.java
index b71a42626..488be23e3 100644
--- a/src/main/java/org/kohsuke/github/authorization/AnonymousAuthorizationProvider.java
+++ b/src/main/java/org/kohsuke/github/authorization/AnonymousAuthorizationProvider.java
@@ -8,6 +8,13 @@ import java.io.IOException;
  * This will result in the "Authorization" header not being added to a request.
  */
 public class AnonymousAuthorizationProvider implements AuthorizationProvider {
+
+    /**
+     * Create default AnonymousAuthorizationProvider instance
+     */
+    public AnonymousAuthorizationProvider() {
+    }
+
     @Override
     public String getEncodedAuthorization() throws IOException {
         return null;
diff --git a/src/main/java/org/kohsuke/github/connector/GitHubConnector.java b/src/main/java/org/kohsuke/github/connector/GitHubConnector.java
index 63ffe9892..006023ac1 100644
--- a/src/main/java/org/kohsuke/github/connector/GitHubConnector.java
+++ b/src/main/java/org/kohsuke/github/connector/GitHubConnector.java
@@ -30,8 +30,6 @@ public interface GitHubConnector {
      * @return a GitHubConnectorResponse for the request
      * @throws IOException
      *             if there is an I/O error
-     *
-     * @author Liam Newman
      */
     GitHubConnectorResponse send(GitHubConnectorRequest connectorRequest) throws IOException;
 
diff --git a/src/main/java/org/kohsuke/github/example/dataobject/ReadOnlyObjects.java b/src/main/java/org/kohsuke/github/example/dataobject/ReadOnlyObjects.java
index fb6a517fd..d9b0f0e2a 100644
--- a/src/main/java/org/kohsuke/github/example/dataobject/ReadOnlyObjects.java
+++ b/src/main/java/org/kohsuke/github/example/dataobject/ReadOnlyObjects.java
@@ -31,6 +31,12 @@ import javax.annotation.Nonnull;
  */
 public final class ReadOnlyObjects {
 
+    /**
+     * Placeholder constructor.
+     */
+    public ReadOnlyObjects() {
+    }
+
     /**
      * All GHMeta data objects should expose these values.
      *
@@ -108,6 +114,12 @@ public final class ReadOnlyObjects {
      */
     public static class GHMetaPublic implements GHMetaExample {
 
+        /**
+         * Create default GHMetaPublic instance
+         */
+        public GHMetaPublic() {
+        }
+
         @JsonProperty("verifiable_password_authentication")
         private boolean verifiablePasswordAuthentication;
         private List<String> hooks;
@@ -251,6 +263,12 @@ public final class ReadOnlyObjects {
      */
     public static class GHMetaPackage implements GHMetaExample {
 
+        /**
+         * Create default GHMetaPackage instance
+         */
+        public GHMetaPackage() {
+        }
+
         private boolean verifiablePasswordAuthentication;
         private List<String> hooks;
         private List<String> git;
@@ -388,6 +406,12 @@ public final class ReadOnlyObjects {
      */
     public static class GHMetaGettersUnmodifiable implements GHMetaExample {
 
+        /**
+         * Create default GHMetaGettersUnmodifiable instance
+         */
+        public GHMetaGettersUnmodifiable() {
+        }
+
         @JsonProperty("verifiable_password_authentication")
         private boolean verifiablePasswordAuthentication;
         private List<String> hooks;


Test patch:
diff --git a/src/test/java/org/kohsuke/HookApp.java b/src/test/java/org/kohsuke/HookApp.java
index 1b67eb67a..0eea23af0 100644
--- a/src/test/java/org/kohsuke/HookApp.java
+++ b/src/test/java/org/kohsuke/HookApp.java
@@ -17,6 +17,12 @@ import java.io.StringReader;
  */
 public class HookApp {
 
+    /**
+     * Create default HookApp instance
+     */
+    public HookApp() {
+    }
+
     /**
      * The main method.
      *
diff --git a/src/test/java/org/kohsuke/github/AbstractGitHubWireMockTest.java b/src/test/java/org/kohsuke/github/AbstractGitHubWireMockTest.java
index 044a7122e..c3f5e9352 100644
--- a/src/test/java/org/kohsuke/github/AbstractGitHubWireMockTest.java
+++ b/src/test/java/org/kohsuke/github/AbstractGitHubWireMockTest.java
@@ -11,7 +11,6 @@ import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
-import org.kohsuke.github.junit.GitHubWireMockRule;
 import wiremock.com.github.jknack.handlebars.Helper;
 import wiremock.com.github.jknack.handlebars.Options;
 
@@ -399,6 +398,12 @@ public abstract class AbstractGitHubWireMockTest {
         /** The test start date. */
         public Date testStartDate = new Date();
 
+        /**
+         * Instantiate TemplatingHelper
+         */
+        public TemplatingHelper() {
+        }
+
         /**
          * New response transformer.
          *
diff --git a/src/test/java/org/kohsuke/github/AbuseLimitHandlerTest.java b/src/test/java/org/kohsuke/github/AbuseLimitHandlerTest.java
index 5736146c4..4eb5aa463 100644
--- a/src/test/java/org/kohsuke/github/AbuseLimitHandlerTest.java
+++ b/src/test/java/org/kohsuke/github/AbuseLimitHandlerTest.java
@@ -15,7 +15,6 @@ import java.util.Date;
 import java.util.Map;
 
 import static org.hamcrest.CoreMatchers.*;
-import static org.hamcrest.CoreMatchers.notNullValue;
 import static org.hamcrest.Matchers.greaterThan;
 import static org.hamcrest.core.IsInstanceOf.instanceOf;
 
@@ -71,127 +70,121 @@ public class AbuseLimitHandlerTest extends AbstractGitHubWireMockTest {
         snapshotNotAllowed();
         final HttpURLConnection[] savedConnection = new HttpURLConnection[1];
 
-        gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl())
-                .withAbuseLimitHandler(new AbuseLimitHandler() {
-                    @Override
-                    public void onError(IOException e, HttpURLConnection uc) throws IOException {
-                        savedConnection[0] = uc;
-                        // Verify
-                        assertThat(uc.getDate(), Matchers.greaterThanOrEqualTo(new Date().getTime() - 10000));
-                        assertThat(uc.getExpiration(), equalTo(0L));
-                        assertThat(uc.getIfModifiedSince(), equalTo(0L));
-                        assertThat(uc.getLastModified(), equalTo(1581014017000L));
-                        assertThat(uc.getRequestMethod(), equalTo("GET"));
-                        assertThat(uc.getResponseCode(), equalTo(403));
-                        assertThat(uc.getResponseMessage(), containsString("Forbidden"));
-                        assertThat(uc.getURL().toString(), endsWith("/repos/hub4j-test-org/temp-testHandler_Fail"));
-                        assertThat(uc.getHeaderFieldInt("X-RateLimit-Limit", 10), equalTo(5000));
-                        assertThat(uc.getHeaderFieldInt("X-RateLimit-Remaining", 10), equalTo(4000));
-                        assertThat(uc.getHeaderFieldInt("X-Foo", 20), equalTo(20));
-                        assertThat(uc.getHeaderFieldLong("X-RateLimit-Limit", 15L), equalTo(5000L));
-                        assertThat(uc.getHeaderFieldLong("X-RateLimit-Remaining", 15L), equalTo(4000L));
-                        assertThat(uc.getHeaderFieldLong("X-Foo", 20L), equalTo(20L));
-
-                        assertThat(uc.getContentEncoding(), nullValue());
-                        assertThat(uc.getContentType(), equalTo("application/json; charset=utf-8"));
-                        assertThat(uc.getContentLength(), equalTo(-1));
-
-                        // getting an input stream in an error case should throw
-                        IOException ioEx = Assert.assertThrows(IOException.class, () -> uc.getInputStream());
-
-                        checkErrorMessageMatches(uc, "Must have push access to repository");
-
-                        // calling again should still error
-                        ioEx = Assert.assertThrows(IOException.class, () -> uc.getInputStream());
-
-                        // calling again on a GitHubConnectorResponse should yield the same value
-                        if (uc.toString().contains("GitHubConnectorResponseHttpUrlConnectionAdapter")) {
-                            checkErrorMessageMatches(uc, "Must have push access to repository");
-                        } else {
-                            try (InputStream errorStream = uc.getErrorStream()) {
-                                assertThat(errorStream, notNullValue());
-                                String errorString = IOUtils.toString(errorStream, StandardCharsets.UTF_8);
-                                fail();
-                            } catch (IOException ex) {
-                                assertThat(ex, notNullValue());
-                                assertThat(ex.getMessage(), containsString("stream is closed"));
-                            }
-                        }
-
-                        assertThat(uc.getHeaderFields(), instanceOf(Map.class));
-                        assertThat(uc.getHeaderFields().size(), greaterThan(25));
-                        assertThat(uc.getHeaderField("Status"), equalTo("403 Forbidden"));
-
-                        String key = uc.getHeaderFieldKey(1);
-                        assertThat(key, notNullValue());
-                        assertThat(uc.getHeaderField(1), notNullValue());
-                        assertThat(uc.getHeaderField(1), equalTo(uc.getHeaderField(key)));
-
-                        assertThat(uc.getRequestProperty("Accept"), equalTo("application/vnd.github+json"));
-
-                        Assert.assertThrows(IllegalStateException.class, () -> uc.getRequestProperties());
-
-                        // Actions that are not allowed because connection already opened.
-                        Assert.assertThrows(IllegalStateException.class, () -> uc.addRequestProperty("bogus", "item"));
-
-                        Assert.assertThrows(IllegalStateException.class, () -> uc.setAllowUserInteraction(true));
-                        Assert.assertThrows(IllegalStateException.class, () -> uc.setChunkedStreamingMode(1));
-                        Assert.assertThrows(IllegalStateException.class, () -> uc.setDoInput(true));
-                        Assert.assertThrows(IllegalStateException.class, () -> uc.setDoOutput(true));
-                        Assert.assertThrows(IllegalStateException.class, () -> uc.setFixedLengthStreamingMode(1));
-                        Assert.assertThrows(IllegalStateException.class, () -> uc.setFixedLengthStreamingMode(1L));
-                        Assert.assertThrows(IllegalStateException.class, () -> uc.setIfModifiedSince(1L));
-                        Assert.assertThrows(IllegalStateException.class, () -> uc.setRequestProperty("bogus", "thing"));
-                        Assert.assertThrows(IllegalStateException.class, () -> uc.setUseCaches(true));
-
-                        if (uc.toString().contains("GitHubConnectorResponseHttpUrlConnectionAdapter")) {
-
-                            Assert.assertThrows(UnsupportedOperationException.class,
-                                    () -> uc.getAllowUserInteraction());
-                            Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getConnectTimeout());
-                            Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getContent());
-                            Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getContent(null));
-                            Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getDefaultUseCaches());
-                            Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getDoInput());
-                            Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getDoOutput());
-                            Assert.assertThrows(UnsupportedOperationException.class,
-                                    () -> uc.getInstanceFollowRedirects());
-                            Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getOutputStream());
-                            Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getPermission());
-                            Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getReadTimeout());
-                            Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getUseCaches());
-                            Assert.assertThrows(UnsupportedOperationException.class, () -> uc.usingProxy());
-
-                            Assert.assertThrows(UnsupportedOperationException.class, () -> uc.setConnectTimeout(10));
-                            Assert.assertThrows(UnsupportedOperationException.class,
-                                    () -> uc.setDefaultUseCaches(true));
-
-                            Assert.assertThrows(UnsupportedOperationException.class,
-                                    () -> uc.setInstanceFollowRedirects(true));
-                            Assert.assertThrows(UnsupportedOperationException.class, () -> uc.setReadTimeout(10));
-                            Assert.assertThrows(ProtocolException.class, () -> uc.setRequestMethod("GET"));
-                        } else {
-                            uc.getDefaultUseCaches();
-                            assertThat(uc.getDoInput(), is(true));
-
-                            // Depending on the underlying implementation, this may throw or not
-                            // Assert.assertThrows(IllegalStateException.class, () -> uc.setRequestMethod("GET"));
-                        }
-
-                        // ignored
-                        uc.connect();
-
-                        // disconnect does nothing, never throws
-                        uc.disconnect();
-                        uc.disconnect();
-
-                        // ignored
-                        uc.connect();
-
-                        AbuseLimitHandler.FAIL.onError(e, uc);
+        gitHub = getGitHubWithAbuseLimitHandler(new TestAbuseLimitHandler() {
+            @Override
+            public void onError(IOException e, HttpURLConnection uc) throws IOException {
+                savedConnection[0] = uc;
+                // Verify
+                assertThat(uc.getDate(), Matchers.greaterThanOrEqualTo(new Date().getTime() - 10000));
+                assertThat(uc.getExpiration(), equalTo(0L));
+                assertThat(uc.getIfModifiedSince(), equalTo(0L));
+                assertThat(uc.getLastModified(), equalTo(1581014017000L));
+                assertThat(uc.getRequestMethod(), equalTo("GET"));
+                assertThat(uc.getResponseCode(), equalTo(403));
+                assertThat(uc.getResponseMessage(), containsString("Forbidden"));
+                assertThat(uc.getURL().toString(), endsWith("/repos/hub4j-test-org/temp-testHandler_Fail"));
+                assertThat(uc.getHeaderFieldInt("X-RateLimit-Limit", 10), equalTo(5000));
+                assertThat(uc.getHeaderFieldInt("X-RateLimit-Remaining", 10), equalTo(4000));
+                assertThat(uc.getHeaderFieldInt("X-Foo", 20), equalTo(20));
+                assertThat(uc.getHeaderFieldLong("X-RateLimit-Limit", 15L), equalTo(5000L));
+                assertThat(uc.getHeaderFieldLong("X-RateLimit-Remaining", 15L), equalTo(4000L));
+                assertThat(uc.getHeaderFieldLong("X-Foo", 20L), equalTo(20L));
+
+                assertThat(uc.getContentEncoding(), nullValue());
+                assertThat(uc.getContentType(), equalTo("application/json; charset=utf-8"));
+                assertThat(uc.getContentLength(), equalTo(-1));
+
+                // getting an input stream in an error case should throw
+                IOException ioEx = Assert.assertThrows(IOException.class, () -> uc.getInputStream());
+
+                checkErrorMessageMatches(uc, "Must have push access to repository");
+
+                // calling again should still error
+                ioEx = Assert.assertThrows(IOException.class, () -> uc.getInputStream());
+
+                // calling again on a GitHubConnectorResponse should yield the same value
+                if (uc.toString().contains("GitHubConnectorResponseHttpUrlConnectionAdapter")) {
+                    checkErrorMessageMatches(uc, "Must have push access to repository");
+                } else {
+                    try (InputStream errorStream = uc.getErrorStream()) {
+                        assertThat(errorStream, notNullValue());
+                        String errorString = IOUtils.toString(errorStream, StandardCharsets.UTF_8);
+                        fail();
+                    } catch (IOException ex) {
+                        assertThat(ex, notNullValue());
+                        assertThat(ex.getMessage(), containsString("stream is closed"));
                     }
-                })
-                .build();
+                }
+
+                assertThat(uc.getHeaderFields(), instanceOf(Map.class));
+                assertThat(uc.getHeaderFields().size(), greaterThan(25));
+                assertThat(uc.getHeaderField("Status"), equalTo("403 Forbidden"));
+
+                String key = uc.getHeaderFieldKey(1);
+                assertThat(key, notNullValue());
+                assertThat(uc.getHeaderField(1), notNullValue());
+                assertThat(uc.getHeaderField(1), equalTo(uc.getHeaderField(key)));
+
+                assertThat(uc.getRequestProperty("Accept"), equalTo("application/vnd.github+json"));
+
+                Assert.assertThrows(IllegalStateException.class, () -> uc.getRequestProperties());
+
+                // Actions that are not allowed because connection already opened.
+                Assert.assertThrows(IllegalStateException.class, () -> uc.addRequestProperty("bogus", "item"));
+
+                Assert.assertThrows(IllegalStateException.class, () -> uc.setAllowUserInteraction(true));
+                Assert.assertThrows(IllegalStateException.class, () -> uc.setChunkedStreamingMode(1));
+                Assert.assertThrows(IllegalStateException.class, () -> uc.setDoInput(true));
+                Assert.assertThrows(IllegalStateException.class, () -> uc.setDoOutput(true));
+                Assert.assertThrows(IllegalStateException.class, () -> uc.setFixedLengthStreamingMode(1));
+                Assert.assertThrows(IllegalStateException.class, () -> uc.setFixedLengthStreamingMode(1L));
+                Assert.assertThrows(IllegalStateException.class, () -> uc.setIfModifiedSince(1L));
+                Assert.assertThrows(IllegalStateException.class, () -> uc.setRequestProperty("bogus", "thing"));
+                Assert.assertThrows(IllegalStateException.class, () -> uc.setUseCaches(true));
+
+                if (uc.toString().contains("GitHubConnectorResponseHttpUrlConnectionAdapter")) {
+
+                    Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getAllowUserInteraction());
+                    Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getConnectTimeout());
+                    Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getContent());
+                    Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getContent(null));
+                    Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getDefaultUseCaches());
+                    Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getDoInput());
+                    Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getDoOutput());
+                    Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getInstanceFollowRedirects());
+                    Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getOutputStream());
+                    Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getPermission());
+                    Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getReadTimeout());
+                    Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getUseCaches());
+                    Assert.assertThrows(UnsupportedOperationException.class, () -> uc.usingProxy());
+
+                    Assert.assertThrows(UnsupportedOperationException.class, () -> uc.setConnectTimeout(10));
+                    Assert.assertThrows(UnsupportedOperationException.class, () -> uc.setDefaultUseCaches(true));
+
+                    Assert.assertThrows(UnsupportedOperationException.class, () -> uc.setInstanceFollowRedirects(true));
+                    Assert.assertThrows(UnsupportedOperationException.class, () -> uc.setReadTimeout(10));
+                    Assert.assertThrows(ProtocolException.class, () -> uc.setRequestMethod("GET"));
+                } else {
+                    uc.getDefaultUseCaches();
+                    assertThat(uc.getDoInput(), is(true));
+
+                    // Depending on the underlying implementation, this may throw or not
+                    // Assert.assertThrows(IllegalStateException.class, () -> uc.setRequestMethod("GET"));
+                }
+
+                // ignored
+                uc.connect();
+
+                // disconnect does nothing, never throws
+                uc.disconnect();
+                uc.disconnect();
+
+                // ignored
+                uc.connect();
+
+                AbuseLimitHandler.FAIL.onError(e, uc);
+            }
+        }).build();
 
         gitHub.getMyself();
         assertThat(mockGitHub.getRequestCount(), equalTo(1));
@@ -224,9 +217,7 @@ public class AbuseLimitHandlerTest extends AbstractGitHubWireMockTest {
         // Customized response that templates the date to keep things working
         snapshotNotAllowed();
 
-        gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl())
-                .withAbuseLimitHandler(AbuseLimitHandler.FAIL)
-                .build();
+        gitHub = getGitHubWithAbuseLimitHandler(AbuseLimitHandler.FAIL).build();
 
         gitHub.getMyself();
         assertThat(mockGitHub.getRequestCount(), equalTo(1));
@@ -257,9 +248,7 @@ public class AbuseLimitHandlerTest extends AbstractGitHubWireMockTest {
         // Customized response that templates the date to keep things working
         snapshotNotAllowed();
 
-        gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl())
-                .withAbuseLimitHandler(AbuseLimitHandler.WAIT)
-                .build();
+        gitHub = getGitHubWithAbuseLimitHandler(AbuseLimitHandler.WAIT).build();
 
         gitHub.getMyself();
         assertThat(mockGitHub.getRequestCount(), equalTo(1));
@@ -279,13 +268,11 @@ public class AbuseLimitHandlerTest extends AbstractGitHubWireMockTest {
         // Customized response that templates the date to keep things working
         snapshotNotAllowed();
 
-        gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl())
-                .withAbuseLimitHandler(new AbuseLimitHandler() {
-                    @Override
-                    public void onError(IOException e, HttpURLConnection uc) throws IOException {
-                    }
-                })
-                .build();
+        gitHub = getGitHubWithAbuseLimitHandler(new TestAbuseLimitHandler() {
+            @Override
+            public void onError(IOException e, HttpURLConnection uc) throws IOException {
+            }
+        }).build();
 
         gitHub.getMyself();
         assertThat(mockGitHub.getRequestCount(), equalTo(1));
@@ -312,56 +299,54 @@ public class AbuseLimitHandlerTest extends AbstractGitHubWireMockTest {
         // Customized response that templates the date to keep things working
         snapshotNotAllowed();
         final HttpURLConnection[] savedConnection = new HttpURLConnection[1];
-        gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl())
-                .withAbuseLimitHandler(new AbuseLimitHandler() {
-                    /**
-                     * Overriding method because the actual method will wait for one minute causing slowness in unit
-                     * tests
-                     */
-                    @Override
-                    public void onError(IOException e, HttpURLConnection uc) throws IOException {
-                        savedConnection[0] = uc;
-                        // Verify
-                        assertThat(uc.getDate(), Matchers.greaterThanOrEqualTo(new Date().getTime() - 10000));
-                        assertThat(uc.getExpiration(), equalTo(0L));
-                        assertThat(uc.getIfModifiedSince(), equalTo(0L));
-                        assertThat(uc.getLastModified(), equalTo(1581014017000L));
-                        assertThat(uc.getRequestMethod(), equalTo("GET"));
-                        assertThat(uc.getResponseCode(), equalTo(403));
-                        assertThat(uc.getResponseMessage(), containsString("Forbidden"));
-                        assertThat(uc.getURL().toString(),
-                                endsWith("/repos/hub4j-test-org/temp-testHandler_Wait_Secondary_Limits"));
-                        assertThat(uc.getHeaderFieldInt("X-RateLimit-Limit", 10), equalTo(5000));
-                        assertThat(uc.getHeaderFieldInt("X-RateLimit-Remaining", 10), equalTo(4000));
-                        assertThat(uc.getHeaderFieldInt("X-Foo", 20), equalTo(20));
-                        assertThat(uc.getHeaderFieldLong("X-RateLimit-Limit", 15L), equalTo(5000L));
-                        assertThat(uc.getHeaderFieldLong("X-RateLimit-Remaining", 15L), equalTo(4000L));
-                        assertThat(uc.getHeaderFieldLong("X-Foo", 20L), equalTo(20L));
-                        assertThat(uc.getHeaderField("gh-limited-by"), equalTo("search-elapsed-time-shared-grouped"));
-                        assertThat(uc.getContentEncoding(), nullValue());
-                        assertThat(uc.getContentType(), equalTo("application/json; charset=utf-8"));
-                        assertThat(uc.getContentLength(), equalTo(-1));
-                        assertThat(uc.getHeaderFields(), instanceOf(Map.class));
-                        assertThat(uc.getHeaderFields().size(), greaterThan(25));
-                        assertThat(uc.getHeaderField("Status"), equalTo("403 Forbidden"));
-
-                        checkErrorMessageMatches(uc,
-                                "You have exceeded a secondary rate limit. Please wait a few minutes before you try again");
-                        AbuseLimitHandler.FAIL.onError(e, uc);
-                    }
-                })
-                .build();
+        gitHub = getGitHubWithAbuseLimitHandler(new TestAbuseLimitHandler() {
+            /**
+             * Overriding method because the actual method will wait for one minute causing slowness in unit tests
+             */
+            @Override
+            public void onError(IOException e, HttpURLConnection uc) throws IOException {
+                savedConnection[0] = uc;
+                // Verify
+                assertThat(uc.getDate(), Matchers.greaterThanOrEqualTo(new Date().getTime() - 10000));
+                assertThat(uc.getExpiration(), equalTo(0L));
+                assertThat(uc.getIfModifiedSince(), equalTo(0L));
+                assertThat(uc.getLastModified(), equalTo(1581014017000L));
+                assertThat(uc.getRequestMethod(), equalTo("GET"));
+                assertThat(uc.getResponseCode(), equalTo(403));
+                assertThat(uc.getResponseMessage(), containsString("Forbidden"));
+                assertThat(uc.getURL().toString(),
+                        endsWith("/repos/hub4j-test-org/temp-testHandler_Wait_Secondary_Limits"));
+                assertThat(uc.getHeaderFieldInt("X-RateLimit-Limit", 10), equalTo(5000));
+                assertThat(uc.getHeaderFieldInt("X-RateLimit-Remaining", 10), equalTo(4000));
+                assertThat(uc.getHeaderFieldInt("X-Foo", 20), equalTo(20));
+                assertThat(uc.getHeaderFieldLong("X-RateLimit-Limit", 15L), equalTo(5000L));
+                assertThat(uc.getHeaderFieldLong("X-RateLimit-Remaining", 15L), equalTo(4000L));
+                assertThat(uc.getHeaderFieldLong("X-Foo", 20L), equalTo(20L));
+                assertThat(uc.getHeaderField("gh-limited-by"), equalTo("search-elapsed-time-shared-grouped"));
+                assertThat(uc.getContentEncoding(), nullValue());
+                assertThat(uc.getContentType(), equalTo("application/json; charset=utf-8"));
+                assertThat(uc.getContentLength(), equalTo(-1));
+                assertThat(uc.getHeaderFields(), instanceOf(Map.class));
+                assertThat(uc.getHeaderFields().size(), greaterThan(25));
+
+                assertThat(AbuseLimitHandler.DEFAULT_WAIT_MILLIS, equalTo(61 * 1000l));
+                AbuseLimitHandler.DEFAULT_WAIT_MILLIS = 3210l;
+                long waitTime = parseWaitTime(uc);
+                assertThat(waitTime, equalTo(AbuseLimitHandler.DEFAULT_WAIT_MILLIS));
+
+                assertThat(uc.getHeaderField("Status"), equalTo("403 Forbidden"));
+
+                checkErrorMessageMatches(uc,
+                        "You have exceeded a secondary rate limit. Please wait a few minutes before you try again");
+                AbuseLimitHandler.WAIT.onError(e, uc);
+            }
+        }).build();
 
         gitHub.getMyself();
         assertThat(mockGitHub.getRequestCount(), equalTo(1));
-        try {
-            getTempRepository();
-            fail();
-        } catch (Exception e) {
-            assertThat(e, instanceOf(HttpException.class));
-            assertThat(e.getMessage(), equalTo("Abuse limit reached"));
-        }
-        assertThat(mockGitHub.getRequestCount(), equalTo(2));
+
+        getTempRepository();
+        assertThat(mockGitHub.getRequestCount(), equalTo(3));
     }
 
     /**
@@ -388,54 +373,43 @@ public class AbuseLimitHandlerTest extends AbstractGitHubWireMockTest {
         // Customized response that templates the date to keep things working
         snapshotNotAllowed();
         final HttpURLConnection[] savedConnection = new HttpURLConnection[1];
-        gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl())
-                .withAbuseLimitHandler(new AbuseLimitHandler() {
-                    /**
-                     * Overriding method because the actual method will wait for one minute causing slowness in unit
-                     * tests
-                     */
-                    @Override
-                    public void onError(IOException e, HttpURLConnection uc) throws IOException {
-                        savedConnection[0] = uc;
-                        // Verify the test data is what we expected it to be for this test case
-                        assertThat(uc.getDate(), Matchers.greaterThanOrEqualTo(new Date().getTime() - 10000));
-                        assertThat(uc.getExpiration(), equalTo(0L));
-                        assertThat(uc.getIfModifiedSince(), equalTo(0L));
-                        assertThat(uc.getLastModified(), equalTo(1581014017000L));
-                        assertThat(uc.getRequestMethod(), equalTo("GET"));
-                        assertThat(uc.getResponseCode(), equalTo(429));
-                        assertThat(uc.getResponseMessage(), containsString("Many"));
-                        assertThat(uc.getURL().toString(),
-                                endsWith(
-                                        "/repos/hub4j-test-org/temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests"));
-                        assertThat(uc.getContentLength(), equalTo(-1));
-                        assertThat(uc.getHeaderFields(), instanceOf(Map.class));
-                        assertThat(uc.getHeaderField("Status"), equalTo("429 Too Many Requests"));
-                        assertThat(uc.getHeaderField("Retry-After"), equalTo("42"));
-
-                        checkErrorMessageMatches(uc,
-                                "You have exceeded a secondary rate limit. Please wait a few minutes before you try again");
-                        // Because we've overridden onError to bypass the wait, we don't cover the wait calculation
-                        // logic
-                        // Manually invoke it to make sure it's what we intended
-                        long waitTime = parseWaitTime(uc);
-                        assertThat(waitTime, equalTo(42 * 1000l));
-
-                        AbuseLimitHandler.FAIL.onError(e, uc);
-                    }
-                })
-                .build();
+        gitHub = getGitHubWithAbuseLimitHandler(new TestAbuseLimitHandler() {
+            /**
+             * Overriding method because the actual method will wait for one minute causing slowness in unit tests
+             */
+            @Override
+            public void onError(IOException e, HttpURLConnection uc) throws IOException {
+                savedConnection[0] = uc;
+                // Verify the test data is what we expected it to be for this test case
+                assertThat(uc.getDate(), Matchers.greaterThanOrEqualTo(new Date().getTime() - 10000));
+                assertThat(uc.getExpiration(), equalTo(0L));
+                assertThat(uc.getIfModifiedSince(), equalTo(0L));
+                assertThat(uc.getLastModified(), equalTo(1581014017000L));
+                assertThat(uc.getRequestMethod(), equalTo("GET"));
+                assertThat(uc.getResponseCode(), equalTo(429));
+                assertThat(uc.getResponseMessage(), containsString("Many"));
+                assertThat(uc.getURL().toString(),
+                        endsWith("/repos/hub4j-test-org/temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests"));
+                assertThat(uc.getContentLength(), equalTo(-1));
+                assertThat(uc.getHeaderFields(), instanceOf(Map.class));
+                assertThat(uc.getHeaderField("Status"), equalTo("429 Too Many Requests"));
+                assertThat(uc.getHeaderField("Retry-After"), equalTo("8"));
+
+                checkErrorMessageMatches(uc,
+                        "You have exceeded a secondary rate limit. Please wait a few minutes before you try again");
+
+                long waitTime = parseWaitTime(uc);
+                assertThat(waitTime, equalTo(8 * 1000l));
+
+                AbuseLimitHandler.WAIT.onError(e, uc);
+            }
+        }).build();
 
         gitHub.getMyself();
         assertThat(mockGitHub.getRequestCount(), equalTo(1));
-        try {
-            getTempRepository();
-            fail();
-        } catch (Exception e) {
-            assertThat(e, instanceOf(HttpException.class));
-            assertThat(e.getMessage(), equalTo("Abuse limit reached"));
-        }
-        assertThat(mockGitHub.getRequestCount(), equalTo(2));
+
+        getTempRepository();
+        assertThat(mockGitHub.getRequestCount(), equalTo(3));
     }
 
     /**
@@ -449,51 +423,41 @@ public class AbuseLimitHandlerTest extends AbstractGitHubWireMockTest {
         // Customized response that templates the date to keep things working
         snapshotNotAllowed();
         final HttpURLConnection[] savedConnection = new HttpURLConnection[1];
-        gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl())
-                .withAbuseLimitHandler(new AbuseLimitHandler() {
-                    /**
-                     * Overriding method because the actual method will wait for one minute causing slowness in unit
-                     * tests
-                     */
-                    @Override
-                    public void onError(IOException e, HttpURLConnection uc) throws IOException {
-                        savedConnection[0] = uc;
-                        // Verify the test data is what we expected it to be for this test case
-                        assertThat(uc.getRequestMethod(), equalTo("GET"));
-                        assertThat(uc.getResponseCode(), equalTo(429));
-                        assertThat(uc.getResponseMessage(), containsString("Many"));
-                        assertThat(uc.getURL().toString(),
-                                endsWith(
-                                        "/repos/hub4j-test-org/temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After"));
-                        assertThat(uc.getContentLength(), equalTo(-1));
-                        assertThat(uc.getHeaderField("Status"), equalTo("429 Too Many Requests"));
-                        assertThat(uc.getHeaderField("Retry-After"), startsWith("Mon"));
-
-                        checkErrorMessageMatches(uc,
-                                "You have exceeded a secondary rate limit. Please wait a few minutes before you try again");
-
-                        // Because we've overridden onError to bypass the wait, we don't cover the wait calculation
-                        // logic
-                        // Manually invoke it to make sure it's what we intended
-                        long waitTime = parseWaitTime(uc);
-                        // The exact value here will depend on when the test is run, but it should be positive, and huge
-                        assertThat(waitTime, greaterThan(1000 * 1000l));
-
-                        AbuseLimitHandler.FAIL.onError(e, uc);
-                    }
-                })
-                .build();
+        gitHub = getGitHubWithAbuseLimitHandler(new TestAbuseLimitHandler() {
+            /**
+             * Overriding method because the actual method will wait for one minute causing slowness in unit tests
+             */
+            @Override
+            public void onError(IOException e, HttpURLConnection uc) throws IOException {
+                savedConnection[0] = uc;
+                // Verify the test data is what we expected it to be for this test case
+                assertThat(uc.getRequestMethod(), equalTo("GET"));
+                assertThat(uc.getResponseCode(), equalTo(429));
+                assertThat(uc.getResponseMessage(), containsString("Many"));
+                assertThat(uc.getURL().toString(),
+                        endsWith(
+                                "/repos/hub4j-test-org/temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After"));
+                assertThat(uc.getContentLength(), equalTo(-1));
+                assertThat(uc.getHeaderField("Status"), equalTo("429 Too Many Requests"));
+                assertThat(uc.getHeaderField("Retry-After"), containsString("GMT"));
+
+                checkErrorMessageMatches(uc,
+                        "You have exceeded a secondary rate limit. Please wait a few minutes before you try again");
+
+                long waitTime = parseWaitTime(uc);
+                // The exact value here will depend on when the test is run
+                assertThat(waitTime, Matchers.lessThan(AbuseLimitHandler.DEFAULT_WAIT_MILLIS));
+                assertThat(waitTime, Matchers.greaterThan(3 * 1000l));
+
+                AbuseLimitHandler.WAIT.onError(e, uc);
+            }
+        }).build();
 
         gitHub.getMyself();
         assertThat(mockGitHub.getRequestCount(), equalTo(1));
-        try {
-            getTempRepository();
-            fail();
-        } catch (Exception e) {
-            assertThat(e, instanceOf(HttpException.class));
-            assertThat(e.getMessage(), equalTo("Abuse limit reached"));
-        }
-        assertThat(mockGitHub.getRequestCount(), equalTo(2));
+
+        getTempRepository();
+        assertThat(mockGitHub.getRequestCount(), equalTo(3));
     }
 
     /**
@@ -507,52 +471,59 @@ public class AbuseLimitHandlerTest extends AbstractGitHubWireMockTest {
         // Customized response that templates the date to keep things working
         snapshotNotAllowed();
         final HttpURLConnection[] savedConnection = new HttpURLConnection[1];
-        gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl())
-                .withAbuseLimitHandler(new AbuseLimitHandler() {
-                    /**
-                     * Overriding method because the actual method will wait for one minute causing slowness in unit
-                     * tests
-                     */
-                    @Override
-                    public void onError(IOException e, HttpURLConnection uc) throws IOException {
-                        savedConnection[0] = uc;
-                        // Verify the test data is what we expected it to be for this test case
-                        assertThat(uc.getRequestMethod(), equalTo("GET"));
-                        assertThat(uc.getResponseCode(), equalTo(429));
-                        assertThat(uc.getResponseMessage(), containsString("Many"));
-                        assertThat(uc.getURL().toString(),
-                                endsWith(
-                                        "/repos/hub4j-test-org/temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After"));
-                        assertThat(uc.getContentEncoding(), nullValue());
-                        assertThat(uc.getContentType(), equalTo("application/json; charset=utf-8"));
-                        assertThat(uc.getContentLength(), equalTo(-1));
-                        assertThat(uc.getHeaderFields(), instanceOf(Map.class));
-                        assertThat(uc.getHeaderField("Status"), equalTo("429 Too Many Requests"));
-                        assertThat(uc.getHeaderField("Retry-After"), nullValue());
-
-                        checkErrorMessageMatches(uc,
-                                "You have exceeded a secondary rate limit. Please wait a few minutes before you try again");
-
-                        // Because we've overridden onError to bypass the wait, we don't cover the wait calculation
-                        // logic
-                        // Manually invoke it to make sure it's what we intended
-                        long waitTime = parseWaitTime(uc);
-                        assertThat(waitTime, greaterThan(60000l));
-
-                        AbuseLimitHandler.FAIL.onError(e, uc);
-                    }
-                })
-                .build();
+        gitHub = getGitHubWithAbuseLimitHandler(new TestAbuseLimitHandler() {
+            /**
+             * Overriding method because the actual method will wait for one minute causing slowness in unit tests
+             */
+            @Override
+            public void onError(IOException e, HttpURLConnection uc) throws IOException {
+                savedConnection[0] = uc;
+                // Verify the test data is what we expected it to be for this test case
+                assertThat(uc.getRequestMethod(), equalTo("GET"));
+                assertThat(uc.getResponseCode(), equalTo(429));
+                assertThat(uc.getResponseMessage(), containsString("Many"));
+                assertThat(uc.getURL().toString(),
+                        endsWith(
+                                "/repos/hub4j-test-org/temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After"));
+                assertThat(uc.getContentEncoding(), nullValue());
+                assertThat(uc.getContentType(), equalTo("application/json; charset=utf-8"));
+                assertThat(uc.getContentLength(), equalTo(-1));
+                assertThat(uc.getHeaderFields(), instanceOf(Map.class));
+                assertThat(uc.getHeaderField("Status"), equalTo("429 Too Many Requests"));
+                assertThat(uc.getHeaderField("Retry-After"), nullValue());
+
+                checkErrorMessageMatches(uc,
+                        "You have exceeded a secondary rate limit. Please wait a few minutes before you try again");
+
+                AbuseLimitHandler.DEFAULT_WAIT_MILLIS = 3210l;
+                long waitTime = parseWaitTime(uc);
+                assertThat(waitTime, equalTo(AbuseLimitHandler.DEFAULT_WAIT_MILLIS));
+
+                AbuseLimitHandler.WAIT.onError(e, uc);
+            }
+        }).build();
 
         gitHub.getMyself();
         assertThat(mockGitHub.getRequestCount(), equalTo(1));
-        try {
-            getTempRepository();
-            fail();
-        } catch (Exception e) {
-            assertThat(e, instanceOf(HttpException.class));
-            assertThat(e.getMessage(), equalTo("Abuse limit reached"));
+
+        getTempRepository();
+        assertThat(mockGitHub.getRequestCount(), equalTo(3));
+    }
+
+    private GitHubBuilder getGitHubWithAbuseLimitHandler(AbuseLimitHandler abuseLimitHandler) {
+        return getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl())
+                .withAbuseLimitHandler(abuseLimitHandler);
+    }
+
+    /**
+     * Test class wrapping the deprecated AbuseLimitHandler to make editing easier.
+     */
+    public static abstract class TestAbuseLimitHandler extends AbuseLimitHandler {
+        /**
+         * Default Constructor
+         */
+        public TestAbuseLimitHandler() {
         }
-        assertThat(mockGitHub.getRequestCount(), equalTo(2));
     }
+
 }
diff --git a/src/test/java/org/kohsuke/aot/AotIntegrationTest.java b/src/test/java/org/kohsuke/github/AotIntegrationTest.java
similarity index 93%
rename from src/test/java/org/kohsuke/aot/AotIntegrationTest.java
rename to src/test/java/org/kohsuke/github/AotIntegrationTest.java
index 574661906..8605d8aa4 100644
--- a/src/test/java/org/kohsuke/aot/AotIntegrationTest.java
+++ b/src/test/java/org/kohsuke/github/AotIntegrationTest.java
@@ -1,4 +1,4 @@
-package org.kohsuke.aot;
+package org.kohsuke.github;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -25,6 +25,12 @@ import static org.junit.Assert.fail;
 @SpringBootTest
 public class AotIntegrationTest {
 
+    /**
+     * Create default AotIntegrationTest instance
+     */
+    public AotIntegrationTest() {
+    }
+
     /**
      * Test to check if all required classes are registered for AOT.
      *
@@ -77,6 +83,7 @@ public class AotIntegrationTest {
                 .map(jsonNode -> jsonNode.get("name"))
                 .map(JsonNode::toString)
                 .map(reflectConfigEntryClassName -> reflectConfigEntryClassName.replace("\"", ""))
-                .filter(x -> x.contains("org.kohsuke.github"));
+                .filter(x -> x.contains("org.kohsuke.github"))
+                .filter(x -> !x.contains("org.kohsuke.github.AotTest"));
     }
 }
diff --git a/src/test/java/org/kohsuke/aot/AotTestApplication.java b/src/test/java/org/kohsuke/github/AotTestApplication.java
similarity index 90%
rename from src/test/java/org/kohsuke/aot/AotTestApplication.java
rename to src/test/java/org/kohsuke/github/AotTestApplication.java
index 0e3081d93..bc4231fab 100644
--- a/src/test/java/org/kohsuke/aot/AotTestApplication.java
+++ b/src/test/java/org/kohsuke/github/AotTestApplication.java
@@ -1,4 +1,4 @@
-package org.kohsuke.aot;
+package org.kohsuke.github;
 
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.builder.SpringApplicationBuilder;
@@ -8,7 +8,7 @@ import org.springframework.boot.builder.SpringApplicationBuilder;
  * required for test purpose.
  */
 @SpringBootApplication
-public class AotTestApplication {
+class AotTestApplication {
 
     /**
      * Runs a spring boot application to generate AOT hints
diff --git a/src/test/java/org/kohsuke/aot/AotTestRuntimeHints.java b/src/test/java/org/kohsuke/github/AotTestRuntimeHints.java
similarity index 96%
rename from src/test/java/org/kohsuke/aot/AotTestRuntimeHints.java
rename to src/test/java/org/kohsuke/github/AotTestRuntimeHints.java
index 0dbad0591..9f184dee6 100644
--- a/src/test/java/org/kohsuke/aot/AotTestRuntimeHints.java
+++ b/src/test/java/org/kohsuke/github/AotTestRuntimeHints.java
@@ -1,4 +1,4 @@
-package org.kohsuke.aot;
+package org.kohsuke.github;
 
 import org.jetbrains.annotations.NotNull;
 import org.springframework.aot.hint.MemberCategory;
@@ -26,6 +26,12 @@ public class AotTestRuntimeHints implements RuntimeHintsRegistrar {
 
     private static final String LOCATION_PATTERN_OF_ORG_KOHSUKE_GITHUB_CLASSES = "classpath*:org/kohsuke/github/**/*.class";
 
+    /**
+     * Default constructor.
+     */
+    public AotTestRuntimeHints() {
+    }
+
     @Override
     public void registerHints(@NotNull RuntimeHints hints, ClassLoader classLoader) {
         try {
diff --git a/src/test/java/org/kohsuke/github/AppTest.java b/src/test/java/org/kohsuke/github/AppTest.java
index 5f34fb91b..b3e7e0fb0 100755
--- a/src/test/java/org/kohsuke/github/AppTest.java
+++ b/src/test/java/org/kohsuke/github/AppTest.java
@@ -29,6 +29,12 @@ import static org.junit.Assert.assertThrows;
  */
 public class AppTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default AppTest instance
+     */
+    public AppTest() {
+    }
+
     /** The Constant GITHUB_API_TEST_REPO. */
     static final String GITHUB_API_TEST_REPO = "github-api-test";
 
@@ -1060,6 +1066,19 @@ public class AppTest extends AbstractGitHubWireMockTest {
         }
     }
 
+    /**
+     * Test getEmails.
+     *
+     * @throws IOException
+     *             Signals that an I/O exception has occurred.
+     */
+    @Test
+    public void testGetEmails() throws IOException {
+        List<String> emails = gitHub.getMyself().getEmails();
+        assertThat(emails.size(), equalTo(2));
+        assertThat(emails, contains("bitwiseman@gmail.com", "bitwiseman@users.noreply.github.com"));
+    }
+
     /**
      * Test app.
      *
diff --git a/src/test/java/org/kohsuke/github/ArchTests.java b/src/test/java/org/kohsuke/github/ArchTests.java
index a460dc7db..8e36984dc 100644
--- a/src/test/java/org/kohsuke/github/ArchTests.java
+++ b/src/test/java/org/kohsuke/github/ArchTests.java
@@ -68,6 +68,12 @@ public class ArchTests {
         }
     };
 
+    /**
+     * Default constructor.
+     */
+    public ArchTests() {
+    }
+
     /**
      * Before class.
      */
diff --git a/src/test/java/org/kohsuke/github/BridgeMethodTest.java b/src/test/java/org/kohsuke/github/BridgeMethodTest.java
index f30aea7f8..3d0dbdfc6 100644
--- a/src/test/java/org/kohsuke/github/BridgeMethodTest.java
+++ b/src/test/java/org/kohsuke/github/BridgeMethodTest.java
@@ -23,6 +23,12 @@ import static org.hamcrest.Matchers.*;
  */
 public class BridgeMethodTest extends Assert {
 
+    /**
+     * Create default BridgeMethodTest instance
+     */
+    public BridgeMethodTest() {
+    }
+
     /**
      * Test bridge methods.
      *
diff --git a/src/test/java/org/kohsuke/github/CommitTest.java b/src/test/java/org/kohsuke/github/CommitTest.java
index 257e681cc..76b5028b3 100644
--- a/src/test/java/org/kohsuke/github/CommitTest.java
+++ b/src/test/java/org/kohsuke/github/CommitTest.java
@@ -19,6 +19,12 @@ import static org.hamcrest.Matchers.*;
  */
 public class CommitTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default CommitTest instance
+     */
+    public CommitTest() {
+    }
+
     /**
      * Last status.
      *
diff --git a/src/test/java/org/kohsuke/github/EnterpriseManagedSupportTest.java b/src/test/java/org/kohsuke/github/EnterpriseManagedSupportTest.java
index 9ddc72ea6..ad2c4c63f 100644
--- a/src/test/java/org/kohsuke/github/EnterpriseManagedSupportTest.java
+++ b/src/test/java/org/kohsuke/github/EnterpriseManagedSupportTest.java
@@ -14,6 +14,12 @@ import static org.hamcrest.Matchers.*;
  */
 public class EnterpriseManagedSupportTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default EnterpriseManagedSupportTest instance
+     */
+    public EnterpriseManagedSupportTest() {
+    }
+
     private static final String NOT_PART_OF_EXTERNALLY_MANAGED_ENTERPRISE_ERROR = "{\"message\":\"This organization is not part of externally managed enterprise.\","
             + "\"documentation_url\": \"https://docs.github.com/rest/teams/external-groups#list-external-groups-in-an-organization\"}";
 
diff --git a/src/test/java/org/kohsuke/github/EnumTest.java b/src/test/java/org/kohsuke/github/EnumTest.java
index 02ab6d912..845856142 100644
--- a/src/test/java/org/kohsuke/github/EnumTest.java
+++ b/src/test/java/org/kohsuke/github/EnumTest.java
@@ -13,6 +13,12 @@ import static org.hamcrest.CoreMatchers.*;
  */
 public class EnumTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default EnumTest instance
+     */
+    public EnumTest() {
+    }
+
     /**
      * Touch enums.
      */
diff --git a/src/test/java/org/kohsuke/github/GHAppExtendedTest.java b/src/test/java/org/kohsuke/github/GHAppExtendedTest.java
index a419f0945..84e3566a5 100644
--- a/src/test/java/org/kohsuke/github/GHAppExtendedTest.java
+++ b/src/test/java/org/kohsuke/github/GHAppExtendedTest.java
@@ -14,6 +14,12 @@ import static org.hamcrest.Matchers.is;
  */
 public class GHAppExtendedTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHAppExtendedTest instance
+     */
+    public GHAppExtendedTest() {
+    }
+
     private static final String APP_SLUG = "ghapi-test-app-4";
 
     /**
diff --git a/src/test/java/org/kohsuke/github/GHAppInstallationTest.java b/src/test/java/org/kohsuke/github/GHAppInstallationTest.java
index d6218d112..46c51b7b6 100644
--- a/src/test/java/org/kohsuke/github/GHAppInstallationTest.java
+++ b/src/test/java/org/kohsuke/github/GHAppInstallationTest.java
@@ -18,6 +18,12 @@ import static org.hamcrest.Matchers.*;
  */
 public class GHAppInstallationTest extends AbstractGHAppInstallationTest {
 
+    /**
+     * Create default GHAppInstallationTest instance
+     */
+    public GHAppInstallationTest() {
+    }
+
     /**
      * Test list repositories two repos.
      *
diff --git a/src/test/java/org/kohsuke/github/GHAppTest.java b/src/test/java/org/kohsuke/github/GHAppTest.java
index 2ceb479e4..3519e3302 100644
--- a/src/test/java/org/kohsuke/github/GHAppTest.java
+++ b/src/test/java/org/kohsuke/github/GHAppTest.java
@@ -24,6 +24,12 @@ import static org.junit.Assert.assertThrows;
  */
 public class GHAppTest extends AbstractGHAppInstallationTest {
 
+    /**
+     * Create default GHAppTest instance
+     */
+    public GHAppTest() {
+    }
+
     /**
      * Gets the git hub builder.
      *
diff --git a/src/test/java/org/kohsuke/github/GHAuthenticatedAppInstallationTest.java b/src/test/java/org/kohsuke/github/GHAuthenticatedAppInstallationTest.java
index 4461ccbc8..3786f22e3 100644
--- a/src/test/java/org/kohsuke/github/GHAuthenticatedAppInstallationTest.java
+++ b/src/test/java/org/kohsuke/github/GHAuthenticatedAppInstallationTest.java
@@ -15,6 +15,12 @@ import static org.hamcrest.Matchers.equalTo;
  */
 public class GHAuthenticatedAppInstallationTest extends AbstractGHAppInstallationTest {
 
+    /**
+     * Create default GHAuthenticatedAppInstallationTest instance
+     */
+    public GHAuthenticatedAppInstallationTest() {
+    }
+
     /**
      * Gets the git hub builder.
      *
diff --git a/src/test/java/org/kohsuke/github/GHBranchProtectionTest.java b/src/test/java/org/kohsuke/github/GHBranchProtectionTest.java
index bee19e8e0..5bbf0183d 100755
--- a/src/test/java/org/kohsuke/github/GHBranchProtectionTest.java
+++ b/src/test/java/org/kohsuke/github/GHBranchProtectionTest.java
@@ -22,6 +22,13 @@ import static org.hamcrest.Matchers.*;
  * The Class GHBranchProtectionTest.
  */
 public class GHBranchProtectionTest extends AbstractGitHubWireMockTest {
+
+    /**
+     * Create default GHBranchProtectionTest instance
+     */
+    public GHBranchProtectionTest() {
+    }
+
     private static final String BRANCH = "main";
     private static final String BRANCH_REF = "heads/" + BRANCH;
 
diff --git a/src/test/java/org/kohsuke/github/GHBranchTest.java b/src/test/java/org/kohsuke/github/GHBranchTest.java
index f28554160..117da049f 100644
--- a/src/test/java/org/kohsuke/github/GHBranchTest.java
+++ b/src/test/java/org/kohsuke/github/GHBranchTest.java
@@ -9,6 +9,13 @@ import static org.hamcrest.Matchers.*;
  * The Class GHBranchTest.
  */
 public class GHBranchTest extends AbstractGitHubWireMockTest {
+
+    /**
+     * Create default GHBranchTest instance
+     */
+    public GHBranchTest() {
+    }
+
     private static final String BRANCH_1 = "testBranch1";
     private static final String BRANCH_2 = "testBranch2";
 
diff --git a/src/test/java/org/kohsuke/github/GHCheckRunBuilderTest.java b/src/test/java/org/kohsuke/github/GHCheckRunBuilderTest.java
index 5b48eabd2..a52e07e3a 100644
--- a/src/test/java/org/kohsuke/github/GHCheckRunBuilderTest.java
+++ b/src/test/java/org/kohsuke/github/GHCheckRunBuilderTest.java
@@ -40,6 +40,12 @@ import static org.hamcrest.Matchers.*;
 @SuppressWarnings("deprecation") // preview
 public class GHCheckRunBuilderTest extends AbstractGHAppInstallationTest {
 
+    /**
+     * Create default GHCheckRunBuilderTest instance
+     */
+    public GHCheckRunBuilderTest() {
+    }
+
     /**
      * Gets the installation github.
      *
diff --git a/src/test/java/org/kohsuke/github/GHCodeownersErrorTest.java b/src/test/java/org/kohsuke/github/GHCodeownersErrorTest.java
index b4294be64..958d4908b 100644
--- a/src/test/java/org/kohsuke/github/GHCodeownersErrorTest.java
+++ b/src/test/java/org/kohsuke/github/GHCodeownersErrorTest.java
@@ -14,6 +14,12 @@ import static org.hamcrest.Matchers.*;
  */
 public class GHCodeownersErrorTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHCodeownersErrorTest instance
+     */
+    public GHCodeownersErrorTest() {
+    }
+
     /**
      * Gets the {@code CODEOWNERS} errors.
      *
diff --git a/src/test/java/org/kohsuke/github/GHContentIntegrationTest.java b/src/test/java/org/kohsuke/github/GHContentIntegrationTest.java
index c663dc1b3..7c83d5174 100644
--- a/src/test/java/org/kohsuke/github/GHContentIntegrationTest.java
+++ b/src/test/java/org/kohsuke/github/GHContentIntegrationTest.java
@@ -22,6 +22,12 @@ import static org.hamcrest.Matchers.*;
  */
 public class GHContentIntegrationTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHContentIntegrationTest instance
+     */
+    public GHContentIntegrationTest() {
+    }
+
     private GHRepository repo;
 
     // file name with spaces and other chars
diff --git a/src/test/java/org/kohsuke/github/GHDeployKeyTest.java b/src/test/java/org/kohsuke/github/GHDeployKeyTest.java
index 35d321888..bc3bb229a 100644
--- a/src/test/java/org/kohsuke/github/GHDeployKeyTest.java
+++ b/src/test/java/org/kohsuke/github/GHDeployKeyTest.java
@@ -17,6 +17,13 @@ import static org.hamcrest.Matchers.*;
  * @author Jonas van Vliet
  */
 public class GHDeployKeyTest extends AbstractGitHubWireMockTest {
+
+    /**
+     * Create default GHDeployKeyTest instance
+     */
+    public GHDeployKeyTest() {
+    }
+
     private static final String DEPLOY_KEY_TEST_REPO_NAME = "hub4j-test-org/GHDeployKeyTest";
     private static final String ED_25519_READONLY = "DeployKey - ed25519 - readonly";
     private static final String RSA_4096_READWRITE = "Deploykey - rsa4096 - readwrite";
diff --git a/src/test/java/org/kohsuke/github/GHDeploymentTest.java b/src/test/java/org/kohsuke/github/GHDeploymentTest.java
index 32be0cead..56d8caa63 100644
--- a/src/test/java/org/kohsuke/github/GHDeploymentTest.java
+++ b/src/test/java/org/kohsuke/github/GHDeploymentTest.java
@@ -16,6 +16,12 @@ import static org.hamcrest.Matchers.*;
  */
 public class GHDeploymentTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHDeploymentTest instance
+     */
+    public GHDeploymentTest() {
+    }
+
     /**
      * Test get deployment by id string payload.
      *
diff --git a/src/test/java/org/kohsuke/github/GHDiscussionTest.java b/src/test/java/org/kohsuke/github/GHDiscussionTest.java
index c2ea7f270..a2b68db1b 100644
--- a/src/test/java/org/kohsuke/github/GHDiscussionTest.java
+++ b/src/test/java/org/kohsuke/github/GHDiscussionTest.java
@@ -17,6 +17,13 @@ import static org.hamcrest.Matchers.*;
  * @author Charles Moulliard
  */
 public class GHDiscussionTest extends AbstractGitHubWireMockTest {
+
+    /**
+     * Create default GHDiscussionTest instance
+     */
+    public GHDiscussionTest() {
+    }
+
     private final String TEAM_SLUG = "dummy-team";
     private GHTeam team;
 
diff --git a/src/test/java/org/kohsuke/github/GHEventTest.java b/src/test/java/org/kohsuke/github/GHEventTest.java
index 4b43202da..900063d2b 100644
--- a/src/test/java/org/kohsuke/github/GHEventTest.java
+++ b/src/test/java/org/kohsuke/github/GHEventTest.java
@@ -11,6 +11,12 @@ import static org.hamcrest.Matchers.is;
  */
 public class GHEventTest {
 
+    /**
+     * Create default GHEventTest instance
+     */
+    public GHEventTest() {
+    }
+
     /**
      * Function from GHEventInfo to transform string event to GHEvent which has been replaced by static mapping due to
      * complex parsing logic below
diff --git a/src/test/java/org/kohsuke/github/GHExternalGroupTest.java b/src/test/java/org/kohsuke/github/GHExternalGroupTest.java
index ef7e7ec7d..da0696eec 100644
--- a/src/test/java/org/kohsuke/github/GHExternalGroupTest.java
+++ b/src/test/java/org/kohsuke/github/GHExternalGroupTest.java
@@ -16,6 +16,12 @@ import static org.kohsuke.github.ExternalGroupsTestingSupport.Matchers.*;
  */
 public class GHExternalGroupTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHExternalGroupTest instance
+     */
+    public GHExternalGroupTest() {
+    }
+
     /**
      * Test refresh bound external group.
      *
diff --git a/src/test/java/org/kohsuke/github/GHGistTest.java b/src/test/java/org/kohsuke/github/GHGistTest.java
index 142247a18..14e02f1c2 100644
--- a/src/test/java/org/kohsuke/github/GHGistTest.java
+++ b/src/test/java/org/kohsuke/github/GHGistTest.java
@@ -14,6 +14,12 @@ import static org.hamcrest.Matchers.*;
  */
 public class GHGistTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHGistTest instance
+     */
+    public GHGistTest() {
+    }
+
     /**
      * Lifecycle test.
      *
diff --git a/src/test/java/org/kohsuke/github/GHGistUpdaterTest.java b/src/test/java/org/kohsuke/github/GHGistUpdaterTest.java
index 5ec2590c5..e5626fc03 100644
--- a/src/test/java/org/kohsuke/github/GHGistUpdaterTest.java
+++ b/src/test/java/org/kohsuke/github/GHGistUpdaterTest.java
@@ -17,6 +17,12 @@ import static org.hamcrest.Matchers.*;
  */
 public class GHGistUpdaterTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHGistUpdaterTest instance
+     */
+    public GHGistUpdaterTest() {
+    }
+
     private GHGist gist;
 
     /**
diff --git a/src/test/java/org/kohsuke/github/GHHookTest.java b/src/test/java/org/kohsuke/github/GHHookTest.java
index 247505fb1..5d87c0407 100644
--- a/src/test/java/org/kohsuke/github/GHHookTest.java
+++ b/src/test/java/org/kohsuke/github/GHHookTest.java
@@ -24,6 +24,12 @@ import static org.hamcrest.core.IsInstanceOf.instanceOf;
  */
 public class GHHookTest {
 
+    /**
+     * Create default GHHookTest instance
+     */
+    public GHHookTest() {
+    }
+
     /**
      * Expose responce headers.
      *
diff --git a/src/test/java/org/kohsuke/github/GHIssueEventAttributeTest.java b/src/test/java/org/kohsuke/github/GHIssueEventAttributeTest.java
index 58f0587e7..73d04232d 100644
--- a/src/test/java/org/kohsuke/github/GHIssueEventAttributeTest.java
+++ b/src/test/java/org/kohsuke/github/GHIssueEventAttributeTest.java
@@ -21,6 +21,12 @@ import static org.hamcrest.Matchers.notNullValue;
  */
 public class GHIssueEventAttributeTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHIssueEventAttributeTest instance
+     */
+    public GHIssueEventAttributeTest() {
+    }
+
     private enum Type implements Predicate<GHIssueEvent>, Consumer<GHIssueEvent> {
         milestone(e -> assertThat(e.getMilestone(), notNullValue()), "milestoned", "demilestoned"),
         label(e -> assertThat(e.getLabel(), notNullValue()), "labeled", "unlabeled"),
diff --git a/src/test/java/org/kohsuke/github/GHIssueEventTest.java b/src/test/java/org/kohsuke/github/GHIssueEventTest.java
index 6ff51e0a4..5ac4c2b1d 100644
--- a/src/test/java/org/kohsuke/github/GHIssueEventTest.java
+++ b/src/test/java/org/kohsuke/github/GHIssueEventTest.java
@@ -16,6 +16,12 @@ import static org.hamcrest.Matchers.*;
  */
 public class GHIssueEventTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHIssueEventTest instance
+     */
+    public GHIssueEventTest() {
+    }
+
     /**
      * Test events for single issue.
      *
diff --git a/src/test/java/org/kohsuke/github/GHIssueTest.java b/src/test/java/org/kohsuke/github/GHIssueTest.java
index a0416f4de..ab32cf6f0 100644
--- a/src/test/java/org/kohsuke/github/GHIssueTest.java
+++ b/src/test/java/org/kohsuke/github/GHIssueTest.java
@@ -29,6 +29,12 @@ import static org.hamcrest.Matchers.nullValue;
  */
 public class GHIssueTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHIssueTest instance
+     */
+    public GHIssueTest() {
+    }
+
     /**
      * Clean up.
      *
diff --git a/src/test/java/org/kohsuke/github/GHLicenseTest.java b/src/test/java/org/kohsuke/github/GHLicenseTest.java
index fc47e7206..89580309b 100644
--- a/src/test/java/org/kohsuke/github/GHLicenseTest.java
+++ b/src/test/java/org/kohsuke/github/GHLicenseTest.java
@@ -40,6 +40,12 @@ import static org.hamcrest.Matchers.*;
  */
 public class GHLicenseTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHLicenseTest instance
+     */
+    public GHLicenseTest() {
+    }
+
     /**
      * Basic test to ensure that the list of licenses from {@link GitHub#listLicenses()} is returned.
      *
diff --git a/src/test/java/org/kohsuke/github/GHMarketplacePlanTest.java b/src/test/java/org/kohsuke/github/GHMarketplacePlanTest.java
index 90e697ce3..cf5eb9a01 100644
--- a/src/test/java/org/kohsuke/github/GHMarketplacePlanTest.java
+++ b/src/test/java/org/kohsuke/github/GHMarketplacePlanTest.java
@@ -20,6 +20,12 @@ import static org.kohsuke.github.GHMarketplaceListAccountBuilder.Sort.UPDATED;
  */
 public class GHMarketplacePlanTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHMarketplacePlanTest instance
+     */
+    public GHMarketplacePlanTest() {
+    }
+
     /**
      * Gets the git hub builder.
      *
diff --git a/src/test/java/org/kohsuke/github/GHMilestoneTest.java b/src/test/java/org/kohsuke/github/GHMilestoneTest.java
index f5da382cc..78867c4cd 100644
--- a/src/test/java/org/kohsuke/github/GHMilestoneTest.java
+++ b/src/test/java/org/kohsuke/github/GHMilestoneTest.java
@@ -18,6 +18,12 @@ import static org.hamcrest.Matchers.containsString;
  */
 public class GHMilestoneTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHMilestoneTest instance
+     */
+    public GHMilestoneTest() {
+    }
+
     /**
      * Clean up.
      *
diff --git a/src/test/java/org/kohsuke/github/GHObjectTest.java b/src/test/java/org/kohsuke/github/GHObjectTest.java
index 66388e55e..04cb3ac36 100644
--- a/src/test/java/org/kohsuke/github/GHObjectTest.java
+++ b/src/test/java/org/kohsuke/github/GHObjectTest.java
@@ -10,6 +10,12 @@ import static org.hamcrest.Matchers.*;
  */
 public class GHObjectTest extends org.kohsuke.github.AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHObjectTest instance
+     */
+    public GHObjectTest() {
+    }
+
     /**
      * Test to string.
      *
diff --git a/src/test/java/org/kohsuke/github/GHOrganizationTest.java b/src/test/java/org/kohsuke/github/GHOrganizationTest.java
index fcafc97aa..88e46dfa2 100644
--- a/src/test/java/org/kohsuke/github/GHOrganizationTest.java
+++ b/src/test/java/org/kohsuke/github/GHOrganizationTest.java
@@ -23,6 +23,12 @@ import static org.kohsuke.github.ExternalGroupsTestingSupport.Matchers.*;
  */
 public class GHOrganizationTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHOrganizationTest instance
+     */
+    public GHOrganizationTest() {
+    }
+
     /** The Constant GITHUB_API_TEST. */
     public static final String GITHUB_API_TEST = "github-api-test";
 
diff --git a/src/test/java/org/kohsuke/github/GHPersonTest.java b/src/test/java/org/kohsuke/github/GHPersonTest.java
index efadce263..199885c01 100644
--- a/src/test/java/org/kohsuke/github/GHPersonTest.java
+++ b/src/test/java/org/kohsuke/github/GHPersonTest.java
@@ -15,6 +15,12 @@ import static org.hamcrest.Matchers.notNullValue;
  */
 public class GHPersonTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHPersonTest instance
+     */
+    public GHPersonTest() {
+    }
+
     /**
      * Test fields for organization.
      *
diff --git a/src/test/java/org/kohsuke/github/GHProjectCardTest.java b/src/test/java/org/kohsuke/github/GHProjectCardTest.java
index 7370ac9de..f3494b8a6 100644
--- a/src/test/java/org/kohsuke/github/GHProjectCardTest.java
+++ b/src/test/java/org/kohsuke/github/GHProjectCardTest.java
@@ -16,6 +16,13 @@ import static org.hamcrest.Matchers.*;
  * @author Gunnar Skjold
  */
 public class GHProjectCardTest extends AbstractGitHubWireMockTest {
+
+    /**
+     * Create default GHProjectCardTest instance
+     */
+    public GHProjectCardTest() {
+    }
+
     private GHOrganization org;
     private GHProject project;
     private GHProjectColumn column;
diff --git a/src/test/java/org/kohsuke/github/GHProjectColumnTest.java b/src/test/java/org/kohsuke/github/GHProjectColumnTest.java
index afbdaf5bb..ec09a4e3a 100644
--- a/src/test/java/org/kohsuke/github/GHProjectColumnTest.java
+++ b/src/test/java/org/kohsuke/github/GHProjectColumnTest.java
@@ -17,6 +17,13 @@ import static org.hamcrest.Matchers.nullValue;
  * @author Gunnar Skjold
  */
 public class GHProjectColumnTest extends AbstractGitHubWireMockTest {
+
+    /**
+     * Create default GHProjectColumnTest instance
+     */
+    public GHProjectColumnTest() {
+    }
+
     private GHProject project;
     private GHProjectColumn column;
 
diff --git a/src/test/java/org/kohsuke/github/GHProjectTest.java b/src/test/java/org/kohsuke/github/GHProjectTest.java
index cf2707e20..45f893e30 100644
--- a/src/test/java/org/kohsuke/github/GHProjectTest.java
+++ b/src/test/java/org/kohsuke/github/GHProjectTest.java
@@ -16,6 +16,13 @@ import static org.hamcrest.Matchers.*;
  * @author Gunnar Skjold
  */
 public class GHProjectTest extends AbstractGitHubWireMockTest {
+
+    /**
+     * Create default GHProjectTest instance
+     */
+    public GHProjectTest() {
+    }
+
     private GHProject project;
 
     /**
diff --git a/src/test/java/org/kohsuke/github/GHPublicKeyTest.java b/src/test/java/org/kohsuke/github/GHPublicKeyTest.java
index 4bd505b16..b4f4a07b8 100644
--- a/src/test/java/org/kohsuke/github/GHPublicKeyTest.java
+++ b/src/test/java/org/kohsuke/github/GHPublicKeyTest.java
@@ -9,6 +9,12 @@ import org.junit.Test;
  */
 public class GHPublicKeyTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHPublicKeyTest instance
+     */
+    public GHPublicKeyTest() {
+    }
+
     private static final String TMP_KEY_NAME = "Temporary user key";
     private static final String WIREMOCK_SSH_PUBLIC_KEY = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDepW2/BSVFM2AfuGGsvi+vjQzC0EBD3R+/7PNEvP0/nvTWxiC/tthfvvCJR6TKrsprCir5tiJFm73gX+K18W0RKYpkyg8H6d1eZu3q/JOiGvoDPeN8Oe9hOGeeexw1WOiz7ESPHzZYXI981evzHAzxxn8zibr2EryopVNsXyoenw==";
 
diff --git a/src/test/java/org/kohsuke/github/GHPullRequestMockTest.java b/src/test/java/org/kohsuke/github/GHPullRequestMockTest.java
index 852a442cc..45dd9af9f 100644
--- a/src/test/java/org/kohsuke/github/GHPullRequestMockTest.java
+++ b/src/test/java/org/kohsuke/github/GHPullRequestMockTest.java
@@ -14,6 +14,12 @@ import static org.mockito.Mockito.when;
  */
 public class GHPullRequestMockTest {
 
+    /**
+     * Create default GHPullRequestMockTest instance
+     */
+    public GHPullRequestMockTest() {
+    }
+
     /**
      * Should mock GH pull request.
      *
diff --git a/src/test/java/org/kohsuke/github/GHPullRequestTest.java b/src/test/java/org/kohsuke/github/GHPullRequestTest.java
index c1e94336f..919e1f8b6 100644
--- a/src/test/java/org/kohsuke/github/GHPullRequestTest.java
+++ b/src/test/java/org/kohsuke/github/GHPullRequestTest.java
@@ -34,6 +34,12 @@ import static org.hamcrest.Matchers.nullValue;
  */
 public class GHPullRequestTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHPullRequestTest instance
+     */
+    public GHPullRequestTest() {
+    }
+
     /**
      * Clean up.
      *
diff --git a/src/test/java/org/kohsuke/github/GHReleaseTest.java b/src/test/java/org/kohsuke/github/GHReleaseTest.java
index 65fb6a9ba..7d907c433 100644
--- a/src/test/java/org/kohsuke/github/GHReleaseTest.java
+++ b/src/test/java/org/kohsuke/github/GHReleaseTest.java
@@ -12,6 +12,12 @@ import static org.junit.Assert.assertThrows;
  */
 public class GHReleaseTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHReleaseTest instance
+     */
+    public GHReleaseTest() {
+    }
+
     /**
      * Test create simple release.
      *
diff --git a/src/test/java/org/kohsuke/github/GHRepositoryRuleTest.java b/src/test/java/org/kohsuke/github/GHRepositoryRuleTest.java
index 9f176883e..084e41e15 100644
--- a/src/test/java/org/kohsuke/github/GHRepositoryRuleTest.java
+++ b/src/test/java/org/kohsuke/github/GHRepositoryRuleTest.java
@@ -21,6 +21,13 @@ import static org.hamcrest.Matchers.nullValue;
  * Test class for GHRepositoryRule.
  */
 public class GHRepositoryRuleTest {
+
+    /**
+     * Create default GHRepositoryRuleTest instance
+     */
+    public GHRepositoryRuleTest() {
+    }
+
     /**
      * Test to cover the constructor of the Parameters class.
      */
diff --git a/src/test/java/org/kohsuke/github/GHRepositoryStatisticsTest.java b/src/test/java/org/kohsuke/github/GHRepositoryStatisticsTest.java
index 56cf3d954..b7e32ce0a 100644
--- a/src/test/java/org/kohsuke/github/GHRepositoryStatisticsTest.java
+++ b/src/test/java/org/kohsuke/github/GHRepositoryStatisticsTest.java
@@ -14,6 +14,12 @@ import static org.hamcrest.Matchers.equalTo;
  */
 public class GHRepositoryStatisticsTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHRepositoryStatisticsTest instance
+     */
+    public GHRepositoryStatisticsTest() {
+    }
+
     /** The max iterations. */
     public static int MAX_ITERATIONS = 3;
 
diff --git a/src/test/java/org/kohsuke/github/GHRepositoryTest.java b/src/test/java/org/kohsuke/github/GHRepositoryTest.java
index d387c93cb..e37a39aee 100644
--- a/src/test/java/org/kohsuke/github/GHRepositoryTest.java
+++ b/src/test/java/org/kohsuke/github/GHRepositoryTest.java
@@ -32,6 +32,12 @@ import static org.kohsuke.github.GHVerification.Reason.UNKNOWN_SIGNATURE_TYPE;
  */
 public class GHRepositoryTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHRepositoryTest instance
+     */
+    public GHRepositoryTest() {
+    }
+
     /**
      * Gets the repository.
      *
diff --git a/src/test/java/org/kohsuke/github/GHRepositoryTrafficReferralBaseTest.java b/src/test/java/org/kohsuke/github/GHRepositoryTrafficReferralBaseTest.java
index 78cd6d252..af092d4c7 100644
--- a/src/test/java/org/kohsuke/github/GHRepositoryTrafficReferralBaseTest.java
+++ b/src/test/java/org/kohsuke/github/GHRepositoryTrafficReferralBaseTest.java
@@ -11,6 +11,12 @@ import static org.hamcrest.Matchers.is;
  */
 public class GHRepositoryTrafficReferralBaseTest {
 
+    /**
+     * Create default GHRepositoryTrafficReferralBaseTest instance
+     */
+    public GHRepositoryTrafficReferralBaseTest() {
+    }
+
     /**
      * Test the constructor.
      */
diff --git a/src/test/java/org/kohsuke/github/GHRepositoryTrafficTopReferralPathTest.java b/src/test/java/org/kohsuke/github/GHRepositoryTrafficTopReferralPathTest.java
index b1de0dff7..498de39fb 100644
--- a/src/test/java/org/kohsuke/github/GHRepositoryTrafficTopReferralPathTest.java
+++ b/src/test/java/org/kohsuke/github/GHRepositoryTrafficTopReferralPathTest.java
@@ -11,6 +11,12 @@ import static org.hamcrest.Matchers.is;
  */
 public class GHRepositoryTrafficTopReferralPathTest {
 
+    /**
+     * Create default GHRepositoryTrafficTopReferralPathTest instance
+     */
+    public GHRepositoryTrafficTopReferralPathTest() {
+    }
+
     /**
      * Test the constructor.
      */
diff --git a/src/test/java/org/kohsuke/github/GHRepositoryTrafficTopReferralSourcesTest.java b/src/test/java/org/kohsuke/github/GHRepositoryTrafficTopReferralSourcesTest.java
index 9125f2908..7051d7f7a 100644
--- a/src/test/java/org/kohsuke/github/GHRepositoryTrafficTopReferralSourcesTest.java
+++ b/src/test/java/org/kohsuke/github/GHRepositoryTrafficTopReferralSourcesTest.java
@@ -11,6 +11,12 @@ import static org.hamcrest.Matchers.is;
  */
 public class GHRepositoryTrafficTopReferralSourcesTest {
 
+    /**
+     * Create default GHRepositoryTrafficTopReferralSourcesTest instance
+     */
+    public GHRepositoryTrafficTopReferralSourcesTest() {
+    }
+
     /**
      * Test the constructor.
      */
diff --git a/src/test/java/org/kohsuke/github/GHTagTest.java b/src/test/java/org/kohsuke/github/GHTagTest.java
index d4536ed92..48f990f3d 100644
--- a/src/test/java/org/kohsuke/github/GHTagTest.java
+++ b/src/test/java/org/kohsuke/github/GHTagTest.java
@@ -16,6 +16,12 @@ import static org.hamcrest.Matchers.*;
  */
 public class GHTagTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHTagTest instance
+     */
+    public GHTagTest() {
+    }
+
     /**
      * Clean up tags.
      *
diff --git a/src/test/java/org/kohsuke/github/GHTeamBuilderTest.java b/src/test/java/org/kohsuke/github/GHTeamBuilderTest.java
index 60148acd7..8a2a71517 100644
--- a/src/test/java/org/kohsuke/github/GHTeamBuilderTest.java
+++ b/src/test/java/org/kohsuke/github/GHTeamBuilderTest.java
@@ -12,6 +12,12 @@ import static org.hamcrest.Matchers.equalTo;
  */
 public class GHTeamBuilderTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHTeamBuilderTest instance
+     */
+    public GHTeamBuilderTest() {
+    }
+
     /**
      * Test create child team.
      *
diff --git a/src/test/java/org/kohsuke/github/GHTeamTest.java b/src/test/java/org/kohsuke/github/GHTeamTest.java
index 8deba28c2..1bd3ea6ba 100644
--- a/src/test/java/org/kohsuke/github/GHTeamTest.java
+++ b/src/test/java/org/kohsuke/github/GHTeamTest.java
@@ -22,6 +22,12 @@ import static org.kohsuke.github.ExternalGroupsTestingSupport.Matchers.isExterna
  */
 public class GHTeamTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHTeamTest instance
+     */
+    public GHTeamTest() {
+    }
+
     /**
      * Test set description.
      *
diff --git a/src/test/java/org/kohsuke/github/GHTreeBuilderTest.java b/src/test/java/org/kohsuke/github/GHTreeBuilderTest.java
index 907147788..c22332c72 100644
--- a/src/test/java/org/kohsuke/github/GHTreeBuilderTest.java
+++ b/src/test/java/org/kohsuke/github/GHTreeBuilderTest.java
@@ -16,6 +16,13 @@ import static org.hamcrest.Matchers.*;
  * The Class GHTreeBuilderTest.
  */
 public class GHTreeBuilderTest extends AbstractGitHubWireMockTest {
+
+    /**
+     * Create default GHTreeBuilderTest instance
+     */
+    public GHTreeBuilderTest() {
+    }
+
     private static String REPO_NAME = "hub4j-test-org/GHTreeBuilderTest";
 
     private static String PATH_SCRIPT = "app/run.sh";
diff --git a/src/test/java/org/kohsuke/github/GHUserTest.java b/src/test/java/org/kohsuke/github/GHUserTest.java
index 5e67bf645..633cf22f8 100644
--- a/src/test/java/org/kohsuke/github/GHUserTest.java
+++ b/src/test/java/org/kohsuke/github/GHUserTest.java
@@ -20,6 +20,12 @@ import static org.hamcrest.Matchers.notNullValue;
  */
 public class GHUserTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHUserTest instance
+     */
+    public GHUserTest() {
+    }
+
     /**
      * Checks if is member of.
      *
diff --git a/src/test/java/org/kohsuke/github/GHVerificationReasonTest.java b/src/test/java/org/kohsuke/github/GHVerificationReasonTest.java
index 42b3292c7..3573fd386 100644
--- a/src/test/java/org/kohsuke/github/GHVerificationReasonTest.java
+++ b/src/test/java/org/kohsuke/github/GHVerificationReasonTest.java
@@ -12,6 +12,12 @@ import static org.hamcrest.Matchers.*;
  */
 public class GHVerificationReasonTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHVerificationReasonTest instance
+     */
+    public GHVerificationReasonTest() {
+    }
+
     /**
      * Test expired key.
      *
diff --git a/src/test/java/org/kohsuke/github/GHWorkflowRunTest.java b/src/test/java/org/kohsuke/github/GHWorkflowRunTest.java
index cda06a9eb..d15f50667 100644
--- a/src/test/java/org/kohsuke/github/GHWorkflowRunTest.java
+++ b/src/test/java/org/kohsuke/github/GHWorkflowRunTest.java
@@ -30,6 +30,12 @@ import static org.hamcrest.Matchers.*;
  */
 public class GHWorkflowRunTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHWorkflowRunTest instance
+     */
+    public GHWorkflowRunTest() {
+    }
+
     private static final String REPO_NAME = "hub4j-test-org/GHWorkflowRunTest";
     private static final String MAIN_BRANCH = "main";
     private static final String SECOND_BRANCH = "second-branch";
diff --git a/src/test/java/org/kohsuke/github/GHWorkflowTest.java b/src/test/java/org/kohsuke/github/GHWorkflowTest.java
index 63b2aec5c..33e3682bb 100644
--- a/src/test/java/org/kohsuke/github/GHWorkflowTest.java
+++ b/src/test/java/org/kohsuke/github/GHWorkflowTest.java
@@ -21,6 +21,12 @@ import static org.hamcrest.Matchers.notNullValue;
  */
 public class GHWorkflowTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GHWorkflowTest instance
+     */
+    public GHWorkflowTest() {
+    }
+
     private static String REPO_NAME = "hub4j-test-org/GHWorkflowTest";
 
     private GHRepository repo;
diff --git a/src/test/java/org/kohsuke/github/GitHubStaticTest.java b/src/test/java/org/kohsuke/github/GitHubStaticTest.java
index 16ac75b52..a6696be79 100644
--- a/src/test/java/org/kohsuke/github/GitHubStaticTest.java
+++ b/src/test/java/org/kohsuke/github/GitHubStaticTest.java
@@ -30,6 +30,12 @@ import static org.junit.Assert.fail;
  */
 public class GitHubStaticTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GitHubStaticTest instance
+     */
+    public GitHubStaticTest() {
+    }
+
     /**
      * Test parse URL.
      *
diff --git a/src/test/java/org/kohsuke/github/GitHubTest.java b/src/test/java/org/kohsuke/github/GitHubTest.java
index fc2c76c21..193652f84 100644
--- a/src/test/java/org/kohsuke/github/GitHubTest.java
+++ b/src/test/java/org/kohsuke/github/GitHubTest.java
@@ -17,6 +17,12 @@ import static org.kohsuke.github.GHMarketplaceAccountType.ORGANIZATION;
  */
 public class GitHubTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default GitHubTest instance
+     */
+    public GitHubTest() {
+    }
+
     /**
      * List users.
      *
diff --git a/src/test/java/org/kohsuke/github/junit/GitHubWireMockRule.java b/src/test/java/org/kohsuke/github/GitHubWireMockRule.java
similarity index 99%
rename from src/test/java/org/kohsuke/github/junit/GitHubWireMockRule.java
rename to src/test/java/org/kohsuke/github/GitHubWireMockRule.java
index 980a997e6..bd4224f9d 100644
--- a/src/test/java/org/kohsuke/github/junit/GitHubWireMockRule.java
+++ b/src/test/java/org/kohsuke/github/GitHubWireMockRule.java
@@ -1,4 +1,4 @@
-package org.kohsuke.github.junit;
+package org.kohsuke.github;
 
 import com.github.tomakehurst.wiremock.WireMockServer;
 import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder;
@@ -31,7 +31,6 @@ import javax.annotation.Nonnull;
 import static com.github.tomakehurst.wiremock.client.WireMock.*;
 import static com.github.tomakehurst.wiremock.common.Gzip.unGzipToString;
 
-// TODO: Auto-generated Javadoc
 /**
  * The standard WireMockRule eagerly initializes a WireMockServer. This version suptakes a laze approach allowing us to
  * automatically isolate snapshots for each method.
diff --git a/src/test/java/org/kohsuke/github/Github2faTest.java b/src/test/java/org/kohsuke/github/Github2faTest.java
index a76661a8d..6aeec0cd7 100644
--- a/src/test/java/org/kohsuke/github/Github2faTest.java
+++ b/src/test/java/org/kohsuke/github/Github2faTest.java
@@ -16,6 +16,12 @@ import static org.hamcrest.Matchers.*;
  */
 public class Github2faTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default Github2faTest instance
+     */
+    public Github2faTest() {
+    }
+
     /**
      * Test 2 fa token.
      *
diff --git a/src/test/java/org/kohsuke/github/LifecycleTest.java b/src/test/java/org/kohsuke/github/LifecycleTest.java
index 2651346f7..6a59e0e4f 100644
--- a/src/test/java/org/kohsuke/github/LifecycleTest.java
+++ b/src/test/java/org/kohsuke/github/LifecycleTest.java
@@ -18,6 +18,12 @@ import static org.hamcrest.Matchers.*;
  */
 public class LifecycleTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default LifecycleTest instance
+     */
+    public LifecycleTest() {
+    }
+
     /**
      * Test create repository.
      *
diff --git a/src/test/java/org/kohsuke/github/RepositoryTrafficTest.java b/src/test/java/org/kohsuke/github/RepositoryTrafficTest.java
index 416c51071..2fd49958b 100644
--- a/src/test/java/org/kohsuke/github/RepositoryTrafficTest.java
+++ b/src/test/java/org/kohsuke/github/RepositoryTrafficTest.java
@@ -14,6 +14,13 @@ import java.util.List;
  * The Class RepositoryTrafficTest.
  */
 public class RepositoryTrafficTest extends AbstractGitHubWireMockTest {
+
+    /**
+     * Create default RepositoryTrafficTest instance
+     */
+    public RepositoryTrafficTest() {
+    }
+
     final private String repositoryName = "github-api";
 
     @SuppressWarnings("unchecked")
diff --git a/src/test/java/org/kohsuke/github/junit/WireMockMultiServerRule.java b/src/test/java/org/kohsuke/github/WireMockMultiServerRule.java
similarity index 99%
rename from src/test/java/org/kohsuke/github/junit/WireMockMultiServerRule.java
rename to src/test/java/org/kohsuke/github/WireMockMultiServerRule.java
index 3d99281cf..0df77f446 100644
--- a/src/test/java/org/kohsuke/github/junit/WireMockMultiServerRule.java
+++ b/src/test/java/org/kohsuke/github/WireMockMultiServerRule.java
@@ -1,4 +1,4 @@
-package org.kohsuke.github.junit;
+package org.kohsuke.github;
 
 import com.github.tomakehurst.wiremock.WireMockServer;
 import com.github.tomakehurst.wiremock.client.VerificationException;
@@ -18,7 +18,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-// TODO: Auto-generated Javadoc
 /**
  * The standard WireMockRule eagerly initializes a WireMockServer. This version supports multiple servers in one rule
  * and takes a lazy approach to intitialization allowing us to isolate files snapshots for each method.
diff --git a/src/test/java/org/kohsuke/github/junit/WireMockRule.java b/src/test/java/org/kohsuke/github/WireMockRule.java
similarity index 99%
rename from src/test/java/org/kohsuke/github/junit/WireMockRule.java
rename to src/test/java/org/kohsuke/github/WireMockRule.java
index b7e89a6cd..66f2baf6d 100644
--- a/src/test/java/org/kohsuke/github/junit/WireMockRule.java
+++ b/src/test/java/org/kohsuke/github/WireMockRule.java
@@ -1,4 +1,4 @@
-package org.kohsuke.github.junit;
+package org.kohsuke.github;
 
 import com.github.tomakehurst.wiremock.WireMockServer;
 import com.github.tomakehurst.wiremock.admin.model.*;
@@ -34,7 +34,6 @@ import java.io.File;
 import java.util.List;
 import java.util.UUID;
 
-// TODO: Auto-generated Javadoc
 /**
  * The Class WireMockRule.
  *
diff --git a/src/test/java/org/kohsuke/github/junit/WireMockRuleConfiguration.java b/src/test/java/org/kohsuke/github/WireMockRuleConfiguration.java
similarity index 99%
rename from src/test/java/org/kohsuke/github/junit/WireMockRuleConfiguration.java
rename to src/test/java/org/kohsuke/github/WireMockRuleConfiguration.java
index 1960061c0..c933f885f 100644
--- a/src/test/java/org/kohsuke/github/junit/WireMockRuleConfiguration.java
+++ b/src/test/java/org/kohsuke/github/WireMockRuleConfiguration.java
@@ -1,4 +1,4 @@
-package org.kohsuke.github.junit;
+package org.kohsuke.github;
 
 import com.github.tomakehurst.wiremock.common.*;
 import com.github.tomakehurst.wiremock.core.MappingsSaver;
@@ -22,7 +22,6 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
-// TODO: Auto-generated Javadoc
 /**
  * The Class WireMockRuleConfiguration.
  */
diff --git a/src/test/java/org/kohsuke/github/WireMockStatusReporterTest.java b/src/test/java/org/kohsuke/github/WireMockStatusReporterTest.java
index 07eab6a2f..eb1a5e143 100644
--- a/src/test/java/org/kohsuke/github/WireMockStatusReporterTest.java
+++ b/src/test/java/org/kohsuke/github/WireMockStatusReporterTest.java
@@ -19,6 +19,12 @@ import static org.junit.Assume.assumeTrue;
  */
 public class WireMockStatusReporterTest extends AbstractGitHubWireMockTest {
 
+    /**
+     * Create default WireMockStatusReporterTest instance
+     */
+    public WireMockStatusReporterTest() {
+    }
+
     /**
      * User when proxying auth correctly configured.
      *
diff --git a/src/test/java/org/kohsuke/github/extras/authorization/JWTTokenProviderTest.java b/src/test/java/org/kohsuke/github/extras/authorization/JWTTokenProviderTest.java
index 793da64bc..4b98cc18c 100644
--- a/src/test/java/org/kohsuke/github/extras/authorization/JWTTokenProviderTest.java
+++ b/src/test/java/org/kohsuke/github/extras/authorization/JWTTokenProviderTest.java
@@ -32,6 +32,12 @@ import static org.hamcrest.Matchers.*;
  */
 public class JWTTokenProviderTest extends AbstractGHAppInstallationTest {
 
+    /**
+     * Create default JWTTokenProviderTest instance
+     */
+    public JWTTokenProviderTest() {
+    }
+
     private static String TEST_APP_ID_2 = "83009";
     private static String PRIVATE_KEY_FILE_APP_2 = "/ghapi-test-app-2.private-key.pem";
 
diff --git a/src/test/java/org/kohsuke/github/internal/EnumUtilsTest.java b/src/test/java/org/kohsuke/github/internal/EnumUtilsTest.java
index b7bab96ec..5169e947a 100644
--- a/src/test/java/org/kohsuke/github/internal/EnumUtilsTest.java
+++ b/src/test/java/org/kohsuke/github/internal/EnumUtilsTest.java
@@ -11,6 +11,12 @@ import static org.hamcrest.Matchers.*;
  */
 public class EnumUtilsTest {
 
+    /**
+     * Create default EnumUtilsTest instance
+     */
+    public EnumUtilsTest() {
+    }
+
     /**
      * Test get enum.
      */
diff --git a/src/test/resources/META-INF/spring/aot.factories b/src/test/resources/META-INF/spring/aot.factories
index f81c736a2..bd6638701 100644
--- a/src/test/resources/META-INF/spring/aot.factories
+++ b/src/test/resources/META-INF/spring/aot.factories
@@ -1,1 +1,1 @@
-org.springframework.aot.hint.RuntimeHintsRegistrar=org.kohsuke.aot.AotTestRuntimeHints
\ No newline at end of file
+org.springframework.aot.hint.RuntimeHintsRegistrar=org.kohsuke.github.AotTestRuntimeHints
\ No newline at end of file
diff --git a/src/test/resources/no-reflect-and-serialization-list b/src/test/resources/no-reflect-and-serialization-list
index 4da5b76fe..d786dc0cf 100644
--- a/src/test/resources/no-reflect-and-serialization-list
+++ b/src/test/resources/no-reflect-and-serialization-list
@@ -26,6 +26,9 @@ org.kohsuke.github.GitHubConnectorResponseErrorHandler
 org.kohsuke.github.GitHubPageIterator
 org.kohsuke.github.GitHubRateLimitChecker
 org.kohsuke.github.GitHubRateLimitHandler
+org.kohsuke.github.GitHubRateLimitHandler$1
+org.kohsuke.github.GitHubRateLimitHandler$2
+org.kohsuke.github.GitHubRequestBuilderDone
 org.kohsuke.github.HttpConnector
 org.kohsuke.github.HttpException
 org.kohsuke.github.PagedIterator
diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests/mappings/2-r_h_t_fail.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests/mappings/2-r_h_t_fail.json
index d1127227f..39bc81002 100644
--- a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests/mappings/2-r_h_t_fail.json
+++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests/mappings/2-r_h_t_fail.json
@@ -11,17 +11,14 @@
     }
   },
   "response": {
-    "status": 403,
+    "status": 429,
     "body": "{\"message\":\"You have exceeded a secondary rate limit. Please wait a few minutes before you try again\"}",
     "headers": {
       "Date": "{{now timezone='GMT' format='EEE, dd MMM yyyy HH:mm:ss z'}}",
       "Content-Type": "application/json; charset=utf-8",
       "Server": "GitHub.com",
-      "Status": "403 Forbidden",
-      "gh-limited-by": "search-elapsed-time-shared-grouped",
-      "X-RateLimit-Limit": "5000",
-      "X-RateLimit-Remaining": "4000",
-      "X-RateLimit-Reset": "{{testStartDate offset='3 seconds' format='unix'}}",
+      "Status": "429 Too Many Requests",
+      "Retry-After": "8",
       "Cache-Control": "private, max-age=60, s-maxage=60",
       "Vary": [
         "Accept, Authorization, Cookie, X-GitHub-OTP",
@@ -45,8 +42,8 @@
   },
   "uuid": "79fb1092-8bf3-4274-bc8e-ca126c9d9261",
   "persistent": true,
-  "scenarioName": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests",
+  "scenarioName": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits1",
   "requiredScenarioState": "Started",
-  "newScenarioState": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests-2",
+  "newScenarioState": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits1-2",
   "insertionIndex": 2
 }
\ No newline at end of file
diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests/mappings/3-r_h_t_fail.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests/mappings/3-r_h_t_fail.json
index a2dc66b59..643ed2e9d 100644
--- a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests/mappings/3-r_h_t_fail.json
+++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests/mappings/3-r_h_t_fail.json
@@ -1,5 +1,5 @@
 {
-  "id": "79fb1092-8bf3-4274-bc8e-ca126c9d9261",
+  "id": "574da117-6845-46d8-b2c1-4415546ca670",
   "name": "repos_hub4j-test-org_temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests",
   "request": {
     "url": "/repos/hub4j-test-org/temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests",
@@ -11,21 +11,23 @@
     }
   },
   "response": {
-    "status": 429,
-    "body": "{\"message\":\"You have exceeded a secondary rate limit. Please wait a few minutes before you try again\"}",
+    "status": 200,
+    "bodyFileName": "3-r_h_t_fail.json",
     "headers": {
       "Date": "{{now timezone='GMT' format='EEE, dd MMM yyyy HH:mm:ss z'}}",
       "Content-Type": "application/json; charset=utf-8",
       "Server": "GitHub.com",
-      "Status": "429 Too Many Requests",
-      "Retry-After": "42",
+      "Status": "200 OK",
+      "X-RateLimit-Limit": "5000",
+      "X-RateLimit-Remaining": "4922",
+      "X-RateLimit-Reset": "{{testStartDate offset='3 seconds' format='unix'}}",
       "Cache-Control": "private, max-age=60, s-maxage=60",
       "Vary": [
         "Accept, Authorization, Cookie, X-GitHub-OTP",
         "Accept-Encoding"
       ],
-      "ETag": "W/\"7ff3c96399f7ddf6129622d675ca9935\"",
-      "Last-Modified": "Thu, 06 Feb 2020 18:33:37 GMT",
+      "ETag": "W/\"858224998ac7d1fd6dcd43f73d375297\"",
+      "Last-Modified": "Thu, 06 Feb 2020 18:33:43 GMT",
       "X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
       "X-Accepted-OAuth-Scopes": "repo",
       "X-GitHub-Media-Type": "unknown, github.v3",
@@ -37,13 +39,12 @@
       "X-XSS-Protection": "1; mode=block",
       "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
       "Content-Security-Policy": "default-src 'none'",
-      "X-GitHub-Request-Id": "CC37:2605:3F982:4E949:5E3C5BFC"
+      "X-GitHub-Request-Id": "CC37:2605:3FADC:4EA8C:5E3C5C02"
     }
   },
-  "uuid": "79fb1092-8bf3-4274-bc8e-ca126c9d9261",
+  "uuid": "574da117-6845-46d8-b2c1-4415546ca670",
   "persistent": true,
-  "scenarioName": "scenario-4-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests",
-  "requiredScenarioState": "Started",
-  "newScenarioState": "scenario-4-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests-2",
-  "insertionIndex": 2
+  "scenarioName": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits1",
+  "requiredScenarioState": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits1-2",
+  "insertionIndex": 3
 }
\ No newline at end of file
diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After/mappings/2-r_h_t_fail.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After/mappings/2-r_h_t_fail.json
index 41af8b707..4d22b7d4b 100644
--- a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After/mappings/2-r_h_t_fail.json
+++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After/mappings/2-r_h_t_fail.json
@@ -11,17 +11,14 @@
     }
   },
   "response": {
-    "status": 403,
+    "status": 429,
     "body": "{\"message\":\"You have exceeded a secondary rate limit. Please wait a few minutes before you try again\"}",
     "headers": {
       "Date": "{{now timezone='GMT' format='EEE, dd MMM yyyy HH:mm:ss z'}}",
       "Content-Type": "application/json; charset=utf-8",
       "Server": "GitHub.com",
-      "Status": "403 Forbidden",
-      "gh-limited-by": "search-elapsed-time-shared-grouped",
-      "X-RateLimit-Limit": "5000",
-      "X-RateLimit-Remaining": "4000",
-      "X-RateLimit-Reset": "{{testStartDate offset='3 seconds' format='unix'}}",
+      "Status": "429 Too Many Requests",
+      "Retry-After": "{{now offset='8 seconds' timezone='GMT' format='EEE, dd MMM yyyy HH:mm:ss z'}}",
       "Cache-Control": "private, max-age=60, s-maxage=60",
       "Vary": [
         "Accept, Authorization, Cookie, X-GitHub-OTP",
@@ -45,8 +42,8 @@
   },
   "uuid": "79fb1092-8bf3-4274-bc8e-ca126c9d9261",
   "persistent": true,
-  "scenarioName": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After",
+  "scenarioName": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits2",
   "requiredScenarioState": "Started",
-  "newScenarioState": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After-2",
+  "newScenarioState": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits2-2",
   "insertionIndex": 2
 }
\ No newline at end of file
diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After/mappings/3-r_h_t_fail.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After/mappings/3-r_h_t_fail.json
index a29ef6ac2..f433290ea 100644
--- a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After/mappings/3-r_h_t_fail.json
+++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After/mappings/3-r_h_t_fail.json
@@ -1,5 +1,5 @@
 {
-  "id": "79fb1092-8bf3-4274-bc8e-ca126c9d9261",
+  "id": "574da117-6845-46d8-b2c1-4415546ca670",
   "name": "repos_hub4j-test-org_temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After",
   "request": {
     "url": "/repos/hub4j-test-org/temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After",
@@ -11,21 +11,23 @@
     }
   },
   "response": {
-    "status": 429,
-    "body": "{\"message\":\"You have exceeded a secondary rate limit. Please wait a few minutes before you try again\"}",
+    "status": 200,
+    "bodyFileName": "3-r_h_t_fail.json",
     "headers": {
       "Date": "{{now timezone='GMT' format='EEE, dd MMM yyyy HH:mm:ss z'}}",
       "Content-Type": "application/json; charset=utf-8",
       "Server": "GitHub.com",
-      "Status": "429 Too Many Requests",
-      "Retry-After": "Mon, 21 Oct 2115 07:28:00 GMT",
+      "Status": "200 OK",
+      "X-RateLimit-Limit": "5000",
+      "X-RateLimit-Remaining": "4922",
+      "X-RateLimit-Reset": "{{testStartDate offset='3 seconds' format='unix'}}",
       "Cache-Control": "private, max-age=60, s-maxage=60",
       "Vary": [
         "Accept, Authorization, Cookie, X-GitHub-OTP",
         "Accept-Encoding"
       ],
-      "ETag": "W/\"7ff3c96399f7ddf6129622d675ca9935\"",
-      "Last-Modified": "Thu, 06 Feb 2020 18:33:37 GMT",
+      "ETag": "W/\"858224998ac7d1fd6dcd43f73d375297\"",
+      "Last-Modified": "Thu, 06 Feb 2020 18:33:43 GMT",
       "X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
       "X-Accepted-OAuth-Scopes": "repo",
       "X-GitHub-Media-Type": "unknown, github.v3",
@@ -37,13 +39,12 @@
       "X-XSS-Protection": "1; mode=block",
       "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
       "Content-Security-Policy": "default-src 'none'",
-      "X-GitHub-Request-Id": "CC37:2605:3F982:4E949:5E3C5BFC"
+      "X-GitHub-Request-Id": "CC37:2605:3FADC:4EA8C:5E3C5C02"
     }
   },
-  "uuid": "79fb1092-8bf3-4274-bc8e-ca126c9d9261",
+  "uuid": "574da117-6845-46d8-b2c1-4415546ca670",
   "persistent": true,
-  "scenarioName": "scenario-4-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After",
-  "requiredScenarioState": "Started",
-  "newScenarioState": "scenario-4-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After-2",
-  "insertionIndex": 2
+  "scenarioName": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits2",
+  "requiredScenarioState": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits2-2",
+  "insertionIndex": 3
 }
\ No newline at end of file
diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After/mappings/2-r_h_t_fail.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After/mappings/2-r_h_t_fail.json
new file mode 100644
index 000000000..f5e2fd8e2
--- /dev/null
+++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After/mappings/2-r_h_t_fail.json
@@ -0,0 +1,49 @@
+{
+  "id": "79fb1092-8bf3-4274-bc8e-ca126c9d9261",
+  "name": "repos_hub4j-test-org_temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After",
+  "request": {
+    "url": "/repos/hub4j-test-org/temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After",
+    "method": "GET",
+    "headers": {
+      "Accept": {
+        "equalTo": "application/vnd.github+json"
+      }
+    }
+  },
+  "response": {
+    "status": 429,
+    "body": "{\"message\":\"You have exceeded a secondary rate limit. Please wait a few minutes before you try again\"}",
+    "headers": {
+      "Date": "{{now timezone='GMT' format='EEE, dd MMM yyyy HH:mm:ss z'}}",
+      "Content-Type": "application/json; charset=utf-8",
+      "Server": "GitHub.com",
+      "Status": "429 Too Many Requests",
+      "gh-limited-by": "search-elapsed-time-shared-grouped",
+      "Cache-Control": "private, max-age=60, s-maxage=60",
+      "Vary": [
+        "Accept, Authorization, Cookie, X-GitHub-OTP",
+        "Accept-Encoding"
+      ],
+      "ETag": "W/\"7ff3c96399f7ddf6129622d675ca9935\"",
+      "Last-Modified": "Thu, 06 Feb 2020 18:33:37 GMT",
+      "X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
+      "X-Accepted-OAuth-Scopes": "repo",
+      "X-GitHub-Media-Type": "unknown, github.v3",
+      "Access-Control-Expose-Headers": "ETag, Link, Location, gh-limited-by, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
+      "Access-Control-Allow-Origin": "*",
+      "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
+      "X-Frame-Options": "deny",
+      "X-Content-Type-Options": "nosniff",
+      "X-XSS-Protection": "1; mode=block",
+      "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
+      "Content-Security-Policy": "default-src 'none'",
+      "X-GitHub-Request-Id": "CC37:2605:3F982:4E949:5E3C5BFC"
+    }
+  },
+  "uuid": "79fb1092-8bf3-4274-bc8e-ca126c9d9261",
+  "persistent": true,
+  "scenarioName": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits3",
+  "requiredScenarioState": "Started",
+  "newScenarioState": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits3-2",
+  "insertionIndex": 2
+}
\ No newline at end of file
diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After/mappings/3-r_h_t_fail.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After/mappings/3-r_h_t_fail.json
index d6522df8e..9d7f608e1 100644
--- a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After/mappings/3-r_h_t_fail.json
+++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After/mappings/3-r_h_t_fail.json
@@ -1,5 +1,5 @@
 {
-  "id": "79fb1092-8bf3-4274-bc8e-ca126c9d9261",
+  "id": "574da117-6845-46d8-b2c1-4415546ca670",
   "name": "repos_hub4j-test-org_temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After",
   "request": {
     "url": "/repos/hub4j-test-org/temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After",
@@ -11,21 +11,23 @@
     }
   },
   "response": {
-    "status": 429,
-    "body": "{\"message\":\"You have exceeded a secondary rate limit. Please wait a few minutes before you try again\"}",
+    "status": 200,
+    "bodyFileName": "3-r_h_t_fail.json",
     "headers": {
       "Date": "{{now timezone='GMT' format='EEE, dd MMM yyyy HH:mm:ss z'}}",
       "Content-Type": "application/json; charset=utf-8",
       "Server": "GitHub.com",
-      "Status": "429 Too Many Requests",
-      "gh-limited-by": "search-elapsed-time-shared-grouped",
+      "Status": "200 OK",
+      "X-RateLimit-Limit": "5000",
+      "X-RateLimit-Remaining": "4922",
+      "X-RateLimit-Reset": "{{testStartDate offset='3 seconds' format='unix'}}",
       "Cache-Control": "private, max-age=60, s-maxage=60",
       "Vary": [
         "Accept, Authorization, Cookie, X-GitHub-OTP",
         "Accept-Encoding"
       ],
-      "ETag": "W/\"7ff3c96399f7ddf6129622d675ca9935\"",
-      "Last-Modified": "Thu, 06 Feb 2020 18:33:37 GMT",
+      "ETag": "W/\"858224998ac7d1fd6dcd43f73d375297\"",
+      "Last-Modified": "Thu, 06 Feb 2020 18:33:43 GMT",
       "X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
       "X-Accepted-OAuth-Scopes": "repo",
       "X-GitHub-Media-Type": "unknown, github.v3",
@@ -37,13 +39,12 @@
       "X-XSS-Protection": "1; mode=block",
       "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
       "Content-Security-Policy": "default-src 'none'",
-      "X-GitHub-Request-Id": "CC37:2605:3F982:4E949:5E3C5BFC"
+      "X-GitHub-Request-Id": "CC37:2605:3FADC:4EA8C:5E3C5C02"
     }
   },
-  "uuid": "79fb1092-8bf3-4274-bc8e-ca126c9d9261",
+  "uuid": "574da117-6845-46d8-b2c1-4415546ca670",
   "persistent": true,
-  "scenarioName": "scenario-4-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After",
-  "requiredScenarioState": "Started",
-  "newScenarioState": "scenario-4-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After-2",
-  "insertionIndex": 2
+  "scenarioName": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits3",
+  "requiredScenarioState": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits3-2",
+  "insertionIndex": 3
 }
\ No newline at end of file
diff --git a/src/test/resources/org/kohsuke/github/AppTest/wiremock/testGetEmails/__files/1-user.json b/src/test/resources/org/kohsuke/github/AppTest/wiremock/testGetEmails/__files/1-user.json
new file mode 100644
index 000000000..9e0ff6043
--- /dev/null
+++ b/src/test/resources/org/kohsuke/github/AppTest/wiremock/testGetEmails/__files/1-user.json
@@ -0,0 +1,47 @@
+{
+  "login": "bitwiseman",
+  "id": 1958953,
+  "node_id": "MDQ6VXNlcjE5NTg5NTM=",
+  "avatar_url": "https://avatars.githubusercontent.com/u/1958953?v=4",
+  "gravatar_id": "",
+  "url": "https://api.github.com/users/bitwiseman",
+  "html_url": "https://github.com/bitwiseman",
+  "followers_url": "https://api.github.com/users/bitwiseman/followers",
+  "following_url": "https://api.github.com/users/bitwiseman/following{/other_user}",
+  "gists_url": "https://api.github.com/users/bitwiseman/gists{/gist_id}",
+  "starred_url": "https://api.github.com/users/bitwiseman/starred{/owner}{/repo}",
+  "subscriptions_url": "https://api.github.com/users/bitwiseman/subscriptions",
+  "organizations_url": "https://api.github.com/users/bitwiseman/orgs",
+  "repos_url": "https://api.github.com/users/bitwiseman/repos",
+  "events_url": "https://api.github.com/users/bitwiseman/events{/privacy}",
+  "received_events_url": "https://api.github.com/users/bitwiseman/received_events",
+  "type": "User",
+  "site_admin": false,
+  "name": "Liam Newman",
+  "company": null,
+  "blog": "",
+  "location": "Seattle, WA, USA",
+  "email": "bitwiseman@gmail.com",
+  "hireable": null,
+  "bio": null,
+  "twitter_username": "bitwiseman",
+  "notification_email": "bitwiseman@gmail.com",
+  "public_repos": 212,
+  "public_gists": 8,
+  "followers": 258,
+  "following": 12,
+  "created_at": "2012-07-11T20:38:33Z",
+  "updated_at": "2024-07-11T16:46:55Z",
+  "private_gists": 19,
+  "total_private_repos": 3,
+  "owned_private_repos": 3,
+  "disk_usage": 34051,
+  "collaborators": 4,
+  "two_factor_authentication": true,
+  "plan": {
+    "name": "free",
+    "space": 976562499,
+    "collaborators": 0,
+    "private_repos": 10000
+  }
+}
\ No newline at end of file
diff --git a/src/test/resources/org/kohsuke/github/AppTest/wiremock/testGetEmails/__files/2-user_emails.json b/src/test/resources/org/kohsuke/github/AppTest/wiremock/testGetEmails/__files/2-user_emails.json
new file mode 100644
index 000000000..b5e4d9f5b
--- /dev/null
+++ b/src/test/resources/org/kohsuke/github/AppTest/wiremock/testGetEmails/__files/2-user_emails.json
@@ -0,0 +1,14 @@
+[
+  {
+    "email": "bitwiseman@gmail.com",
+    "primary": true,
+    "verified": true,
+    "visibility": "public"
+  },
+  {
+    "email": "bitwiseman@users.noreply.github.com",
+    "primary": false,
+    "verified": true,
+    "visibility": null
+  }
+]
\ No newline at end of file
diff --git a/src/test/resources/org/kohsuke/github/AppTest/wiremock/testGetEmails/mappings/1-user.json b/src/test/resources/org/kohsuke/github/AppTest/wiremock/testGetEmails/mappings/1-user.json
new file mode 100644
index 000000000..dedf69087
--- /dev/null
+++ b/src/test/resources/org/kohsuke/github/AppTest/wiremock/testGetEmails/mappings/1-user.json
@@ -0,0 +1,48 @@
+{
+  "id": "ccd6f98f-7d6f-44a8-87ab-375e3a49d8f2",
+  "name": "user",
+  "request": {
+    "url": "/user",
+    "method": "GET",
+    "headers": {
+      "Accept": {
+        "equalTo": "application/vnd.github+json"
+      }
+    }
+  },
+  "response": {
+    "status": 200,
+    "bodyFileName": "1-user.json",
+    "headers": {
+      "Date": "Tue, 17 Sep 2024 18:41:52 GMT",
+      "Content-Type": "application/json; charset=utf-8",
+      "Cache-Control": "private, max-age=60, s-maxage=60",
+      "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With",
+      "ETag": "W/\"a27242a466c3df86c7421f5da77e7af0282d7b11679db48547af0b315d2eb3c1\"",
+      "Last-Modified": "Thu, 11 Jul 2024 16:46:55 GMT",
+      "X-OAuth-Scopes": "read:user, repo, user:email",
+      "X-Accepted-OAuth-Scopes": "",
+      "github-authentication-token-expiration": "2024-10-17 18:38:10 UTC",
+      "X-GitHub-Media-Type": "github.v3; format=json",
+      "x-github-api-version-selected": "2022-11-28",
+      "X-RateLimit-Limit": "5000",
+      "X-RateLimit-Remaining": "4991",
+      "X-RateLimit-Reset": "1726601960",
+      "X-RateLimit-Used": "9",
+      "X-RateLimit-Resource": "core",
+      "Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset",
+      "Access-Control-Allow-Origin": "*",
+      "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
+      "X-Frame-Options": "deny",
+      "X-Content-Type-Options": "nosniff",
+      "X-XSS-Protection": "0",
+      "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
+      "Content-Security-Policy": "default-src 'none'",
+      "Server": "github.com",
+      "X-GitHub-Request-Id": "6A1F:A6CDA:12AE1BE:12C74DE:66E9CD70"
+    }
+  },
+  "uuid": "ccd6f98f-7d6f-44a8-87ab-375e3a49d8f2",
+  "persistent": true,
+  "insertionIndex": 1
+}
\ No newline at end of file
diff --git a/src/test/resources/org/kohsuke/github/AppTest/wiremock/testGetEmails/mappings/2-user_emails.json b/src/test/resources/org/kohsuke/github/AppTest/wiremock/testGetEmails/mappings/2-user_emails.json
new file mode 100644
index 000000000..067a6a1d9
--- /dev/null
+++ b/src/test/resources/org/kohsuke/github/AppTest/wiremock/testGetEmails/mappings/2-user_emails.json
@@ -0,0 +1,47 @@
+{
+  "id": "f17d4d94-f19c-425e-8133-f9f3ad2bafea",
+  "name": "user_emails",
+  "request": {
+    "url": "/user/emails",
+    "method": "GET",
+    "headers": {
+      "Accept": {
+        "equalTo": "application/vnd.github+json"
+      }
+    }
+  },
+  "response": {
+    "status": 200,
+    "bodyFileName": "2-user_emails.json",
+    "headers": {
+      "Date": "Tue, 17 Sep 2024 18:41:52 GMT",
+      "Content-Type": "application/json; charset=utf-8",
+      "Cache-Control": "private, max-age=60, s-maxage=60",
+      "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With",
+      "ETag": "W/\"6e974566422ee9f8351add9d3450581b14045944d67d5b0d45d93816f7526d77\"",
+      "X-OAuth-Scopes": "read:user, repo, user:email",
+      "X-Accepted-OAuth-Scopes": "user, user:email",
+      "github-authentication-token-expiration": "2024-10-17 18:38:10 UTC",
+      "X-GitHub-Media-Type": "github.v3; format=json",
+      "x-github-api-version-selected": "2022-11-28",
+      "X-RateLimit-Limit": "5000",
+      "X-RateLimit-Remaining": "4989",
+      "X-RateLimit-Reset": "1726601960",
+      "X-RateLimit-Used": "11",
+      "X-RateLimit-Resource": "core",
+      "Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset",
+      "Access-Control-Allow-Origin": "*",
+      "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
+      "X-Frame-Options": "deny",
+      "X-Content-Type-Options": "nosniff",
+      "X-XSS-Protection": "0",
+      "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
+      "Content-Security-Policy": "default-src 'none'",
+      "Server": "github.com",
+      "X-GitHub-Request-Id": "9EA1:32201C:118116E:119A333:66E9CD70"
+    }
+  },
+  "uuid": "f17d4d94-f19c-425e-8133-f9f3ad2bafea",
+  "persistent": true,
+  "insertionIndex": 2
+}
\ No newline at end of file
diff --git a/src/test/resources/slow-or-flaky-tests.txt b/src/test/resources/slow-or-flaky-tests.txt
index b9c6fbbdc..df6827bec 100644
--- a/src/test/resources/slow-or-flaky-tests.txt
+++ b/src/test/resources/slow-or-flaky-tests.txt
@@ -1,4 +1,5 @@
 **/extras/**
+**/AbuseLimitHandlerTest
 **/GHRateLimitTest
 **/GHPullRequestTest
 **/RequesterRetryTest