diff --git a/README.md b/README.md
index 7a64aae8d..6a2094450 100644
--- a/README.md
+++ b/README.md
@@ -105,7 +105,7 @@ in less than one second and therewith can be easily integrated in each build.
* Comparison of two jar archives without the need to add all of their dependencies to the classpath.
* Differences are printed on the command line in a simple diff format.
-* Differences can optionally be printed as XML or HTML file.
+* Differences can optionally be printed as [Markdown](https://www.markdownguide.org/), XML or HTML file.
* Per default private and package protected classes and class members are not compared. If necessary, the access modifier of the classes and class members to be
compared can be set to public, protected, package or private.
* Per default all classes are tracked. If necessary, certain packages, classes, methods or fields can be excluded or explicitly included. Inclusion and exclusion is also possible based on annotations.
diff --git a/doc/japicmp_guava.md b/doc/japicmp_guava.md
new file mode 100644
index 000000000..ec876f46d
--- /dev/null
+++ b/doc/japicmp_guava.md
@@ -0,0 +1,3177 @@
+
+# Compatibility Report
+
+![semver MAJOR](https://img.shields.io/badge/semver-MAJOR-red?logo=semver "semver MAJOR")
+
+## Summary
+
+> [!CAUTION]
+>
+> Incompatible changes found while checking backward compatibility of version `19.0` with the previous version `18.0`.
+
+
+Expand to see options used.
+
+- **Report only summary**: No
+- **Report only changes**: Yes
+- **Report only binary-incompatible changes**: No
+- **Access modifier filter**: `PROTECTED`
+- **Old archives**:
+ - ![guava 18.0](https://img.shields.io/badge/guava-18.0-blue "guava 18.0")
+- **New archives**:
+ - ![guava 19.0](https://img.shields.io/badge/guava-19.0-blue "guava 19.0")
+- **Evaluate annotations**: Yes
+- **Include synthetic classes and class members**: No
+- **Include specific elements**: No
+- **Exclude specific elements**: No
+- **Ignore all missing classes**: No
+- **Ignore specific missing classes**: No
+- **Treat changes as errors**:
+ - Any changes: No
+ - Binary incompatible changes: No
+ - Source incompatible changes: No
+ - Incompatible changes caused by excluded classes: Yes
+ - Semantically incompatible changes: No
+ - Semantically incompatible changes, including development versions: No
+- **Classpath mode**: `ONE_COMMON_CLASSPATH`
+- **Old classpath**:
+```
+
+```
+- **New classpath**:
+```
+
+```
+
+
+
+
+## Results
+
+| Status | Type | Serialization | Compatibility Changes |
+|----------------------------|-----------------------------------------------------------|-------------------------------------|-----------------------|
+| Unchanged | [com.google.common.base.Ascii] | ![Not serializable] | ![Annotation added] ![Annotation removed] |
+| Unchanged | [com.google.common.base.CaseFormat] | ![Compatible] | ![Annotation added] |
+| Modified | [com.google.common.base.CharMatcher] | ![Not serializable] | ![Method added to public class] |
+| Unchanged | [com.google.common.base.Defaults] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.base.Enums] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.base.Equivalence] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.base.Functions] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.base.Joiner] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.base.Joiner$MapJoiner] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.base.MoreObjects] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.base.MoreObjects$ToStringHelper] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.base.Objects] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.base.Optional] | ![Compatible] | ![Annotation added] |
+| Unchanged | [com.google.common.base.Predicates] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.base.Splitter] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.base.Splitter$MapSplitter] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.base.StandardSystemProperty] | ![Compatible] | ![Annotation added] |
+| Unchanged | [com.google.common.base.Stopwatch] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.base.Strings] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.base.Suppliers] | ![Not serializable] | ![Annotation added] |
+| Modified | [com.google.common.base.Throwables] | ![Not serializable] | ![Annotation added] ![Method added to public class] |
+| Unchanged | [com.google.common.base.Ticker] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.base.Utf8] | ![Not serializable] | ![Annotation added] |
+| Modified | [com.google.common.base.VerifyException] | ![Default serialversionuid changed] | ![No changes] |
+| Modified | [com.google.common.cache.CacheLoader$UnsupportedLoadingOperationException] | ![Default serialversionuid changed] | ![No changes] |
+| Modified | [com.google.common.cache.RemovalNotification] | ![Not serializable] | ![Method added to public class] |
+| Unchanged | [com.google.common.collect.BiMap] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.collect.Collections2] | ![Not serializable] | ![Annotation added] |
+| Modified | [com.google.common.collect.ComparisonChain] | ![Not serializable] | ![Annotation added] ![Annotation deprecated added] ![Method added to public class] |
+| Modified | [com.google.common.collect.FluentIterable] | ![Not serializable] | ![Annotation added] ![Method added to public class] |
+| Modified | [com.google.common.collect.HashBiMap] | ![Superclass modified] | ![Superclass added] ![Method return type generics changed] |
+| Modified | [com.google.common.collect.ImmutableBiMap] | ![Default serialversionuid changed] | ![Method added to public class] |
+| Modified | [com.google.common.collect.ImmutableBiMap$Builder] | ![Not serializable] | ![Method added to public class] |
+| Modified | [com.google.common.collect.ImmutableClassToInstanceMap] | ![Default serialversionuid changed] | ![Method added to public class] |
+| Modified | [com.google.common.collect.ImmutableCollection] | ![Default serialversionuid changed] | ![Method now abstract] |
+| Serialization-incompatible | [com.google.common.collect.ImmutableList] | ![Default serialversionuid changed] | ![No changes] |
+| Modified | [com.google.common.collect.ImmutableListMultimap] | ![Compatible] | ![Method added to public class] |
+| Modified | [com.google.common.collect.ImmutableListMultimap$Builder] | ![Not serializable] | ![Method added to public class] |
+| Modified | [com.google.common.collect.ImmutableMap] | ![Default serialversionuid changed] | ![Method added to public class] |
+| Modified | [com.google.common.collect.ImmutableMap$Builder] | ![Not serializable] | ![Method added to public class] |
+| Modified | [com.google.common.collect.ImmutableMultimap] | ![Compatible] | ![Method added to public class] |
+| Modified | [com.google.common.collect.ImmutableMultimap$Builder] | ![Not serializable] | ![Method added to public class] |
+| Modified | [com.google.common.collect.ImmutableMultiset] | ![Default serialversionuid changed] | ![No changes] |
+| Modified | [com.google.common.collect.ImmutableRangeMap] | ![Compatible] | ![Interface added] ![Method added to public class] |
+| Modified | [com.google.common.collect.ImmutableRangeSet] | ![Default serialversionuid changed] | ![Method added to public class] |
+| Modified | [com.google.common.collect.ImmutableSetMultimap] | ![Compatible] | ![Method added to public class] |
+| Modified | [com.google.common.collect.ImmutableSetMultimap$Builder] | ![Not serializable] | ![Method added to public class] |
+| Modified | [com.google.common.collect.ImmutableSortedMap] | ![Compatible] | ![Class now final] ![Method added to public class] |
+| Modified | [com.google.common.collect.ImmutableSortedMap$Builder] | ![Not serializable] | ![Annotation deprecated added] ![Method added to public class] |
+| Source-incompatible | [com.google.common.collect.ImmutableSortedMultiset] | ![Compatible] | ![Class generic template generics changed] |
+| Serialization-incompatible | [com.google.common.collect.ImmutableSortedSet] | ![Default serialversionuid changed] | ![No changes] |
+| Unchanged | [com.google.common.collect.Iterables] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.collect.Iterators] | ![Not serializable] | ![Annotation added] |
+| Modified | [com.google.common.collect.Lists] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.collect.MapConstraint] | ![Not serializable] | ![Annotation deprecated added] |
+| Unchanged | [com.google.common.collect.MapConstraints] | ![Not serializable] | ![Annotation deprecated added] |
+| Modified | [com.google.common.collect.MapMaker] | ![Not serializable] | ![Method less accessible] |
+| Modified | [com.google.common.collect.Maps] | ![Not serializable] | ![Annotation added] ![Method added to public class] |
+| Unchanged | [com.google.common.collect.MultimapBuilder] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.collect.Multimaps] | ![Not serializable] | ![Annotation added] |
+| Modified | [com.google.common.collect.Multisets] | ![Not serializable] | ![Annotation added] ![Method added to public class] |
+| Modified | [com.google.common.collect.RangeMap] | ![Not serializable] | ![Method added to interface] |
+| Modified | [com.google.common.collect.RangeSet] | ![Not serializable] | ![Method added to interface] |
+| Unchanged | [com.google.common.collect.Sets] | ![Not serializable] | ![Annotation added] ![Annotation deprecated added] |
+| Unchanged | [com.google.common.collect.Table] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.collect.Table$Cell] | ![Not serializable] | ![Annotation added] |
+| Modified | [com.google.common.collect.TreeRangeMap] | ![Not serializable] | ![Method added to public class] |
+| Modified | [com.google.common.collect.TreeRangeSet] | ![Not serializable] | ![Method added to public class] |
+| Modified | [com.google.common.eventbus.AsyncEventBus] | ![Not serializable] | ![Method removed] |
+| Modified | [com.google.common.eventbus.DeadEvent] | ![Not serializable] | ![Method added to public class] |
+| Modified | [com.google.common.eventbus.EventBus] | ![Not serializable] | ![Method added to public class] |
+| Modified | [com.google.common.hash.BloomFilter] | ![Default serialversionuid changed] | ![Annotation added] ![Method added to public class] |
+| Unchanged | [com.google.common.hash.Funnels] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.hash.HashCode] | ![Not serializable] | ![Annotation added] |
+| Modified | [com.google.common.hash.Hasher] | ![Not serializable] | ![Annotation added] ![Annotation deprecated added] ![Method added to interface] |
+| Modified | [com.google.common.hash.Hashing] | ![Not serializable] | ![Annotation added] ![Method added to public class] |
+| Unchanged | [com.google.common.hash.HashingInputStream] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.hash.HashingOutputStream] | ![Not serializable] | ![Annotation added] |
+| Modified | [com.google.common.io.BaseEncoding] | ![Not serializable] | ![Method now abstract] |
+| Modified | [com.google.common.io.ByteSource] | ![Not serializable] | ![Method added to public class] |
+| Modified | [com.google.common.io.CharSource] | ![Not serializable] | ![Method added to public class] |
+| Modified | [com.google.common.net.HttpHeaders] | ![Not serializable] | ![No changes] |
+| Modified | [com.google.common.net.MediaType] | ![Not serializable] | ![No changes] |
+| Unchanged | [com.google.common.primitives.Booleans] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.primitives.Bytes] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.primitives.Chars] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.primitives.Doubles] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.primitives.Floats] | ![Not serializable] | ![Annotation added] |
+| Modified | [com.google.common.primitives.Ints] | ![Not serializable] | ![Annotation added] |
+| Modified | [com.google.common.primitives.Longs] | ![Not serializable] | ![Annotation added] ![Method added to public class] |
+| Unchanged | [com.google.common.primitives.Primitives] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.primitives.Shorts] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.primitives.SignedBytes] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.primitives.UnsignedBytes] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.primitives.UnsignedInteger] | ![Compatible] | ![Annotation added] ![Annotation removed] |
+| Unchanged | [com.google.common.primitives.UnsignedInts] | ![Not serializable] | ![Annotation added] |
+| Unchanged | [com.google.common.primitives.UnsignedLong] | ![Compatible] | ![Annotation added] |
+| Unchanged | [com.google.common.primitives.UnsignedLongs] | ![Not serializable] | ![Annotation added] |
+| Modified | [com.google.common.reflect.ClassPath$ResourceInfo] | ![Not serializable] | ![No changes] |
+| Modified | [com.google.common.reflect.TypeToken] | ![Default serialversionuid changed] | ![Annotation deprecated added] ![Method added to public class] |
+| Modified | [com.google.common.util.concurrent.AbstractFuture] | ![Not serializable] | ![No changes] |
+| Modified | [com.google.common.util.concurrent.AbstractListeningExecutorService] | ![Not serializable] | ![Method return type changed] |
+| Unchanged | [com.google.common.util.concurrent.FutureFallback] | ![Not serializable] | ![Annotation deprecated added] |
+| Modified | [com.google.common.util.concurrent.Futures] | ![Not serializable] | ![Annotation added] ![Annotation deprecated added] ![Superclass added] ![Method added to public class] |
+| Modified | [com.google.common.util.concurrent.SettableFuture] | ![Not serializable] | ![Superclass added] ![Method added to public class] |
+
+
+Expand for details.
+
+___
+
+
+### `com.google.common.base.Ascii`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|---------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Ascii` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-------------------|----------|------------|-------------------------------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `static` `public` | | [`String`] | `truncate`([`CharSequence`], `int`, [`String`]) | ~~[`CheckReturnValue`]~~ | | ![Annotation removed] |
+
+___
+
+
+### `com.google.common.base.CaseFormat`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|---------------------|------|--------------|-------------|-------|---------------|-----------------------|
+| Unchanged | `public` `abstract` | Enum | `CaseFormat` | [`Enum`] | JDK 6 | ![Compatible] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+___
+
+
+### `com.google.common.base.CharMatcher`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|---------------------|-------|---------------|------------|-------|---------------------|-----------------------|
+| Modified | `public` `abstract` | Class | `CharMatcher` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|---------------------------|----------|---------------------|----------------------------|-------------|--------|-----------------------|
+| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`any`**() | | | ![Method added to public class] |
+| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`ascii`**() | | | ![Method added to public class] |
+| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`breakingWhitespace`**() | | | ![Method added to public class] |
+| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`digit`**() | | | ![Method added to public class] |
+| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`invisible`**() | | | ![Method added to public class] |
+| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`javaDigit`**() | | | ![Method added to public class] |
+| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`javaIsoControl`**() | | | ![Method added to public class] |
+| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`javaLetter`**() | | | ![Method added to public class] |
+| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`javaLetterOrDigit`**() | | | ![Method added to public class] |
+| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`javaLowerCase`**() | | | ![Method added to public class] |
+| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`javaUpperCase`**() | | | ![Method added to public class] |
+| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`none`**() | | | ![Method added to public class] |
+| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`singleWidth`**() | | | ![Method added to public class] |
+| Added | **`static`** **`public`** | | **[`CharMatcher`]** | **`whitespace`**() | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.base.Defaults`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Defaults` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+___
+
+
+### `com.google.common.base.Enums`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|---------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Enums` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+___
+
+
+### `com.google.common.base.Equivalence`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|---------------------|-------|---------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `public` `abstract` | Class | `Equivalence` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `T` | [`Object`] | ![No changes] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+___
+
+
+### `com.google.common.base.Functions`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|-------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Functions` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+___
+
+
+### `com.google.common.base.Joiner`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|-----------|-------|----------|------------|-------|---------------------|-----------------------|
+| Unchanged | `public` | Class | `Joiner` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-------------------|----------|------------|-----------------------------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `final` `public` | | [`String`] | `join`([`Iterable>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `final` `public` | | [`String`] | `join`([`Iterator>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `final` `public` | | [`String`] | `join`([`Object[]`][1]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `final` `public` | | [`String`] | `join`([`Object`], [`Object`], [`Object...`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`Joiner`] | `on`([`String`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`Joiner`] | `on`(`char`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.base.Joiner$MapJoiner`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|---------------------------|-------|-------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `static` `public` | Class | `MapJoiner` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-----------|----------|------------|-----------------------------------------------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `public` | | [`String`] | `join`([`Map, ?>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `public` | | [`String`] | `join`([`Iterable extends Entry extends ?, ? extends ?>>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `public` | | [`String`] | `join`([`Iterator extends Entry extends ?, ? extends ?>>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.base.MoreObjects`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|---------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `MoreObjects` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-------------------|--------------------------|--------------------|--------------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `static` `public` | \<[`T extends Object`]\> | [`Object`] | `firstNonNull`(`T`, `T`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`ToStringHelper`] | `toStringHelper`([`Object`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`ToStringHelper`] | `toStringHelper`([`Class>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`ToStringHelper`] | `toStringHelper`([`String`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.base.MoreObjects$ToStringHelper`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|---------------------------|-------|------------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `static` `public` | Class | `ToStringHelper` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-----------|----------|------------|--------------|--------------------------|--------|-----------------------|
+| Unchanged | `public` | | [`String`] | `toString`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.base.Objects`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|-----------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Objects` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-------------------|--------------------------|-----------------------|--------------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `static` `public` | \<[`T extends Object`]\> | [`Object`] | `firstNonNull`(`T`, `T`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | `int` | `hashCode`([`Object...`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`ToStringHelper`][2] | `toStringHelper`([`Object`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`ToStringHelper`][2] | `toStringHelper`([`Class>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`ToStringHelper`][2] | `toStringHelper`([`String`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.base.Optional`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|---------------------|-------|------------|------------|-------|---------------|-----------------------|
+| Unchanged | `public` `abstract` | Class | `Optional` | [`Object`] | JDK 6 | ![Compatible] | ![Annotation added] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `T` | [`Object`] | ![No changes] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+___
+
+
+### `com.google.common.base.Predicates`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|--------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Predicates` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+___
+
+
+### `com.google.common.base.Splitter`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Splitter` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-------------------|----------|----------------------|---------------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `static` `public` | | [`Splitter`] | `fixedLength`(`int`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`Splitter`] | `on`(`char`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`Splitter`] | `on`([`CharMatcher`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`Splitter`] | `on`([`String`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`Splitter`] | `on`([`Pattern`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`Splitter`] | `onPattern`([`String`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `public` | | [`Iterable`] | `split`([`CharSequence`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `public` | | [`List`] | `splitToList`([`CharSequence`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.base.Splitter$MapSplitter`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|---------------------------|-------|---------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `static` `public` | Class | `MapSplitter` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-----------|----------|-------------------------|---------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `public` | | [`Map`] | `split`([`CharSequence`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.base.StandardSystemProperty`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|------|--------------------------|-------------|-------|---------------|-----------------------|
+| Unchanged | `final` `public` | Enum | `StandardSystemProperty` | [`Enum`] | JDK 6 | ![Compatible] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+___
+
+
+### `com.google.common.base.Stopwatch`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|-------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Stopwatch` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-------------------|----------|---------------|-------------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `static` `public` | | [`Stopwatch`] | `createStarted`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`Stopwatch`] | `createStarted`([`Ticker`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`Stopwatch`] | `createUnstarted`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`Stopwatch`] | `createUnstarted`([`Ticker`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `public` | | `long` | `elapsed`([`TimeUnit`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `public` | | `boolean` | `isRunning`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.base.Strings`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|-----------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Strings` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+___
+
+
+### `com.google.common.base.Suppliers`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|-------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Suppliers` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+___
+
+
+### `com.google.common.base.Throwables`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|------------------|-------|--------------|------------|-------|---------------------|-----------------------|
+| Modified | `final` `public` | Class | `Throwables` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|---------------------------|----------|---------------------------------|----------------------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `static` `public` | | [`List`] | `getCausalChain`([`Throwable`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`Throwable`] | `getRootCause`([`Throwable`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`String`] | `getStackTraceAsString`([`Throwable`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Added | **`static`** **`public`** | | **[`List`]** | **`lazyStackTrace`**([`Throwable`]) | **[`CheckReturnValue`]** | | ![Method added to public class] ![Annotation added] |
+| Added | **`static`** **`public`** | | **`boolean`** | **`lazyStackTraceIsLazy`**() | **[`CheckReturnValue`]** | | ![Method added to public class] ![Annotation added] |
+
+___
+
+
+### `com.google.common.base.Ticker`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|---------------------|-------|----------|------------|-------|---------------------|-----------------------|
+| Unchanged | `public` `abstract` | Class | `Ticker` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-------------------|----------|------------|------------------|--------------------------|--------|-----------------------|
+| Unchanged | `static` `public` | | [`Ticker`] | `systemTicker`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.base.Utf8`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|--------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Utf8` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-------------------|----------|-----------|----------------------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `static` `public` | | `int` | `encodedLength`([`CharSequence`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | `boolean` | `isWellFormed`(`byte[]`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | `boolean` | `isWellFormed`(`byte[]`, `int`, `int`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.base.VerifyException`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [ ] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|-----------|-------|-------------------|----------------------|-------|-------------------------------------|-----------------------|
+| Modified | `public` | Class | `VerifyException` | [`RuntimeException`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] |
+
+
+#### Constructors
+
+| Status | Modifiers | Generics | Constructor | Annotations | Throws | Compatibility Changes |
+|--------|--------------|----------|--------------------------------------------------|-------------|--------|-----------------------|
+| Added | **`public`** | | **`VerifyException`**([`Throwable`]) | | | ![No changes] |
+| Added | **`public`** | | **`VerifyException`**([`String`], [`Throwable`]) | | | ![No changes] |
+
+___
+
+
+### `com.google.common.cache.CacheLoader$UnsupportedLoadingOperationException`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [ ] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|-------------------------------|-------|------------------------------------|-----------------------------------|-------|-------------------------------------|-----------------------|
+| Modified | `final` `static` **`public`** | Class | `UnsupportedLoad…erationException` | [`UnsupportedOperationException`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] |
+
+___
+
+
+### `com.google.common.cache.RemovalNotification`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|------------------|-------|-----------------------|------------|-------|---------------------|-----------------------|
+| Modified | `final` `public` | Class | `RemovalNotification` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `K` | [`Object`] | ![No changes] |
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|---------------------------|--------------------------------------------------------|-----------------------------------|------------------------------------------|-------------|--------|-----------------------|
+| Added | **`static`** **`public`** | \<**[`K extends Object`]**, **[`V extends Object`]**\> | **[`RemovalNotification`]** | **`create`**(`K`, `V`, [`RemovalCause`]) | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.collect.BiMap`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|---------------------|-----------|---------|------------|-------|---------------------|-----------------------|
+| Unchanged | `public` `abstract` | Interface | `BiMap` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `K` | [`Object`] | ![No changes] |
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|---------------------|----------|------------|----------------------|------------------|--------|-----------------------|
+| Unchanged | `public` `abstract` | | [`Object`] | `forcePut`(`K`, `V`) | **[`Nullable`]** | | ![Annotation added] |
+| Unchanged | `public` `abstract` | | [`Object`] | `put`(`K`, `V`) | **[`Nullable`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.collect.Collections2`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|----------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Collections2` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-------------------|--------------------------|-------------------|-------------------------------------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `static` `public` | \<[`E extends Object`]\> | [`Collection`] | `filter`([`Collection`], [`Predicate super E>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.collect.ComparisonChain`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|---------------------|-------|-------------------|------------|-------|---------------------|-----------------------|
+| Modified | `public` `abstract` | Class | `ComparisonChain` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|--------------------------|----------|-------------------------|-----------------------------------------|--------------------|--------|-----------------------|
+| Added | **`final`** **`public`** | | **[`ComparisonChain`]** | **`compare`**([`Boolean`], [`Boolean`]) | **[`Deprecated`]** | | ![Method added to public class] ![Annotation deprecated added] |
+
+___
+
+
+### `com.google.common.collect.FluentIterable`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|---------------------|-------|------------------|------------|-------|---------------------|-----------------------|
+| Modified | `public` `abstract` | Class | `FluentIterable` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `E` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|--------------------------|--------------------------|---------------------------------|-------------------------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `final` `public` | | `boolean` | `allMatch`([`Predicate super E>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `final` `public` | | `boolean` | `anyMatch`([`Predicate super E>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `final` `public` | | `boolean` | `contains`([`Object`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `final` `public` | | [`Optional`] | `first`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `final` `public` | | [`Optional`] | `firstMatch`([`Predicate super E>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`E extends Object`]\> | [`FluentIterable`] | `from`([`Iterable`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`E extends Object`]\> | [`FluentIterable`] | `from`([`FluentIterable`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `final` `public` | | [`Object`] | `get`(`int`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `final` `public` | \<[`K extends Object`]\> | [`ImmutableListMultimap`] | `index`([`Function super E, K>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `final` `public` | | `boolean` | `isEmpty`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `final` `public` | | [`String`] | `join`([`Joiner`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `final` `public` | | [`Optional`] | `last`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`E extends Object`]\> | [`FluentIterable`] | `of`([`Object[]`][1]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `final` `public` | | `int` | `size`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `final` `public` | | [`Object[]`][1] | `toArray`([`Class`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `final` `public` | | [`ImmutableList`] | `toList`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `final` `public` | \<[`V extends Object`]\> | [`ImmutableMap`] | `toMap`([`Function super E, V>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Added | **`final`** **`public`** | | **[`ImmutableMultiset`]** | **`toMultiset`**() | **[`CheckReturnValue`]** | | ![Method added to public class] ![Annotation added] |
+| Unchanged | `final` `public` | | [`ImmutableSet`] | `toSet`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `final` `public` | | [`ImmutableList`] | `toSortedList`([`Comparator super E>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `final` `public` | | [`ImmutableSortedSet`] | `toSortedSet`([`Comparator super E>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `public` | | [`String`] | `toString`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `final` `public` | \<[`T extends Object`]\> | [`FluentIterable`] | `transform`([`Function super E, T>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `public` | \<[`T extends Object`]\> | [`FluentIterable`] | `transformAndConcat`([`Function super E, ? extends Iterable extends T>>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `final` `public` | \<[`K extends Object`]\> | [`ImmutableMap`] | `uniqueIndex`([`Function super E, K>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.collect.HashBiMap`
+
+- [X] Binary-compatible
+- [ ] Source-compatible
+- [ ] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|------------------|-------|-------------|---------|-------|------------------------|-----------------------|
+| Modified | `final` `public` | Class | `HashBiMap` | ~~[`AbstractMap`]~~ → **[`IteratorBasedAbstractMap`]** | JDK 6 | ![Superclass modified] | ![Superclass added] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `K` | [`Object`] | ![No changes] |
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|---------------------|---------------------------------------|----------|---------------------------------------------|--------------|-------------|--------|-----------------------|
+| Source-incompatible | `public` **`bridge`** **`synthetic`** | | ~~[`Set>`]~~ → **[`Set`]** | `entrySet`() | | | ![Method return type generics changed] |
+
+___
+
+
+### `com.google.common.collect.ImmutableBiMap`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [ ] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|---------------------|-------|------------------|------------------------|-------|-------------------------------------|-----------------------|
+| Modified | `public` `abstract` | Class | `ImmutableBiMap` | [`ImmutableMap`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `K` | [`Object`] | ![No changes] |
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|---------------------------|--------------------------------------------------------|------------------------------|--------|-------------|--------|-----------------------|
+| Added | **`static`** **`public`** | \<**[`K extends Object`]**, **[`V extends Object`]**\> | **[`ImmutableBiMap`]** | **`copyOf`**([`Iterable extends Entry extends K, ? extends V>>`]) | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.collect.ImmutableBiMap$Builder`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|---------------------------|-------|-----------|-------------------|-------|---------------------|-----------------------|
+| Modified | `final` `static` `public` | Class | `Builder` | [`Builder`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `K` | [`Object`] | ![No changes] |
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|--------------|----------|--------------------------|------------------------------------------------------|-------------|--------|-----------------------|
+| Added | **`public`** | | **[`Builder`][3]** | **`orderEntriesByValue`**([`Comparator super V>`]) | | | ![Method added to public class] |
+| Added | **`public`** | | **[`Builder`][3]** | **`put`**([`Entry extends K, ? extends V>`]) | | | ![Method added to public class] |
+| Added | **`public`** | | **[`Builder`][3]** | **`putAll`**([`Iterable extends Entry extends K, ? extends V>>`]) | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.collect.ImmutableClassToInstanceMap`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [ ] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|------------------|-------|-------------------------------|-------------------------|-------|-------------------------------------|-----------------------|
+| Modified | `final` `public` | Class | `ImmutableClassToInstanceMap` | [`ForwardingMap`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `B` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|---------------------------|-------------------------------------------------|----------------------------------------|-----------------------------|-------------|--------|-----------------------|
+| Added | **`static`** **`public`** | \<**[`B extends Object`]**\> | **[`ImmutableClassToInstanceMap`]** | **`of`**() | | | ![Method added to public class] |
+| Added | **`static`** **`public`** | \<**[`B extends Object`]**, **`T extends B`**\> | **[`ImmutableClassToInstanceMap`]** | **`of`**([`Class`], `T`) | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.collect.ImmutableCollection`
+
+- [ ] Binary-compatible
+- [ ] Source-compatible
+- [ ] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|---------------------|-------|-----------------------|---------------------------|-------|-------------------------------------|-----------------------|
+| Modified | `public` `abstract` | Class | `ImmutableCollection` | [`AbstractCollection`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `E` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|----------|-------------------------|----------|-----------|------------------------|-------------|--------|-----------------------|
+| Modified | `public` **`abstract`** | | `boolean` | `contains`([`Object`]) | | | ![Method now abstract] |
+
+___
+
+
+### `com.google.common.collect.ImmutableList`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [ ] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------------------------|---------------------|-------|-----------------|----------------------------|-------|-------------------------------------|-----------------------|
+| Serialization-incompatible | `public` `abstract` | Class | `ImmutableList` | [`ImmutableCollection`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `E` | [`Object`] | ![No changes] |
+
+___
+
+
+### `com.google.common.collect.ImmutableListMultimap`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|-----------|-------|-------------------------|-----------------------------|-------|---------------|-----------------------|
+| Modified | `public` | Class | `ImmutableListMultimap` | [`ImmutableMultimap`] | JDK 6 | ![Compatible] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `K` | [`Object`] | ![No changes] |
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|---------------------------|--------------------------------------------------------|-------------------------------------|--------|-------------|--------|-----------------------|
+| Added | **`static`** **`public`** | \<**[`K extends Object`]**, **[`V extends Object`]**\> | **[`ImmutableListMultimap`]** | **`copyOf`**([`Iterable extends Entry extends K, ? extends V>>`]) | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.collect.ImmutableListMultimap$Builder`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|---------------------------|-------|-----------|----------------------|-------|---------------------|-----------------------|
+| Modified | `final` `static` `public` | Class | `Builder` | [`Builder`][4] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `K` | [`Object`] | ![No changes] |
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|--------------|----------|--------------------------|--------|-------------|--------|-----------------------|
+| Added | **`public`** | | **[`Builder`][5]** | **`putAll`**([`Iterable extends Entry extends K, ? extends V>>`]) | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.collect.ImmutableMap`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [ ] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|---------------------|-------|----------------|------------|-------|-------------------------------------|-----------------------|
+| Modified | `public` `abstract` | Class | `ImmutableMap` | [`Object`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `K` | [`Object`] | ![No changes] |
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|---------------------------|--------------------------------------------------------|-------------------------------|--------|-------------|--------|-----------------------|
+| Added | **`static`** **`public`** | \<**[`K extends Object`]**, **[`V extends Object`]**\> | **[`ImmutableMap`][6]** | **`copyOf`**([`Iterable extends Entry extends K, ? extends V>>`]) | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.collect.ImmutableMap$Builder`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|-------------------|-------|-----------|------------|-------|---------------------|-----------------------|
+| Modified | `static` `public` | Class | `Builder` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `K` | [`Object`] | ![No changes] |
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|--------------|----------|--------------------------|------------------------------------------------------|-------------|--------|-----------------------|
+| Added | **`public`** | | **[`Builder`][7]** | **`orderEntriesByValue`**([`Comparator super V>`]) | | | ![Method added to public class] |
+| Added | **`public`** | | **[`Builder`][7]** | **`putAll`**([`Iterable extends Entry extends K, ? extends V>>`]) | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.collect.ImmutableMultimap`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|---------------------|-------|---------------------|----------------------------|-------|---------------|-----------------------|
+| Modified | `public` `abstract` | Class | `ImmutableMultimap` | [`AbstractMultimap`] | JDK 6 | ![Compatible] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `K` | [`Object`] | ![No changes] |
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|---------------------------|--------------------------------------------------------|------------------------------------|--------|-------------|--------|-----------------------|
+| Added | **`static`** **`public`** | \<**[`K extends Object`]**, **[`V extends Object`]**\> | **[`ImmutableMultimap`][8]** | **`copyOf`**([`Iterable extends Entry extends K, ? extends V>>`]) | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.collect.ImmutableMultimap$Builder`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|-------------------|-------|-----------|------------|-------|---------------------|-----------------------|
+| Modified | `static` `public` | Class | `Builder` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `K` | [`Object`] | ![No changes] |
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|--------------|----------|--------------------------|--------|-------------|--------|-----------------------|
+| Added | **`public`** | | **[`Builder`][9]** | **`putAll`**([`Iterable extends Entry extends K, ? extends V>>`]) | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.collect.ImmutableMultiset`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [ ] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|---------------------|-------|---------------------|----------------------------|-------|-------------------------------------|-----------------------|
+| Modified | `public` `abstract` | Class | `ImmutableMultiset` | [`ImmutableCollection`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `E` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|---------|--------------|----------|---------------|--------------------------------------|-------------|--------|-----------------------|
+| Removed | ~~`public`~~ | | ~~`boolean`~~ | ~~`containsAll`~~([`Collection>`]) | | | ![No changes] |
+
+___
+
+
+### `com.google.common.collect.ImmutableRangeMap`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|-----------|-------|---------------------|------------|-------|---------------|-----------------------|
+| Modified | `public` | Class | `ImmutableRangeMap` | [`Object`] | JDK 6 | ![Compatible] | ![Interface added] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|-------------------|-----------------------|
+| Unchanged | `K` | [`Comparable>`] | ![No changes] |
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Implemented Interfaces
+
+| Status | Interface | Compatibility Changes |
+|---------------------|----------------------|-----------------------|
+| Source-incompatible | [`RangeMap`] | ![No changes] |
+| Added | **[`Serializable`]** | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|--------------|----------|-----------------------------------|---------------------------------|-------------|--------|-----------------------|
+| Added | **`public`** | | **[`ImmutableMap, V>`]** | **`asDescendingMapOfRanges`**() | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.collect.ImmutableRangeSet`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [ ] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|------------------|-------|---------------------|-------------------------|-------|-------------------------------------|-----------------------|
+| Modified | `final` `public` | Class | `ImmutableRangeSet` | [`AbstractRangeSet`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|----------------|-----------------------|
+| Unchanged | `C` | [`Comparable`] | ![No changes] |
+
+
+#### Implemented Interfaces
+
+| Status | Interface | Compatibility Changes |
+|---------------------|-----------------|-----------------------|
+| Source-incompatible | [`RangeSet`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|--------------|----------|--------------------------------|---------------------------------|-------------|--------|-----------------------|
+| Added | **`public`** | | **[`ImmutableSet>`]** | **`asDescendingSetOfRanges`**() | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.collect.ImmutableSetMultimap`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|-----------|-------|------------------------|-----------------------------|-------|---------------|-----------------------|
+| Modified | `public` | Class | `ImmutableSetMultimap` | [`ImmutableMultimap`] | JDK 6 | ![Compatible] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `K` | [`Object`] | ![No changes] |
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|---------------------------|--------------------------------------------------------|------------------------------------|--------|-------------|--------|-----------------------|
+| Added | **`static`** **`public`** | \<**[`K extends Object`]**, **[`V extends Object`]**\> | **[`ImmutableSetMultimap`]** | **`copyOf`**([`Iterable extends Entry extends K, ? extends V>>`]) | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.collect.ImmutableSetMultimap$Builder`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|---------------------------|-------|-----------|----------------------|-------|---------------------|-----------------------|
+| Modified | `final` `static` `public` | Class | `Builder` | [`Builder`][4] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `K` | [`Object`] | ![No changes] |
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|--------------|----------|---------------------------|--------|-------------|--------|-----------------------|
+| Added | **`public`** | | **[`Builder`][10]** | **`putAll`**([`Iterable extends Entry extends K, ? extends V>>`]) | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.collect.ImmutableSortedMap`
+
+- [ ] Binary-compatible
+- [ ] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|-------------------------------------|-------|----------------------|--------------------------------------------|-------|---------------|-----------------------|
+| Modified | **`final`** `public` ~~`abstract`~~ | Class | `ImmutableSortedMap` | [`ImmutableSortedMapFauxverideShim`] | JDK 6 | ![Compatible] | ![Class now final] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `K` | [`Object`] | ![No changes] |
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|----------|---------------------------|--------------------------------------------------------|----------------------------------|---------------------------------|-------------|--------|-----------------------|
+| Removed | ~~`public`~~ | | ~~`boolean`~~ | ~~`containsValue`~~([`Object`]) | | | ![No changes] |
+| Added | **`static`** **`public`** | \<**[`K extends Object`]**, **[`V extends Object`]**\> | **[`ImmutableSortedMap`]** | **`copyOf`**([`Iterable extends Entry extends K, ? extends V>>`]) | | | ![Method added to public class] |
+| Added | **`static`** **`public`** | \<**[`K extends Object`]**, **[`V extends Object`]**\> | **[`ImmutableSortedMap`]** | **`copyOf`**([`Iterable extends Entry extends K, ? extends V>>`], [`Comparator super K>`]) | | | ![Method added to public class] |
+| Added | **`public`** | | **[`Object`]** | **`get`**([`Object`]) | | | ![Method added to public class] |
+| Modified | `public` ~~`abstract`~~ | | [`ImmutableSortedMap`] | `headMap`(`K`, `boolean`) | | | ![No changes] |
+| Modified | `public` ~~`abstract`~~ | | [`ImmutableSortedSet`] | `keySet`() | | | ![No changes] |
+| Modified | `public` ~~`abstract`~~ | | [`ImmutableSortedMap`] | `tailMap`(`K`, `boolean`) | | | ![No changes] |
+| Modified | `public` ~~`abstract`~~ | | [`ImmutableCollection`] | `values`() | | | ![No changes] |
+
+___
+
+
+### `com.google.common.collect.ImmutableSortedMap$Builder`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|-------------------|-------|-----------|-------------------|-------|---------------------|-----------------------|
+| Modified | `static` `public` | Class | `Builder` | [`Builder`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `K` | [`Object`] | ![No changes] |
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|--------------|----------|---------------------------|------------------------------------------------------|--------------------|--------|-----------------------|
+| Added | **`public`** | | **[`Builder`][11]** | **`orderEntriesByValue`**([`Comparator super V>`]) | **[`Deprecated`]** | | ![Method added to public class] ![Annotation deprecated added] |
+| Added | **`public`** | | **[`Builder`][11]** | **`putAll`**([`Iterable extends Entry extends K, ? extends V>>`]) | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.collect.ImmutableSortedMultiset`
+
+- [X] Binary-compatible
+- [ ] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|---------------------|---------------------|-------|---------------------------|-----------------------------------------|-------|---------------|-----------------------|
+| Source-incompatible | `public` `abstract` | Class | `ImmutableSortedMultiset` | [`ImmutableSorted…etFauxverideShim`] | JDK 6 | ![Compatible] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `E` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|---------------------|-------------------|----------|----------------|------------------|-------------|--------|-----------------------|
+| Source-incompatible | `static` `public` | \<~~[`E extends Comparable`]~~ → **[`E extends Comparable>`]**\> | [`Builder`] | `naturalOrder`() | | | ![Class generic template generics changed] |
+| Source-incompatible | `static` `public` | \<~~[`E extends Comparable`]~~ → **[`E extends Comparable>`]**\> | [`Builder`] | `reverseOrder`() | | | ![Class generic template generics changed] |
+
+___
+
+
+### `com.google.common.collect.ImmutableSortedSet`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [ ] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------------------------|---------------------|-------|----------------------|-----------------------------------------|-------|-------------------------------------|-----------------------|
+| Serialization-incompatible | `public` `abstract` | Class | `ImmutableSortedSet` | [`ImmutableSortedSetFauxverideShim`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `E` | [`Object`] | ![No changes] |
+
+___
+
+
+### `com.google.common.collect.Iterables`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|-------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Iterables` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-------------------|------------------------------------------------|-----------------|-----------------------------------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `static` `public` | | `boolean` | `elementsEqual`([`Iterable>`], [`Iterable>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`T extends Object`]\> | [`Iterable`] | `filter`([`Iterable`], [`Predicate super T>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`T extends Object`]\> | [`Iterable`] | `filter`([`Iterable>`], [`Class`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`F extends Object`], [`T extends Object`]\> | [`Iterable`] | `transform`([`Iterable`], [`Function super F, ? extends T>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.collect.Iterators`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|-------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Iterators` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-------------------|--------------------------|-----------------------------|-----------------------------------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `static` `public` | \<[`T extends Object`]\> | [`UnmodifiableIterator`] | `filter`([`Iterator`], [`Predicate super T>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`T extends Object`]\> | [`UnmodifiableIterator`] | `filter`([`Iterator>`], [`Class`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.collect.Lists`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|------------------|-------|---------|------------|-------|---------------------|-----------------------|
+| Modified | `final` `public` | Class | `Lists` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-----------------------|------------------------------------------------|-------------------|----------------------------------------------------------------|--------------------------|--------|-----------------------|
+| Modified | `static` **`public`** | \<[`B extends Object`]\> | [`List>`] | `cartesianProduct`([`List extends List extends B>>`]) | | | ![No changes] |
+| Modified | `static` **`public`** | \<[`B extends Object`]\> | [`List>`] | `cartesianProduct`([`List... extends B>`]) | | | ![No changes] |
+| Unchanged | `static` `public` | \<[`T extends Object`]\> | [`List`] | `reverse`([`List`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`F extends Object`], [`T extends Object`]\> | [`List`] | `transform`([`List`], [`Function super F, ? extends T>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.collect.MapConstraint`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|---------------------|-----------|-----------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `public` `abstract` | Interface | `MapConstraint` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation deprecated added] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `K` | [`Object`] | ![No changes] |
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------|-----------------------|
+| Added | **[`Deprecated`]** | ![No changes] |
+
+___
+
+
+### `com.google.common.collect.MapConstraints`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|------------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `MapConstraints` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation deprecated added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------|-----------------------|
+| Added | **[`Deprecated`]** | ![No changes] |
+
+___
+
+
+### `com.google.common.collect.MapMaker`
+
+- [ ] Binary-compatible
+- [ ] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|------------------|-------|------------|-----------------------------|-------|---------------------|-----------------------|
+| Modified | `final` `public` | Class | `MapMaker` | [`GenericMapMaker`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|----------|--------------|----------|--------------|----------------|-------------|--------|-----------------------|
+| Modified | ~~`public`~~ | | [`MapMaker`] | `softValues`() | | | ![Method less accessible] |
+
+___
+
+
+### `com.google.common.collect.Maps`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|------------------|-------|--------|------------|-------|---------------------|-----------------------|
+| Modified | `final` `public` | Class | `Maps` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|---------------------------|--------------------------------------------------------|-----------------------------|------------------------------------------------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`Map`] | `filterEntries`([`Map`], [`Predicate super Entry super K, ? super V>>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`SortedMap`] | `filterEntries`([`SortedMap`], [`Predicate super Entry super K, ? super V>>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`NavigableMap`] | `filterEntries`([`NavigableMap`], [`Predicate super Entry super K, ? super V>>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`BiMap`] | `filterEntries`([`BiMap`], [`Predicate super Entry super K, ? super V>>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`Map`] | `filterKeys`([`Map`], [`Predicate super K>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`SortedMap`] | `filterKeys`([`SortedMap`], [`Predicate super K>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`NavigableMap`] | `filterKeys`([`NavigableMap`], [`Predicate super K>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`BiMap`] | `filterKeys`([`BiMap`], [`Predicate super K>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`Map`] | `filterValues`([`Map`], [`Predicate super V>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`SortedMap`] | `filterValues`([`SortedMap`], [`Predicate super V>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`NavigableMap`] | `filterValues`([`NavigableMap`], [`Predicate super V>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`BiMap`] | `filterValues`([`BiMap`], [`Predicate super V>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Added | **`static`** **`public`** | \<**[`K extends Object`]**, **[`V extends Object`]**\> | **[`LinkedHashMap`]** | **`newLinkedHashMapWithExpectedSize`**(`int`) | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.collect.MultimapBuilder`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|---------------------|-------|-------------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `public` `abstract` | Class | `MultimapBuilder` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `K0` | [`Object`] | ![No changes] |
+| Unchanged | `V0` | [`Object`] | ![No changes] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+___
+
+
+### `com.google.common.collect.Multimaps`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|-------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Multimaps` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-------------------|------------------------------------------------|------------------------|-----------------------------------------------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`Multimap`] | `filterEntries`([`Multimap`], [`Predicate super Entry super K, ? super V>>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`SetMultimap`] | `filterEntries`([`SetMultimap`], [`Predicate super Entry super K, ? super V>>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`Multimap`] | `filterKeys`([`Multimap`], [`Predicate super K>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`SetMultimap`] | `filterKeys`([`SetMultimap`], [`Predicate super K>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`ListMultimap`] | `filterKeys`([`ListMultimap`], [`Predicate super K>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`Multimap`] | `filterValues`([`Multimap`], [`Predicate super V>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`K extends Object`], [`V extends Object`]\> | [`SetMultimap`] | `filterValues`([`SetMultimap`], [`Predicate super V>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.collect.Multisets`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|------------------|-------|-------------|------------|-------|---------------------|-----------------------|
+| Modified | `final` `public` | Class | `Multisets` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|---------------------------|--------------------------|-----------------|-----------------------------------------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `static` `public` | \<[`E extends Object`]\> | [`Multiset`] | `filter`([`Multiset`], [`Predicate super E>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Added | **`static`** **`public`** | | **`boolean`** | **`removeOccurrences`**([`Multiset>`], [`Multiset>`]) | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.collect.RangeMap`
+
+- [X] Binary-compatible
+- [ ] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|---------------------|-----------|------------|------------|-------|---------------------|-----------------------|
+| Modified | `public` `abstract` | Interface | `RangeMap` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|----------------|-----------------------|
+| Unchanged | `K` | [`Comparable`] | ![No changes] |
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|-----------------------------|----------|--------------------------|---------------------------------|-------------|--------|-----------------------|
+| Added | **`public`** **`abstract`** | | **[`Map, V>`]** | **`asDescendingMapOfRanges`**() | | | ![Method added to interface] |
+
+___
+
+
+### `com.google.common.collect.RangeSet`
+
+- [X] Binary-compatible
+- [ ] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|---------------------|-----------|------------|------------|-------|---------------------|-----------------------|
+| Modified | `public` `abstract` | Interface | `RangeSet` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|----------------|-----------------------|
+| Unchanged | `C` | [`Comparable`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|-----------------------------|----------|-----------------------|---------------------------------|-------------|--------|-----------------------|
+| Added | **`public`** **`abstract`** | | **[`Set>`]** | **`asDescendingSetOfRanges`**() | | | ![Method added to interface] |
+
+___
+
+
+### `com.google.common.collect.Sets`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|--------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Sets` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-------------------|--------------------------|---------------------|---------------------------------------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `static` `public` | \<[`E extends Object`]\> | [`Set`] | `filter`([`Set`], [`Predicate super E>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`E extends Object`]\> | [`SortedSet`] | `filter`([`SortedSet`], [`Predicate super E>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`E extends Object`]\> | [`NavigableSet`] | `filter`([`NavigableSet`], [`Predicate super E>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`E extends Object`]\> | [`Set`] | `newSetFromMap`([`Map`]) | **[`Deprecated`]** | | ![Annotation deprecated added] |
+
+___
+
+
+### `com.google.common.collect.Table`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|---------------------|-----------|---------|------------|-------|---------------------|-----------------------|
+| Unchanged | `public` `abstract` | Interface | `Table` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `C` | [`Object`] | ![No changes] |
+| Unchanged | `R` | [`Object`] | ![No changes] |
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|---------------------|----------|------------|----------------------------------|------------------|--------|-----------------------|
+| Unchanged | `public` `abstract` | | [`Object`] | `put`(`R`, `C`, `V`) | **[`Nullable`]** | | ![Annotation added] |
+| Unchanged | `public` `abstract` | | [`Object`] | `remove`([`Object`], [`Object`]) | **[`Nullable`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.collect.Table$Cell`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------------------|-----------|--------|------------|-------|---------------------|-----------------------|
+| Unchanged | `static` `public` `abstract` | Interface | `Cell` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `C` | [`Object`] | ![No changes] |
+| Unchanged | `R` | [`Object`] | ![No changes] |
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|---------------------|----------|------------|------------------|------------------|--------|-----------------------|
+| Unchanged | `public` `abstract` | | [`Object`] | `getColumnKey`() | **[`Nullable`]** | | ![Annotation added] |
+| Unchanged | `public` `abstract` | | [`Object`] | `getRowKey`() | **[`Nullable`]** | | ![Annotation added] |
+| Unchanged | `public` `abstract` | | [`Object`] | `getValue`() | **[`Nullable`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.collect.TreeRangeMap`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|------------------|-------|----------------|------------|-------|---------------------|-----------------------|
+| Modified | `final` `public` | Class | `TreeRangeMap` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|----------------|-----------------------|
+| Unchanged | `K` | [`Comparable`] | ![No changes] |
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Implemented Interfaces
+
+| Status | Interface | Compatibility Changes |
+|---------------------|--------------------|-----------------------|
+| Source-incompatible | [`RangeMap`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|--------------|----------|--------------------------|---------------------------------|-------------|--------|-----------------------|
+| Added | **`public`** | | **[`Map, V>`]** | **`asDescendingMapOfRanges`**() | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.collect.TreeRangeSet`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|-----------|-------|----------------|-------------------------|-------|---------------------|-----------------------|
+| Modified | `public` | Class | `TreeRangeSet` | [`AbstractRangeSet`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|-------------------|-----------------------|
+| Unchanged | `C` | [`Comparable>`] | ![No changes] |
+
+
+#### Implemented Interfaces
+
+| Status | Interface | Compatibility Changes |
+|---------------------|-----------------|-----------------------|
+| Source-incompatible | [`RangeSet`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|--------------|----------|-----------------------|---------------------------------|-------------|--------|-----------------------|
+| Added | **`public`** | | **[`Set>`]** | **`asDescendingSetOfRanges`**() | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.eventbus.AsyncEventBus`
+
+- [ ] Binary-compatible
+- [ ] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|-----------|-------|-----------------|--------------|-------|---------------------|-----------------------|
+| Modified | `public` | Class | `AsyncEventBus` | [`EventBus`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|---------|-----------------|----------|------------|------------------------------|-------------|--------|-----------------------|
+| Removed | ~~`protected`~~ | | ~~`void`~~ | ~~`dispatchQueuedEvents`~~() | | | ![Method removed] |
+
+___
+
+
+### `com.google.common.eventbus.DeadEvent`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|-----------|-------|-------------|------------|-------|---------------------|-----------------------|
+| Modified | `public` | Class | `DeadEvent` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|--------------|----------|----------------|------------------|-------------|--------|-----------------------|
+| Added | **`public`** | | **[`String`]** | **`toString`**() | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.eventbus.EventBus`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|-----------|-------|------------|------------|-------|---------------------|-----------------------|
+| Modified | `public` | Class | `EventBus` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|--------------------------|----------|----------------|--------------------|-------------|--------|-----------------------|
+| Added | **`final`** **`public`** | | **[`String`]** | **`identifier`**() | | | ![Method added to public class] |
+| Added | **`public`** | | **[`String`]** | **`toString`**() | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.hash.BloomFilter`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [ ] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|------------------|-------|---------------|------------|-------|-------------------------------------|-----------------------|
+| Modified | `final` `public` | Class | `BloomFilter` | [`Object`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `T` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|---------------------------|------------------------------|------------------------|-------------------------------------------------------|--------------------------|-----------------|-----------------------|
+| Unchanged | `public` | | `boolean` | `apply`(`T`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `public` | | [`BloomFilter`] | `copy`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`T extends Object`]\> | [`BloomFilter`] | `create`([`Funnel super T>`], `int`, `double`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`T extends Object`]\> | [`BloomFilter`] | `create`([`Funnel super T>`], `int`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Added | **`static`** **`public`** | \<**[`T extends Object`]**\> | **[`BloomFilter`]** | **`create`**([`Funnel super T>`], `long`, `double`) | **[`CheckReturnValue`]** | | ![Method added to public class] ![Annotation added] |
+| Added | **`static`** **`public`** | \<**[`T extends Object`]**\> | **[`BloomFilter`]** | **`create`**([`Funnel super T>`], `long`) | **[`CheckReturnValue`]** | | ![Method added to public class] ![Annotation added] |
+| Unchanged | `public` | | `double` | `expectedFpp`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `public` | | `boolean` | `isCompatible`([`BloomFilter`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `public` | | `boolean` | `mightContain`(`T`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`T extends Object`]\> | [`BloomFilter`] | `readFrom`([`InputStream`], [`Funnel`]) | **[`CheckReturnValue`]** | [`IOException`] | ![Annotation added] |
+
+___
+
+
+### `com.google.common.hash.Funnels`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|-----------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Funnels` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+___
+
+
+### `com.google.common.hash.HashCode`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|---------------------|-------|------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `public` `abstract` | Class | `HashCode` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|---------------------|----------|--------------|--------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `public` `abstract` | | `byte[]` | `asBytes`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `public` `abstract` | | `int` | `asInt`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `public` `abstract` | | `long` | `asLong`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `public` `abstract` | | `int` | `bits`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`HashCode`] | `fromBytes`(`byte[]`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`HashCode`] | `fromInt`(`int`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`HashCode`] | `fromLong`(`long`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`HashCode`] | `fromString`([`String`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `public` `abstract` | | `long` | `padToLong`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.hash.Hasher`
+
+- [X] Binary-compatible
+- [ ] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|---------------------|-----------|----------|------------|-------|---------------------|-----------------------|
+| Modified | `public` `abstract` | Interface | `Hasher` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-----------------------------|----------|--------------|------------------|--------------------------|--------|-----------------------|
+| Unchanged | `public` `abstract` | | [`HashCode`] | `hash`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Added | **`public`** **`abstract`** | | **`int`** | **`hashCode`**() | **[`Deprecated`]** | | ![Method added to interface] ![Annotation deprecated added] |
+
+___
+
+
+### `com.google.common.hash.Hashing`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|------------------|-------|-----------|------------|-------|---------------------|-----------------------|
+| Modified | `final` `public` | Class | `Hashing` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|---------------------------|----------|----------------------|-------------------------------------------------|-------------|--------|-----------------------|
+| Added | **`static`** **`public`** | | **[`HashFunction`]** | **`concatenating`**([`HashFunction`], [`HashFunction`], [`HashFunction...`]) | | | ![Method added to public class] |
+| Added | **`static`** **`public`** | | **[`HashFunction`]** | **`concatenating`**([`Iterable`]) | | | ![Method added to public class] |
+| Added | **`static`** **`public`** | | **[`HashFunction`]** | **`sha384`**() | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.hash.HashingInputStream`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|----------------------|-----------------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `HashingInputStream` | [`FilterInputStream`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-----------|----------|--------------|-------------------|--------------------------|--------|-----------------------|
+| Unchanged | `public` | | [`HashCode`] | `hash`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `public` | | `boolean` | `markSupported`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.hash.HashingOutputStream`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|-----------------------|------------------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `HashingOutputStream` | [`FilterOutputStream`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-----------|----------|--------------|----------|--------------------------|--------|-----------------------|
+| Unchanged | `public` | | [`HashCode`] | `hash`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.io.BaseEncoding`
+
+- [ ] Binary-compatible
+- [ ] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|---------------------|-------|----------------|------------|-------|---------------------|-----------------------|
+| Modified | `public` `abstract` | Class | `BaseEncoding` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|----------|-------------------------------------|----------|------------------|------------------------------|-------------|--------|-----------------------|
+| Modified | ~~`final`~~ `public` **`abstract`** | | [`InputStream`] | `decodingStream`([`Reader`]) | | | ![Method now abstract] |
+| Modified | ~~`final`~~ `public` **`abstract`** | | [`OutputStream`] | `encodingStream`([`Writer`]) | | | ![Method now abstract] |
+
+___
+
+
+### `com.google.common.io.ByteSource`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|---------------------|-------|--------------|------------|-------|---------------------|-----------------------|
+| Modified | `public` `abstract` | Class | `ByteSource` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|--------------|----------|------------------------|---------------------|-------------|--------|-----------------------|
+| Added | **`public`** | | **[`Optional`]** | **`sizeIfKnown`**() | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.io.CharSource`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|---------------------|-------|--------------|------------|-------|---------------------|-----------------------|
+| Modified | `public` `abstract` | Class | `CharSource` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|--------------|----------|------------------------|-----------------------|-------------|---------------------|-----------------------|
+| Added | **`public`** | | **`long`** | **`length`**() | | **[`IOException`]** | ![Method added to public class] |
+| Added | **`public`** | | **[`Optional`]** | **`lengthIfKnown`**() | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.net.HttpHeaders`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|------------------|-------|---------------|------------|-------|---------------------|-----------------------|
+| Modified | `final` `public` | Class | `HttpHeaders` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Fields
+
+| Status | Modifiers | Type | Name | Annotations | Compatibility Changes |
+|--------|---------------------------------------|----------------|-------------|-------------|-----------------------|
+| Added | **`public`** **`static`** **`final`** | **[`String`]** | `PING_FROM` | | ![No changes] |
+| Added | **`public`** **`static`** **`final`** | **[`String`]** | `PING_TO` | | ![No changes] |
+
+___
+
+
+### `com.google.common.net.MediaType`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|------------------|-------|-------------|------------|-------|---------------------|-----------------------|
+| Modified | `final` `public` | Class | `MediaType` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Fields
+
+| Status | Modifiers | Type | Name | Annotations | Compatibility Changes |
+|--------|---------------------------------------|-------------------|-----------------------|-------------|-----------------------|
+| Added | **`public`** **`static`** **`final`** | **[`MediaType`]** | `APPLE_PASSBOOK` | | ![No changes] |
+| Added | **`public`** **`static`** **`final`** | **[`MediaType`]** | `DART_UTF_8` | | ![No changes] |
+| Added | **`public`** **`static`** **`final`** | **[`MediaType`]** | `MANIFEST_JSON_UTF_8` | | ![No changes] |
+
+___
+
+
+### `com.google.common.primitives.Booleans`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Booleans` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+___
+
+
+### `com.google.common.primitives.Bytes`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|---------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Bytes` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+___
+
+
+### `com.google.common.primitives.Chars`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|---------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Chars` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+___
+
+
+### `com.google.common.primitives.Doubles`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|-----------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Doubles` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-------------------|----------|------------|------------------------|----------------------|--------|-----------------------|
+| Unchanged | `static` `public` | | [`Double`] | `tryParse`([`String`]) | **[`CheckForNull`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.primitives.Floats`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|----------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Floats` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-------------------|----------|-----------|------------------------|----------------------|--------|-----------------------|
+| Unchanged | `static` `public` | | [`Float`] | `tryParse`([`String`]) | **[`CheckForNull`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.primitives.Ints`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|------------------|-------|--------|------------|-------|---------------------|-----------------------|
+| Modified | `final` `public` | Class | `Ints` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-----------------------|----------|-------------|-------------------------------|------------------|--------|-----------------------|
+| Unchanged | `static` `public` | | [`Integer`] | `tryParse`([`String`]) | **[`Nullable`]** | | ![Annotation added] |
+| Modified | `static` **`public`** | | [`Integer`] | `tryParse`([`String`], `int`) | **[`Nullable`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.primitives.Longs`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|------------------|-------|---------|------------|-------|---------------------|-----------------------|
+| Modified | `final` `public` | Class | `Longs` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|---------------------------|----------|--------------|-----------------------------------|------------------------------------------|--------|-----------------------|
+| Unchanged | `static` `public` | | [`Long`] | `tryParse`([`String`]) | **[`CheckForNull`]**
**[`Nullable`]** | | ![Annotation added] |
+| Added | **`static`** **`public`** | | **[`Long`]** | **`tryParse`**([`String`], `int`) | **[`CheckForNull`]**
**[`Nullable`]** | | ![Method added to public class] ![Annotation added] |
+
+___
+
+
+### `com.google.common.primitives.Primitives`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|--------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Primitives` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+___
+
+
+### `com.google.common.primitives.Shorts`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|----------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `Shorts` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+___
+
+
+### `com.google.common.primitives.SignedBytes`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|---------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `SignedBytes` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+___
+
+
+### `com.google.common.primitives.UnsignedBytes`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|-----------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `UnsignedBytes` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-------------------|----------|----------------|-------------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `static` `public` | | `int` | `compare`(`byte`, `byte`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`String`] | `join`([`String`], `byte...`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`Comparator`] | `lexicographicalComparator`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | `byte` | `max`(`byte...`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | `byte` | `min`(`byte...`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | `int` | `toInt`(`byte`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`String`] | `toString`(`byte`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`String`] | `toString`(`byte`, `int`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.primitives.UnsignedInteger`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|-------------------|------------|-------|---------------|-----------------------|
+| Unchanged | `final` `public` | Class | `UnsignedInteger` | [`Number`] | JDK 6 | ![Compatible] | ![Annotation added] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------------|-----------------------|
+| Added | **[`CheckReturnValue`]** | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-----------|----------|---------------------|----------------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `public` | | [`UnsignedInteger`] | `dividedBy`([`UnsignedInteger`]) | ~~[`CheckReturnValue`]~~ | | ![Annotation removed] |
+| Unchanged | `public` | | [`UnsignedInteger`] | `minus`([`UnsignedInteger`]) | ~~[`CheckReturnValue`]~~ | | ![Annotation removed] |
+| Unchanged | `public` | | [`UnsignedInteger`] | `mod`([`UnsignedInteger`]) | ~~[`CheckReturnValue`]~~ | | ![Annotation removed] |
+| Unchanged | `public` | | [`UnsignedInteger`] | `plus`([`UnsignedInteger`]) | ~~[`CheckReturnValue`]~~ | | ![Annotation removed] |
+| Unchanged | `public` | | [`UnsignedInteger`] | `times`([`UnsignedInteger`]) | ~~[`CheckReturnValue`]~~ | | ![Annotation removed] |
+
+___
+
+
+### `com.google.common.primitives.UnsignedInts`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|----------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `UnsignedInts` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-------------------|----------|----------------|-------------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `static` `public` | | `int` | `compare`(`int`, `int`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | `int` | `divide`(`int`, `int`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`String`] | `join`([`String`], `int...`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`Comparator`] | `lexicographicalComparator`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | `int` | `max`(`int...`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | `int` | `min`(`int...`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | `int` | `remainder`(`int`, `int`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | `long` | `toLong`(`int`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`String`] | `toString`(`int`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`String`] | `toString`(`int`, `int`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.primitives.UnsignedLong`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|----------------|------------|-------|---------------|-----------------------|
+| Unchanged | `final` `public` | Class | `UnsignedLong` | [`Number`] | JDK 6 | ![Compatible] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-----------|----------|------------------|---------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `public` | | [`UnsignedLong`] | `minus`([`UnsignedLong`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `public` | | [`UnsignedLong`] | `plus`([`UnsignedLong`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.primitives.UnsignedLongs`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|------------------|-------|-----------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `final` `public` | Class | `UnsignedLongs` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|-------------------|----------|----------------|-------------------------------|--------------------------|--------|-----------------------|
+| Unchanged | `static` `public` | | `int` | `compare`(`long`, `long`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | `long` | `divide`(`long`, `long`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`String`] | `join`([`String`], `long...`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`Comparator`] | `lexicographicalComparator`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | `long` | `max`(`long...`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | `long` | `min`(`long...`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | `long` | `remainder`(`long`, `long`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`String`] | `toString`(`long`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | | [`String`] | `toString`(`long`, `int`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+
+___
+
+
+### `com.google.common.reflect.ClassPath$ResourceInfo`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|-------------------|-------|----------------|------------|-------|---------------------|-----------------------|
+| Modified | `static` `public` | Class | `ResourceInfo` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|----------|------------------|----------|---------|---------|-------------|--------------------------------|-----------------------|
+| Modified | `final` `public` | | [`URL`] | `url`() | | **[`NoSuchElementException`]** | ![No changes] |
+
+___
+
+
+### `com.google.common.reflect.TypeToken`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [ ] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|---------------------|-------|-------------|--------------------|-------|-------------------------------------|-----------------------|
+| Modified | `public` `abstract` | Class | `TypeToken` | [`TypeCapture`] | JDK 6 | ![Default serialversionuid changed] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `T` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|--------------------------|----------|---------------|---------------------------------------|--------------------|--------|-----------------------|
+| Unchanged | `final` `public` | | `boolean` | `isAssignableFrom`([`TypeToken>`]) | **[`Deprecated`]** | | ![Annotation deprecated added] |
+| Unchanged | `final` `public` | | `boolean` | `isAssignableFrom`([`Type`]) | **[`Deprecated`]** | | ![Annotation deprecated added] |
+| Added | **`final`** **`public`** | | **`boolean`** | **`isSubtypeOf`**([`TypeToken>`]) | | | ![Method added to public class] |
+| Added | **`final`** **`public`** | | **`boolean`** | **`isSubtypeOf`**([`Type`]) | | | ![Method added to public class] |
+| Added | **`final`** **`public`** | | **`boolean`** | **`isSupertypeOf`**([`TypeToken>`]) | | | ![Method added to public class] |
+| Added | **`final`** **`public`** | | **`boolean`** | **`isSupertypeOf`**([`Type`]) | | | ![Method added to public class] |
+
+___
+
+
+### `com.google.common.util.concurrent.AbstractFuture`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|---------------------|-------|------------------|------------|-------|---------------------|-----------------------|
+| Modified | `public` `abstract` | Class | `AbstractFuture` | [`Object`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|-----------------|----------|---------------|----------------------------------------------------|-------------|--------|-----------------------|
+| Added | **`protected`** | | **`boolean`** | **`setFuture`**([`ListenableFuture extends V>`]) | | | ![No changes] |
+
+___
+
+
+### `com.google.common.util.concurrent.AbstractListeningExecutorService`
+
+- [ ] Binary-compatible
+- [ ] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|---------------------|-------|------------------------------------|-----------------------------|-------|---------------------|-----------------------|
+| Modified | `public` `abstract` | Class | `AbstractListeningExecutorService` | [`AbstractExecutorService`] | JDK 6 | ![Not serializable] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|----------|---------------------|--------------------------|------------------------------------------------------------------|---------------------------------|-------------|--------|-----------------------|
+| Modified | `final` `protected` | \<[`T extends Object`]\> | ~~[`ListenableFutureTask`]~~ → **[`RunnableFuture`]** | `newTaskFor`([`Runnable`], `T`) | | | ![Method return type changed] |
+| Modified | `final` `protected` | \<[`T extends Object`]\> | ~~[`ListenableFutureTask`]~~ → **[`RunnableFuture`]** | `newTaskFor`([`Callable`]) | | | ![Method return type changed] |
+
+___
+
+
+### `com.google.common.util.concurrent.FutureFallback`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|-----------|---------------------|-----------|------------------|------------|-------|---------------------|-----------------------|
+| Unchanged | `public` `abstract` | Interface | `FutureFallback` | [`Object`] | JDK 6 | ![Not serializable] | ![Annotation deprecated added] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Annotations
+
+| Status | Annotation | Compatibility Changes |
+|--------|--------------------|-----------------------|
+| Added | **[`Deprecated`]** | ![No changes] |
+
+___
+
+
+### `com.google.common.util.concurrent.Futures`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|------------------|-------|-----------|----------------------------------------------------------------|-------|---------------------|-----------------------|
+| Modified | `final` `public` | Class | `Futures` | ~~[`Object`]~~ → **[`GwtFuturesCatchingSpecialization`]** | JDK 6 | ![Not serializable] | ![Superclass added] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|-----------|---------------------------|-----------------------------------------------------------|----------------------------------------|----------------------------------------------------------|-------------------------------------------------|-------------------|-----------------------|
+| Unchanged | `static` `public` | \<[`V extends Object`]\> | [`ListenableFuture>`] | `allAsList`([`ListenableFuture... extends V>`]) | **[`CheckReturnValue`]**
**[`SafeVarargs`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`V extends Object`]\> | [`ListenableFuture>`] | `allAsList`([`Iterable extends ListenableFuture extends V>>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Added | **`static`** **`public`** | \<**[`V extends Object`]**, **[`X extends Throwable`]**\> | **[`ListenableFuture`]** | **`catching`**([`ListenableFuture extends V>`], [`Class`], [`Function super X, ? extends V>`]) | **[`CheckReturnValue`]** | | ![Method added to public class] ![Annotation added] |
+| Added | **`static`** **`public`** | \<**[`V extends Object`]**, **[`X extends Throwable`]**\> | **[`ListenableFuture`]** | **`catching`**([`ListenableFuture extends V>`], [`Class`], [`Function super X, ? extends V>`], [`Executor`]) | **[`CheckReturnValue`]** | | ![Method added to public class] ![Annotation added] |
+| Added | **`static`** **`public`** | \<**[`V extends Object`]**, **[`X extends Throwable`]**\> | **[`ListenableFuture`]** | **`catchingAsync`**([`ListenableFuture extends V>`], [`Class`], [`AsyncFunction super X, ? extends V>`]) | | | ![Method added to public class] |
+| Added | **`static`** **`public`** | \<**[`V extends Object`]**, **[`X extends Throwable`]**\> | **[`ListenableFuture`]** | **`catchingAsync`**([`ListenableFuture extends V>`], [`Class`], [`AsyncFunction super X, ? extends V>`], [`Executor`]) | | | ![Method added to public class] |
+| Unchanged | `static` `public` | \<[`V extends Object`]\> | [`ListenableFuture`] | `dereference`([`ListenableFuture extends ListenableFuture extends V>>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`V extends Object`], [`X extends Exception`]\> | [`Object`] | `get`([`Future`], [`Class`]) | **[`Deprecated`]** | [`Exception`] | ![Annotation deprecated added] |
+| Unchanged | `static` `public` | \<[`V extends Object`], [`X extends Exception`]\> | [`Object`] | `get`([`Future`], `long`, [`TimeUnit`], [`Class`]) | **[`Deprecated`]** | [`Exception`] | ![Annotation deprecated added] |
+| Added | **`static`** **`public`** | \<**[`V extends Object`]**, **[`X extends Exception`]**\> | **[`Object`]** | **`getChecked`**([`Future`], [`Class`]) | | **[`Exception`]** | ![Method added to public class] |
+| Added | **`static`** **`public`** | \<**[`V extends Object`]**, **[`X extends Exception`]**\> | **[`Object`]** | **`getChecked`**([`Future`], [`Class`], `long`, [`TimeUnit`]) | | **[`Exception`]** | ![Method added to public class] |
+| Unchanged | `static` `public` | \<[`V extends Object`]\> | [`ListenableFuture`] | `immediateCancelledFuture`() | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`V extends Object`], [`X extends Exception`]\> | [`CheckedFuture`] | `immediateCheckedFuture`(`V`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`V extends Object`], [`X extends Exception`]\> | [`CheckedFuture`] | `immediateFailedCheckedFuture`(`X`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`V extends Object`]\> | [`ListenableFuture`] | `immediateFailedFuture`([`Throwable`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`V extends Object`]\> | [`ListenableFuture`] | `immediateFuture`(`V`) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`T extends Object`]\> | [`ImmutableList>`] | `inCompletionOrder`([`Iterable extends ListenableFuture extends T>>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`I extends Object`], [`O extends Object`]\> | [`Future`] | `lazyTransform`([`Future`], [`Function super I, ? extends O>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`V extends Object`], [`X extends Exception`]\> | [`CheckedFuture`] | `makeChecked`([`ListenableFuture`], [`Function super Exception, X>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`V extends Object`]\> | [`ListenableFuture`] | `nonCancellationPropagating`([`ListenableFuture`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`V extends Object`]\> | [`ListenableFuture>`] | `successfulAsList`([`ListenableFuture... extends V>`]) | **[`CheckReturnValue`]**
**[`SafeVarargs`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`V extends Object`]\> | [`ListenableFuture>`] | `successfulAsList`([`Iterable extends ListenableFuture extends V>>`]) | **[`CheckReturnValue`]** | | ![Annotation added] |
+| Unchanged | `static` `public` | \<[`I extends Object`], [`O extends Object`]\> | [`ListenableFuture`] | `transform`([`ListenableFuture`], [`AsyncFunction super I, ? extends O>`]) | **[`Deprecated`]** | | ![Annotation deprecated added] |
+| Unchanged | `static` `public` | \<[`I extends Object`], [`O extends Object`]\> | [`ListenableFuture`] | `transform`([`ListenableFuture`], [`AsyncFunction super I, ? extends O>`], [`Executor`]) | **[`Deprecated`]** | | ![Annotation deprecated added] |
+| Added | **`static`** **`public`** | \<**[`I extends Object`]**, **[`O extends Object`]**\> | **[`ListenableFuture`]** | **`transformAsync`**([`ListenableFuture`], [`AsyncFunction super I, ? extends O>`]) | | | ![Method added to public class] |
+| Added | **`static`** **`public`** | \<**[`I extends Object`]**, **[`O extends Object`]**\> | **[`ListenableFuture`]** | **`transformAsync`**([`ListenableFuture`], [`AsyncFunction super I, ? extends O>`], [`Executor`]) | | | ![Method added to public class] |
+| Unchanged | `static` `public` | \<[`V extends Object`]\> | [`ListenableFuture`] | `withFallback`([`ListenableFuture extends V>`], [`FutureFallback extends V>`]) | **[`CheckReturnValue`]**
**[`Deprecated`]** | | ![Annotation added] ![Annotation deprecated added] |
+| Unchanged | `static` `public` | \<[`V extends Object`]\> | [`ListenableFuture`] | `withFallback`([`ListenableFuture extends V>`], [`FutureFallback extends V>`], [`Executor`]) | **[`CheckReturnValue`]**
**[`Deprecated`]** | | ![Annotation added] ![Annotation deprecated added] |
+| Added | **`static`** **`public`** | \<**[`V extends Object`]**\> | **[`ListenableFuture`]** | **`withTimeout`**([`ListenableFuture`], `long`, [`TimeUnit`], [`ScheduledExecutorService`]) | **[`CheckReturnValue`]** | | ![Method added to public class] ![Annotation added] |
+
+___
+
+
+### `com.google.common.util.concurrent.SettableFuture`
+
+- [X] Binary-compatible
+- [X] Source-compatible
+- [X] Serialization-compatible
+
+| Status | Modifiers | Type | Name | Extends | JDK | Serialization | Compatibility Changes |
+|----------|------------------|-------|------------------|-----------------------------------------------------------|-------|---------------------|-----------------------|
+| Modified | `final` `public` | Class | `SettableFuture` | ~~[`AbstractFuture`]~~ → **[`TrustedFuture`]** | JDK 6 | ![Not serializable] | ![Superclass added] |
+
+
+#### Generics
+
+| Status | Name | Extends | Compatibility Changes |
+|-----------|------|------------|-----------------------|
+| Unchanged | `V` | [`Object`] | ![No changes] |
+
+
+#### Methods
+
+| Status | Modifiers | Generics | Type | Method | Annotations | Throws | Compatibility Changes |
+|--------|--------------|----------|---------------|----------------------------------------------------|-------------|--------|-----------------------|
+| Added | **`public`** | | **`boolean`** | **`setFuture`**([`ListenableFuture extends V>`]) | | | ![Method added to public class] |
+
+
+
+
+
+___
+
+*Generated on: 2024-07-29 17:08:40.539+0000*.
+
+[1]: # "java.lang.Object[]"
+[2]: # "com.google.common.base.Objects$ToStringHelper"
+[3]: # "com.google.common.collect.ImmutableBiMap$Builder"
+[4]: # "com.google.common.collect.ImmutableMultimap$Builder"
+[5]: # "com.google.common.collect.ImmutableListMultimap$Builder"
+[6]: # "com.google.common.collect.ImmutableMap"
+[7]: # "com.google.common.collect.ImmutableMap$Builder"
+[8]: # "com.google.common.collect.ImmutableMultimap"
+[9]: # "com.google.common.collect.ImmutableMultimap$Builder"
+[10]: # "com.google.common.collect.ImmutableSetMultimap$Builder"
+[11]: # "com.google.common.collect.ImmutableSortedMap$Builder"
+[Annotation added]: https://img.shields.io/badge/Annotation_added-yellow "Annotation added"
+[Annotation deprecated added]: https://img.shields.io/badge/Annotation_deprecated_added-orange "Annotation deprecated added"
+[Annotation removed]: https://img.shields.io/badge/Annotation_removed-yellow "Annotation removed"
+[Class generic template generics changed]: https://img.shields.io/badge/Class_generic_template_generics_changed-orange "Class generic template generics changed"
+[Class now final]: https://img.shields.io/badge/Class_now_final-red "Class now final"
+[Compatible]: https://img.shields.io/badge/Compatible-green "Compatible"
+[Default serialversionuid changed]: https://img.shields.io/badge/Incompatible-red "Default serialversionuid changed"
+[Interface added]: https://img.shields.io/badge/Interface_added-orange "Interface added"
+[Method added to interface]: https://img.shields.io/badge/Method_added_to_interface-orange "Method added to interface"
+[Method added to public class]: https://img.shields.io/badge/Method_added_to_public_class-yellow "Method added to public class"
+[Method less accessible]: https://img.shields.io/badge/Method_less_accessible-red "Method less accessible"
+[Method now abstract]: https://img.shields.io/badge/Method_now_abstract-red "Method now abstract"
+[Method removed]: https://img.shields.io/badge/Method_removed-red "Method removed"
+[Method return type changed]: https://img.shields.io/badge/Method_return_type_changed-red "Method return type changed"
+[Method return type generics changed]: https://img.shields.io/badge/Method_return_type_generics_changed-orange "Method return type generics changed"
+[No changes]: https://img.shields.io/badge/No_changes-green "No changes"
+[Not serializable]: https://img.shields.io/badge/Not_serializable-green "Not serializable"
+[Superclass added]: https://img.shields.io/badge/Superclass_added-orange "Superclass added"
+[Superclass modified]: https://img.shields.io/badge/Incompatible-red "Superclass modified"
+[`AbstractCollection`]: # "java.util.AbstractCollection"
+[`AbstractExecutorService`]: # "java.util.concurrent.AbstractExecutorService"
+[`AbstractFuture`]: # "com.google.common.util.concurrent.AbstractFuture"
+[`AbstractMap`]: # "java.util.AbstractMap"
+[`AbstractMultimap`]: # "com.google.common.collect.AbstractMultimap"
+[`AbstractRangeSet`]: # "com.google.common.collect.AbstractRangeSet"
+[`AsyncFunction super I, ? extends O>`]: # "com.google.common.util.concurrent.AsyncFunction super I, ? extends O>"
+[`AsyncFunction super X, ? extends V>`]: # "com.google.common.util.concurrent.AsyncFunction super X, ? extends V>"
+[`B extends Object`]: # "B extends java.lang.Object"
+[`BiMap`]: # "com.google.common.collect.BiMap"
+[`BloomFilter`]: # "com.google.common.hash.BloomFilter"
+[`Boolean`]: # "java.lang.Boolean"
+[`Builder`]: # "com.google.common.collect.ImmutableSortedMultiset$Builder"
+[`Builder`]: # "com.google.common.collect.ImmutableMap$Builder"
+[`Callable`]: # "java.util.concurrent.Callable"
+[`CharMatcher`]: # "com.google.common.base.CharMatcher"
+[`CharSequence`]: # "java.lang.CharSequence"
+[`CheckForNull`]: # "javax.annotation.CheckForNull"
+[`CheckReturnValue`]: # "javax.annotation.CheckReturnValue"
+[`CheckedFuture`]: # "com.google.common.util.concurrent.CheckedFuture"
+[`Class>`]: # "java.lang.Class>"
+[`Class`]: # "java.lang.Class"
+[`Class`]: # "java.lang.Class"
+[`Class`]: # "java.lang.Class"
+[`Collection>`]: # "java.util.Collection>"
+[`Collection`]: # "java.util.Collection"
+[`Comparable>`]: # "java.lang.Comparable>"
+[`Comparable`]: # "java.lang.Comparable"
+[`Comparator super E>`]: # "java.util.Comparator super E>"
+[`Comparator super K>`]: # "java.util.Comparator super K>"
+[`Comparator super V>`]: # "java.util.Comparator super V>"
+[`Comparator`]: # "java.util.Comparator"
+[`ComparisonChain`]: # "com.google.common.collect.ComparisonChain"
+[`Deprecated`]: # "java.lang.Deprecated"
+[`Double`]: # "java.lang.Double"
+[`E extends Comparable>`]: # "E extends java.lang.Comparable>"
+[`E extends Comparable`]: # "E extends java.lang.Comparable"
+[`E extends Object`]: # "E extends java.lang.Object"
+[`Entry extends K, ? extends V>`]: # "java.util.Map$Entry extends K, ? extends V>"
+[`Enum`]: # "java.lang.Enum>"
+[`EventBus`]: # "com.google.common.eventbus.EventBus"
+[`Exception`]: # "java.lang.Exception"
+[`Executor`]: # "java.util.concurrent.Executor"
+[`F extends Object`]: # "F extends java.lang.Object"
+[`FilterInputStream`]: # "java.io.FilterInputStream"
+[`FilterOutputStream`]: # "java.io.FilterOutputStream"
+[`Float`]: # "java.lang.Float"
+[`FluentIterable`]: # "com.google.common.collect.FluentIterable"
+[`FluentIterable`]: # "com.google.common.collect.FluentIterable"
+[`ForwardingMap`]: # "com.google.common.collect.ForwardingMap"
+[`Function super E, ? extends Iterable extends T>>`]: # "com.google.common.base.Function super E, ? extends java.lang.Iterable extends T>>"
+[`Function super E, K>`]: # "com.google.common.base.Function super E, K>"
+[`Function super E, T>`]: # "com.google.common.base.Function super E, T>"
+[`Function super E, V>`]: # "com.google.common.base.Function super E, V>"
+[`Function super Exception, X>`]: # "com.google.common.base.Function super java.lang.Exception, X>"
+[`Function super F, ? extends T>`]: # "com.google.common.base.Function super F, ? extends T>"
+[`Function super I, ? extends O>`]: # "com.google.common.base.Function super I, ? extends O>"
+[`Function super X, ? extends V>`]: # "com.google.common.base.Function super X, ? extends V>"
+[`Funnel super T>`]: # "com.google.common.hash.Funnel super T>"
+[`Funnel`]: # "com.google.common.hash.Funnel"
+[`Future`]: # "java.util.concurrent.Future"
+[`Future`]: # "java.util.concurrent.Future"
+[`Future`]: # "java.util.concurrent.Future"
+[`FutureFallback extends V>`]: # "com.google.common.util.concurrent.FutureFallback extends V>"
+[`GenericMapMaker`]: # "com.google.common.collect.GenericMapMaker"
+[`GwtFuturesCatchingSpecialization`]: # "com.google.common.util.concurrent.GwtFuturesCatchingSpecialization"
+[`HashCode`]: # "com.google.common.hash.HashCode"
+[`HashFunction...`]: # "com.google.common.hash.HashFunction..."
+[`HashFunction`]: # "com.google.common.hash.HashFunction"
+[`I extends Object`]: # "I extends java.lang.Object"
+[`IOException`]: # "java.io.IOException"
+[`ImmutableBiMap`]: # "com.google.common.collect.ImmutableBiMap"
+[`ImmutableClassToInstanceMap`]: # "com.google.common.collect.ImmutableClassToInstanceMap"
+[`ImmutableCollection`]: # "com.google.common.collect.ImmutableCollection"
+[`ImmutableCollection`]: # "com.google.common.collect.ImmutableCollection"
+[`ImmutableList`]: # "com.google.common.collect.ImmutableList"
+[`ImmutableList>`]: # "com.google.common.collect.ImmutableList>"
+[`ImmutableListMultimap`]: # "com.google.common.collect.ImmutableListMultimap"
+[`ImmutableListMultimap`]: # "com.google.common.collect.ImmutableListMultimap"
+[`ImmutableMap`]: # "com.google.common.collect.ImmutableMap"
+[`ImmutableMap`]: # "com.google.common.collect.ImmutableMap"
+[`ImmutableMap`]: # "com.google.common.collect.ImmutableMap"
+[`ImmutableMap, V>`]: # "com.google.common.collect.ImmutableMap, V>"
+[`ImmutableMultimap`]: # "com.google.common.collect.ImmutableMultimap"
+[`ImmutableMultiset`]: # "com.google.common.collect.ImmutableMultiset"
+[`ImmutableSet`]: # "com.google.common.collect.ImmutableSet"
+[`ImmutableSet>`]: # "com.google.common.collect.ImmutableSet>"
+[`ImmutableSetMultimap`]: # "com.google.common.collect.ImmutableSetMultimap"
+[`ImmutableSortedMap`]: # "com.google.common.collect.ImmutableSortedMap"
+[`ImmutableSortedMapFauxverideShim`]: # "com.google.common.collect.ImmutableSortedMapFauxverideShim"
+[`ImmutableSortedSet`]: # "com.google.common.collect.ImmutableSortedSet"
+[`ImmutableSortedSet`]: # "com.google.common.collect.ImmutableSortedSet"
+[`ImmutableSortedSetFauxverideShim`]: # "com.google.common.collect.ImmutableSortedSetFauxverideShim"
+[`ImmutableSorted…etFauxverideShim`]: # "com.google.common.collect.ImmutableSortedMultisetFauxverideShim"
+[`InputStream`]: # "java.io.InputStream"
+[`Integer`]: # "java.lang.Integer"
+[`Iterable extends Entry extends ?, ? extends ?>>`]: # "java.lang.Iterable extends java.util.Map$Entry extends ?, ? extends ?>>"
+[`Iterable extends Entry extends K, ? extends V>>`]: # "java.lang.Iterable extends java.util.Map$Entry extends K, ? extends V>>"
+[`Iterable extends ListenableFuture extends T>>`]: # "java.lang.Iterable extends com.google.common.util.concurrent.ListenableFuture extends T>>"
+[`Iterable extends ListenableFuture extends V>>`]: # "java.lang.Iterable extends com.google.common.util.concurrent.ListenableFuture extends V>>"
+[`Iterable>`]: # "java.lang.Iterable>"
+[`Iterable`]: # "java.lang.Iterable"
+[`Iterable`]: # "java.lang.Iterable"
+[`Iterable`]: # "java.lang.Iterable"
+[`Iterable`]: # "java.lang.Iterable"
+[`Iterable`]: # "java.lang.Iterable"
+[`Iterator extends Entry extends ?, ? extends ?>>`]: # "java.util.Iterator extends java.util.Map$Entry extends ?, ? extends ?>>"
+[`Iterator>`]: # "java.util.Iterator>"
+[`Iterator`]: # "java.util.Iterator"
+[`IteratorBasedAbstractMap`]: # "com.google.common.collect.Maps$IteratorBasedAbstractMap"
+[`Joiner`]: # "com.google.common.base.Joiner"
+[`K extends Object`]: # "K extends java.lang.Object"
+[`LinkedHashMap`]: # "java.util.LinkedHashMap"
+[`List... extends B>`]: # "java.util.List... extends B>"
+[`List extends List extends B>>`]: # "java.util.List extends java.util.List extends B>>"
+[`List`]: # "java.util.List"
+[`List>`]: # "java.util.List>"
+[`List`]: # "java.util.List"
+[`List`]: # "java.util.List"
+[`List`]: # "java.util.List"
+[`List`]: # "java.util.List"
+[`ListMultimap`]: # "com.google.common.collect.ListMultimap"
+[`ListenableFuture... extends V>`]: # "com.google.common.util.concurrent.ListenableFuture... extends V>"
+[`ListenableFuture extends ListenableFuture extends V>>`]: # "com.google.common.util.concurrent.ListenableFuture extends com.google.common.util.concurrent.ListenableFuture extends V>>"
+[`ListenableFuture extends V>`]: # "com.google.common.util.concurrent.ListenableFuture extends V>"
+[`ListenableFuture`]: # "com.google.common.util.concurrent.ListenableFuture"
+[`ListenableFuture>`]: # "com.google.common.util.concurrent.ListenableFuture>"
+[`ListenableFuture`]: # "com.google.common.util.concurrent.ListenableFuture"
+[`ListenableFuture`]: # "com.google.common.util.concurrent.ListenableFuture"
+[`ListenableFutureTask`]: # "com.google.common.util.concurrent.ListenableFutureTask"
+[`Long`]: # "java.lang.Long"
+[`Map, ?>`]: # "java.util.Map, ?>"
+[`Map`]: # "java.util.Map"
+[`Map`]: # "java.util.Map"
+[`Map, V>`]: # "java.util.Map, V>"
+[`Map`]: # "java.util.Map"
+[`MapMaker`]: # "com.google.common.collect.MapMaker"
+[`MediaType`]: # "com.google.common.net.MediaType"
+[`Multimap`]: # "com.google.common.collect.Multimap"
+[`Multiset>`]: # "com.google.common.collect.Multiset>"
+[`Multiset`]: # "com.google.common.collect.Multiset"
+[`NavigableMap`]: # "java.util.NavigableMap"
+[`NavigableSet`]: # "java.util.NavigableSet"
+[`NoSuchElementException`]: # "java.util.NoSuchElementException"
+[`Nullable`]: # "javax.annotation.Nullable"
+[`Number`]: # "java.lang.Number"
+[`O extends Object`]: # "O extends java.lang.Object"
+[`Object...`]: # "java.lang.Object..."
+[`Object`]: # "java.lang.Object"
+[`Optional`]: # "com.google.common.base.Optional"
+[`Optional`]: # "com.google.common.base.Optional"
+[`OutputStream`]: # "java.io.OutputStream"
+[`Pattern`]: # "java.util.regex.Pattern"
+[`Predicate super E>`]: # "com.google.common.base.Predicate super E>"
+[`Predicate super Entry super K, ? super V>>`]: # "com.google.common.base.Predicate super java.util.Map$Entry super K, ? super V>>"
+[`Predicate super K>`]: # "com.google.common.base.Predicate super K>"
+[`Predicate super T>`]: # "com.google.common.base.Predicate super T>"
+[`Predicate super V>`]: # "com.google.common.base.Predicate super V>"
+[`RangeMap`]: # "com.google.common.collect.RangeMap"
+[`RangeSet`]: # "com.google.common.collect.RangeSet"
+[`Reader`]: # "java.io.Reader"
+[`RemovalCause`]: # "com.google.common.cache.RemovalCause"
+[`RemovalNotification`]: # "com.google.common.cache.RemovalNotification"
+[`RunnableFuture`]: # "java.util.concurrent.RunnableFuture"
+[`Runnable`]: # "java.lang.Runnable"
+[`RuntimeException`]: # "java.lang.RuntimeException"
+[`SafeVarargs`]: # "java.lang.SafeVarargs"
+[`ScheduledExecutorService`]: # "java.util.concurrent.ScheduledExecutorService"
+[`Serializable`]: # "java.io.Serializable"
+[`Set`]: # "java.util.Set"
+[`Set>`]: # "java.util.Set>"
+[`Set>`]: # "java.util.Set>"
+[`SetMultimap`]: # "com.google.common.collect.SetMultimap"
+[`Set`]: # "java.util.Set"
+[`SortedMap`]: # "java.util.SortedMap"
+[`SortedSet`]: # "java.util.SortedSet"
+[`Splitter`]: # "com.google.common.base.Splitter"
+[`Stopwatch`]: # "com.google.common.base.Stopwatch"
+[`String`]: # "java.lang.String"
+[`T extends Object`]: # "T extends java.lang.Object"
+[`Throwable`]: # "java.lang.Throwable"
+[`Ticker`]: # "com.google.common.base.Ticker"
+[`TimeUnit`]: # "java.util.concurrent.TimeUnit"
+[`ToStringHelper`]: # "com.google.common.base.MoreObjects$ToStringHelper"
+[`TrustedFuture`]: # "com.google.common.util.concurrent.AbstractFuture$TrustedFuture"
+[`TypeCapture`]: # "com.google.common.reflect.TypeCapture"
+[`TypeToken>`]: # "com.google.common.reflect.TypeToken>"
+[`Type`]: # "java.lang.reflect.Type"
+[`URL`]: # "java.net.URL"
+[`UnmodifiableIterator`]: # "com.google.common.collect.UnmodifiableIterator"
+[`UnsignedInteger`]: # "com.google.common.primitives.UnsignedInteger"
+[`UnsignedLong`]: # "com.google.common.primitives.UnsignedLong"
+[`UnsupportedOperationException`]: # "java.lang.UnsupportedOperationException"
+[`V extends Object`]: # "V extends java.lang.Object"
+[`Writer`]: # "java.io.Writer"
+[`X extends Exception`]: # "X extends java.lang.Exception"
+[`X extends Throwable`]: # "X extends java.lang.Throwable"
+[com.google.common.base.Ascii]: #user-content-com.google.common.base.ascii
+[com.google.common.base.CaseFormat]: #user-content-com.google.common.base.caseformat
+[com.google.common.base.CharMatcher]: #user-content-com.google.common.base.charmatcher
+[com.google.common.base.Defaults]: #user-content-com.google.common.base.defaults
+[com.google.common.base.Enums]: #user-content-com.google.common.base.enums
+[com.google.common.base.Equivalence]: #user-content-com.google.common.base.equivalence
+[com.google.common.base.Functions]: #user-content-com.google.common.base.functions
+[com.google.common.base.Joiner]: #user-content-com.google.common.base.joiner
+[com.google.common.base.Joiner$MapJoiner]: #user-content-com.google.common.base.joiner$mapjoiner
+[com.google.common.base.MoreObjects]: #user-content-com.google.common.base.moreobjects
+[com.google.common.base.MoreObjects$ToStringHelper]: #user-content-com.google.common.base.moreobjects$tostringhelper
+[com.google.common.base.Objects]: #user-content-com.google.common.base.objects
+[com.google.common.base.Optional]: #user-content-com.google.common.base.optional
+[com.google.common.base.Predicates]: #user-content-com.google.common.base.predicates
+[com.google.common.base.Splitter]: #user-content-com.google.common.base.splitter
+[com.google.common.base.Splitter$MapSplitter]: #user-content-com.google.common.base.splitter$mapsplitter
+[com.google.common.base.StandardSystemProperty]: #user-content-com.google.common.base.standardsystemproperty
+[com.google.common.base.Stopwatch]: #user-content-com.google.common.base.stopwatch
+[com.google.common.base.Strings]: #user-content-com.google.common.base.strings
+[com.google.common.base.Suppliers]: #user-content-com.google.common.base.suppliers
+[com.google.common.base.Throwables]: #user-content-com.google.common.base.throwables
+[com.google.common.base.Ticker]: #user-content-com.google.common.base.ticker
+[com.google.common.base.Utf8]: #user-content-com.google.common.base.utf8
+[com.google.common.base.VerifyException]: #user-content-com.google.common.base.verifyexception
+[com.google.common.cache.CacheLoader$UnsupportedLoadingOperationException]: #user-content-com.google.common.cache.cacheloader$unsupportedloadingoperationexception
+[com.google.common.cache.RemovalNotification]: #user-content-com.google.common.cache.removalnotification
+[com.google.common.collect.BiMap]: #user-content-com.google.common.collect.bimap
+[com.google.common.collect.Collections2]: #user-content-com.google.common.collect.collections2
+[com.google.common.collect.ComparisonChain]: #user-content-com.google.common.collect.comparisonchain
+[com.google.common.collect.FluentIterable]: #user-content-com.google.common.collect.fluentiterable
+[com.google.common.collect.HashBiMap]: #user-content-com.google.common.collect.hashbimap
+[com.google.common.collect.ImmutableBiMap]: #user-content-com.google.common.collect.immutablebimap
+[com.google.common.collect.ImmutableBiMap$Builder]: #user-content-com.google.common.collect.immutablebimap$builder
+[com.google.common.collect.ImmutableClassToInstanceMap]: #user-content-com.google.common.collect.immutableclasstoinstancemap
+[com.google.common.collect.ImmutableCollection]: #user-content-com.google.common.collect.immutablecollection
+[com.google.common.collect.ImmutableList]: #user-content-com.google.common.collect.immutablelist
+[com.google.common.collect.ImmutableListMultimap]: #user-content-com.google.common.collect.immutablelistmultimap
+[com.google.common.collect.ImmutableListMultimap$Builder]: #user-content-com.google.common.collect.immutablelistmultimap$builder
+[com.google.common.collect.ImmutableMap]: #user-content-com.google.common.collect.immutablemap
+[com.google.common.collect.ImmutableMap$Builder]: #user-content-com.google.common.collect.immutablemap$builder
+[com.google.common.collect.ImmutableMultimap]: #user-content-com.google.common.collect.immutablemultimap
+[com.google.common.collect.ImmutableMultimap$Builder]: #user-content-com.google.common.collect.immutablemultimap$builder
+[com.google.common.collect.ImmutableMultiset]: #user-content-com.google.common.collect.immutablemultiset
+[com.google.common.collect.ImmutableRangeMap]: #user-content-com.google.common.collect.immutablerangemap
+[com.google.common.collect.ImmutableRangeSet]: #user-content-com.google.common.collect.immutablerangeset
+[com.google.common.collect.ImmutableSetMultimap]: #user-content-com.google.common.collect.immutablesetmultimap
+[com.google.common.collect.ImmutableSetMultimap$Builder]: #user-content-com.google.common.collect.immutablesetmultimap$builder
+[com.google.common.collect.ImmutableSortedMap]: #user-content-com.google.common.collect.immutablesortedmap
+[com.google.common.collect.ImmutableSortedMap$Builder]: #user-content-com.google.common.collect.immutablesortedmap$builder
+[com.google.common.collect.ImmutableSortedMultiset]: #user-content-com.google.common.collect.immutablesortedmultiset
+[com.google.common.collect.ImmutableSortedSet]: #user-content-com.google.common.collect.immutablesortedset
+[com.google.common.collect.Iterables]: #user-content-com.google.common.collect.iterables
+[com.google.common.collect.Iterators]: #user-content-com.google.common.collect.iterators
+[com.google.common.collect.Lists]: #user-content-com.google.common.collect.lists
+[com.google.common.collect.MapConstraint]: #user-content-com.google.common.collect.mapconstraint
+[com.google.common.collect.MapConstraints]: #user-content-com.google.common.collect.mapconstraints
+[com.google.common.collect.MapMaker]: #user-content-com.google.common.collect.mapmaker
+[com.google.common.collect.Maps]: #user-content-com.google.common.collect.maps
+[com.google.common.collect.MultimapBuilder]: #user-content-com.google.common.collect.multimapbuilder
+[com.google.common.collect.Multimaps]: #user-content-com.google.common.collect.multimaps
+[com.google.common.collect.Multisets]: #user-content-com.google.common.collect.multisets
+[com.google.common.collect.RangeMap]: #user-content-com.google.common.collect.rangemap
+[com.google.common.collect.RangeSet]: #user-content-com.google.common.collect.rangeset
+[com.google.common.collect.Sets]: #user-content-com.google.common.collect.sets
+[com.google.common.collect.Table]: #user-content-com.google.common.collect.table
+[com.google.common.collect.Table$Cell]: #user-content-com.google.common.collect.table$cell
+[com.google.common.collect.TreeRangeMap]: #user-content-com.google.common.collect.treerangemap
+[com.google.common.collect.TreeRangeSet]: #user-content-com.google.common.collect.treerangeset
+[com.google.common.eventbus.AsyncEventBus]: #user-content-com.google.common.eventbus.asynceventbus
+[com.google.common.eventbus.DeadEvent]: #user-content-com.google.common.eventbus.deadevent
+[com.google.common.eventbus.EventBus]: #user-content-com.google.common.eventbus.eventbus
+[com.google.common.hash.BloomFilter]: #user-content-com.google.common.hash.bloomfilter
+[com.google.common.hash.Funnels]: #user-content-com.google.common.hash.funnels
+[com.google.common.hash.HashCode]: #user-content-com.google.common.hash.hashcode
+[com.google.common.hash.Hasher]: #user-content-com.google.common.hash.hasher
+[com.google.common.hash.Hashing]: #user-content-com.google.common.hash.hashing
+[com.google.common.hash.HashingInputStream]: #user-content-com.google.common.hash.hashinginputstream
+[com.google.common.hash.HashingOutputStream]: #user-content-com.google.common.hash.hashingoutputstream
+[com.google.common.io.BaseEncoding]: #user-content-com.google.common.io.baseencoding
+[com.google.common.io.ByteSource]: #user-content-com.google.common.io.bytesource
+[com.google.common.io.CharSource]: #user-content-com.google.common.io.charsource
+[com.google.common.net.HttpHeaders]: #user-content-com.google.common.net.httpheaders
+[com.google.common.net.MediaType]: #user-content-com.google.common.net.mediatype
+[com.google.common.primitives.Booleans]: #user-content-com.google.common.primitives.booleans
+[com.google.common.primitives.Bytes]: #user-content-com.google.common.primitives.bytes
+[com.google.common.primitives.Chars]: #user-content-com.google.common.primitives.chars
+[com.google.common.primitives.Doubles]: #user-content-com.google.common.primitives.doubles
+[com.google.common.primitives.Floats]: #user-content-com.google.common.primitives.floats
+[com.google.common.primitives.Ints]: #user-content-com.google.common.primitives.ints
+[com.google.common.primitives.Longs]: #user-content-com.google.common.primitives.longs
+[com.google.common.primitives.Primitives]: #user-content-com.google.common.primitives.primitives
+[com.google.common.primitives.Shorts]: #user-content-com.google.common.primitives.shorts
+[com.google.common.primitives.SignedBytes]: #user-content-com.google.common.primitives.signedbytes
+[com.google.common.primitives.UnsignedBytes]: #user-content-com.google.common.primitives.unsignedbytes
+[com.google.common.primitives.UnsignedInteger]: #user-content-com.google.common.primitives.unsignedinteger
+[com.google.common.primitives.UnsignedInts]: #user-content-com.google.common.primitives.unsignedints
+[com.google.common.primitives.UnsignedLong]: #user-content-com.google.common.primitives.unsignedlong
+[com.google.common.primitives.UnsignedLongs]: #user-content-com.google.common.primitives.unsignedlongs
+[com.google.common.reflect.ClassPath$ResourceInfo]: #user-content-com.google.common.reflect.classpath$resourceinfo
+[com.google.common.reflect.TypeToken]: #user-content-com.google.common.reflect.typetoken
+[com.google.common.util.concurrent.AbstractFuture]: #user-content-com.google.common.util.concurrent.abstractfuture
+[com.google.common.util.concurrent.AbstractListeningExecutorService]: #user-content-com.google.common.util.concurrent.abstractlisteningexecutorservice
+[com.google.common.util.concurrent.FutureFallback]: #user-content-com.google.common.util.concurrent.futurefallback
+[com.google.common.util.concurrent.Futures]: #user-content-com.google.common.util.concurrent.futures
+[com.google.common.util.concurrent.SettableFuture]: #user-content-com.google.common.util.concurrent.settablefuture
diff --git a/doc/japicmp_guava_markdown.png b/doc/japicmp_guava_markdown.png
new file mode 100644
index 000000000..c7fc15aed
Binary files /dev/null and b/doc/japicmp_guava_markdown.png differ
diff --git a/japicmp-ant-task/src/main/java/japicmp/ant/JApiCmpTask.java b/japicmp-ant-task/src/main/java/japicmp/ant/JApiCmpTask.java
index b44f40076..8672c99d3 100644
--- a/japicmp-ant-task/src/main/java/japicmp/ant/JApiCmpTask.java
+++ b/japicmp-ant-task/src/main/java/japicmp/ant/JApiCmpTask.java
@@ -9,6 +9,7 @@
import japicmp.output.html.HtmlOutputGenerator;
import japicmp.output.html.HtmlOutputGeneratorOptions;
import japicmp.output.incompatible.IncompatibleErrorOutput;
+import japicmp.output.markdown.MarkdownOutputGenerator;
import japicmp.output.semver.SemverOut;
import japicmp.output.stdout.StdoutOutputGenerator;
import japicmp.output.xml.XmlOutput;
@@ -38,6 +39,7 @@ public class JApiCmpTask extends Task {
private boolean includeSynthetic = false;
private boolean noAnnotations = false;
private boolean semanticVersioning = false;
+ private boolean markdown = false;
private boolean reportOnlyFilename = false;
private boolean reportOnlySummary = false;
private boolean ignoreMissingClasses = false;
@@ -46,6 +48,7 @@ public class JApiCmpTask extends Task {
private final List ignoreMissingClassesByRegularExpressions = new ArrayList<>();
private String accessModifier = "protected";
private String semanticVersionProperty;
+ private String markdownProperty;
private String oldJar;
private String newJar;
private Path oldClassPath;
@@ -88,6 +91,15 @@ public void setSemVerProperty(String semverProperty) {
semanticVersionProperty = semverProperty;
}
+ public void setMarkdown(String markdown) {
+ this.markdown = Project.toBoolean(markdown);
+ }
+
+ public void setMarkdownProperty(String mdProperty) {
+ markdown = Boolean.TRUE;
+ markdownProperty = mdProperty;
+ }
+
public void setReportOnlyFilename(String reportOnlyFilename) {
this.reportOnlyFilename = Project.toBoolean(reportOnlyFilename);
}
@@ -284,6 +296,14 @@ private void generateOutput(Options options, List jApiClasses, JarArc
}
log(semver);
return;
+ } else if (markdown) {
+ MarkdownOutputGenerator markdownOutputGenerator = new MarkdownOutputGenerator(options, jApiClasses);
+ String md = markdownOutputGenerator.generate();
+ if (markdownProperty != null) {
+ getProject().setProperty(markdownProperty, md);
+ }
+ log(md);
+ return;
}
if (!options.getXmlOutputFile().isPresent() && !options.getHtmlOutputFile().isPresent()) {
diff --git a/japicmp-maven-plugin/src/main/java/japicmp/maven/JApiCmpMojo.java b/japicmp-maven-plugin/src/main/java/japicmp/maven/JApiCmpMojo.java
index 6b892fc43..1396962f8 100644
--- a/japicmp-maven-plugin/src/main/java/japicmp/maven/JApiCmpMojo.java
+++ b/japicmp-maven-plugin/src/main/java/japicmp/maven/JApiCmpMojo.java
@@ -15,6 +15,8 @@
import japicmp.output.html.HtmlOutputGenerator;
import japicmp.output.html.HtmlOutputGeneratorOptions;
import japicmp.output.incompatible.IncompatibleErrorOutput;
+import japicmp.output.markdown.MarkdownOutputGenerator;
+import japicmp.output.markdown.config.MarkdownOptions;
import japicmp.output.semver.SemverOut;
import japicmp.output.stdout.StdoutOutputGenerator;
import japicmp.output.xml.XmlOutput;
@@ -77,6 +79,8 @@ public class JApiCmpMojo extends AbstractMojo {
private boolean skip;
@org.apache.maven.plugins.annotations.Parameter(property = "japicmp.skip", defaultValue = "false")
private boolean skipExec;
+ @org.apache.maven.plugins.annotations.Parameter(property = "japicmp.skipMarkdownReport", required = false)
+ private boolean skipMarkdownReport;
@org.apache.maven.plugins.annotations.Parameter(property = "japicmp.skipXmlReport", required = false)
private boolean skipXmlReport;
@org.apache.maven.plugins.annotations.Parameter(property = "japicmp.skipHtmlReport", required = false)
@@ -148,6 +152,9 @@ Optional executeWithParameters(PluginParameters pluginParameters, Ma
SemverOut semverOut = new SemverOut(options, jApiClasses);
String semanticVersioningInformation = semverOut.generate();
generateDiffOutput(mavenParameters, pluginParameters, options, jApiClasses, jApiCmpBuildDir, semanticVersioningInformation);
+ if (!skipMarkdownReport(pluginParameters)) {
+ generateMarkdownOutput(mavenParameters, pluginParameters, options, jApiClasses, jApiCmpBuildDir);
+ }
if (!skipXmlReport(pluginParameters)) {
XmlOutput xmlOutput = generateXmlOutput(jApiClasses, jApiCmpBuildDir, options, mavenParameters, pluginParameters, semanticVersioningInformation);
if (pluginParameters.isWriteToFiles()) {
@@ -576,6 +583,18 @@ private void generateDiffOutput(MavenParameters mavenParameters, PluginParameter
}
}
+ private void generateMarkdownOutput(MavenParameters mavenParameters, PluginParameters pluginParameters, Options options,
+ List jApiClasses, File jApiCmpBuildDir) throws IOException, MojoFailureException {
+ MarkdownOptions mdOptions = MarkdownOptions.newDefault(options);
+ if (pluginParameters.getParameterParam() != null && pluginParameters.getParameterParam().getMarkdownTitle() != null) {
+ mdOptions.title.report = pluginParameters.getParameterParam().getMarkdownTitle();
+ }
+ MarkdownOutputGenerator mdOut = new MarkdownOutputGenerator(mdOptions, jApiClasses);
+ String markdown = mdOut.generate();
+ File output = new File(jApiCmpBuildDir.getCanonicalPath() + File.separator + createFilename(mavenParameters) + ".md");
+ writeToFile(markdown, output);
+ }
+
private XmlOutput generateXmlOutput(List jApiClasses, File jApiCmpBuildDir, Options options, MavenParameters mavenParameters,
PluginParameters pluginParameters, String semanticVersioningInformation) throws IOException {
String filename = createFilename(mavenParameters);
@@ -621,6 +640,14 @@ private boolean skipXmlReport(PluginParameters pluginParameters) {
return skipReport || this.skipXmlReport;
}
+ private boolean skipMarkdownReport(PluginParameters pluginParameters) {
+ boolean skipReport = false;
+ if (pluginParameters.getParameterParam() != null) {
+ skipReport = pluginParameters.getParameterParam().getSkipMarkdownReport();
+ }
+ return skipReport || this.skipMarkdownReport;
+ }
+
private String createFilename(MavenParameters mavenParameters) {
String filename = "japicmp";
String executionId = mavenParameters.getMojoExecution().getExecutionId();
diff --git a/japicmp-maven-plugin/src/main/java/japicmp/maven/Parameter.java b/japicmp-maven-plugin/src/main/java/japicmp/maven/Parameter.java
index 8aa3f0f19..51bb6b1ec 100644
--- a/japicmp-maven-plugin/src/main/java/japicmp/maven/Parameter.java
+++ b/japicmp-maven-plugin/src/main/java/japicmp/maven/Parameter.java
@@ -23,6 +23,8 @@ public class Parameter {
@org.apache.maven.plugins.annotations.Parameter(required = false)
private String htmlTitle;
@org.apache.maven.plugins.annotations.Parameter(required = false)
+ private String markdownTitle;
+ @org.apache.maven.plugins.annotations.Parameter(required = false)
private boolean noAnnotations;
@org.apache.maven.plugins.annotations.Parameter(required = false)
private String ignoreNonResolvableArtifacts;
@@ -35,6 +37,8 @@ public class Parameter {
@org.apache.maven.plugins.annotations.Parameter(required = false)
private boolean skipXmlReport;
@org.apache.maven.plugins.annotations.Parameter(required = false)
+ private boolean skipMarkdownReport;
+ @org.apache.maven.plugins.annotations.Parameter(required = false)
private boolean skipDiffReport;
@org.apache.maven.plugins.annotations.Parameter(required = false)
private boolean ignoreMissingOldVersion;
@@ -221,6 +225,14 @@ public void setHtmlTitle(String htmlTitle) {
this.htmlTitle = htmlTitle;
}
+ public String getMarkdownTitle() {
+ return markdownTitle;
+ }
+
+ public void setMarkdownTitle(String markdownTitle) {
+ this.markdownTitle = markdownTitle;
+ }
+
public String getIgnoreNonResolvableArtifacts() {
return ignoreNonResolvableArtifacts;
}
@@ -277,6 +289,14 @@ public void setSkipXmlReport(boolean skipXmlReport) {
this.skipXmlReport = skipXmlReport;
}
+ public boolean getSkipMarkdownReport() {
+ return skipMarkdownReport;
+ }
+
+ public void setSkipMarkdownReport(boolean skipMarkdownReport) {
+ this.skipMarkdownReport = skipMarkdownReport;
+ }
+
public boolean isSkipDiffReport() {
return skipDiffReport;
}
diff --git a/japicmp-testbase/japicmp-test-maven-plugin/pom.xml b/japicmp-testbase/japicmp-test-maven-plugin/pom.xml
index 0df80b09c..16dc67134 100644
--- a/japicmp-testbase/japicmp-test-maven-plugin/pom.xml
+++ b/japicmp-testbase/japicmp-test-maven-plugin/pom.xml
@@ -108,6 +108,7 @@
true
${project.basedir}/src/main/resources/css/stylesheet.css
Test-Title
+ Test-Markdown-Title
@@ -190,6 +191,7 @@
true
true
true
+ true
diff --git a/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITClassFileFormatVersion.java b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITClassFileFormatVersion.java
index 4da3a7335..4ff700387 100644
--- a/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITClassFileFormatVersion.java
+++ b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITClassFileFormatVersion.java
@@ -38,6 +38,24 @@ public void testClassFileFormatVersionIsPresent() throws IOException {
}
}
+ @Test
+ public void testMarkdownReportDiffClassFileFormatVersionIsPresent() throws IOException {
+ Path path = Paths.get(System.getProperty("user.dir"), "target", "japicmp", "class-file-format-version.md");
+ if (!Files.exists(path)) {
+ return; //in JDK 1.7 case
+ }
+ assertThat(Files.exists(path), is(true));
+ List lines = Files.readAllLines(path, StandardCharsets.UTF_8);
+ boolean found = false;
+ for (String line : lines) {
+ if (line.contains("~~JDK 6~~ → **JDK 8**")) {
+ found = true;
+ break;
+ }
+ }
+ assertThat(found, is(true));
+ }
+
@Test
public void testStoutDiffClassFileFormatVersionIsPresent() throws IOException {
Path path = Paths.get(System.getProperty("user.dir"), "target", "japicmp", "class-file-format-version.diff");
diff --git a/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITMarkdownTitle.java b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITMarkdownTitle.java
new file mode 100644
index 000000000..c3af25cef
--- /dev/null
+++ b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITMarkdownTitle.java
@@ -0,0 +1,30 @@
+package japicmp.test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import org.junit.Test;
+
+public class ITMarkdownTitle {
+
+ @Test
+ public void testMarkdownTitle() throws IOException {
+ Path markdownPath = Paths.get(System.getProperty("user.dir"), "target", "japicmp", "single-version.md");
+ assertThat(Files.exists(markdownPath), is(true));
+ List lines = Files.readAllLines(markdownPath, StandardCharsets.UTF_8);
+ boolean found = false;
+ for (String line : lines) {
+ if (line.equals("# Test-Markdown-Title")) {
+ found = true;
+ break;
+ }
+ }
+ assertThat(found, is(true));
+ }
+}
diff --git a/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITModuleExcluded.java b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITModuleExcluded.java
index d565dc30a..194f340fb 100644
--- a/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITModuleExcluded.java
+++ b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITModuleExcluded.java
@@ -21,6 +21,11 @@ public void testHtmlReportNotGenerated() throws IOException {
assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "ignore-module.xml")), is(false));
}
+ @Test
+ public void testMarkdownReportGenerated() throws IOException {
+ assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "ignore-module.md")), is(false));
+ }
+
@Test
public void testDiffReportGenerated() throws IOException {
assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "ignore-module.diff")), is(false));
diff --git a/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITMultipleExecutions.java b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITMultipleExecutions.java
index a54441f6a..d829ff46b 100644
--- a/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITMultipleExecutions.java
+++ b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITMultipleExecutions.java
@@ -14,9 +14,11 @@ public class ITMultipleExecutions {
public void testThatXmlAndHtmlFilesAreWritten() {
assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "multiple-versions.html")), is(true));
assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "multiple-versions.xml")), is(true));
+ assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "multiple-versions.md")), is(true));
assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "multiple-versions.diff")), is(true));
assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "single-version.html")), is(true));
assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "single-version.xml")), is(true));
+ assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "single-version.md")), is(true));
assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "single-version.diff")), is(true));
}
}
diff --git a/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITNoReports.java b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITNoReports.java
index 6cc8ebc8b..5504fecc6 100644
--- a/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITNoReports.java
+++ b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITNoReports.java
@@ -21,6 +21,11 @@ public void testHtmlReportNotGenerated() throws IOException {
assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "no-reports.xml")), is(false));
}
+ @Test
+ public void testMarkdownReportNotGenerated() throws IOException {
+ assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "no-reports.md")), is(false));
+ }
+
@Test
public void testDiffReportGenerated() throws IOException {
assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "no-reports.diff")), is(true));
diff --git a/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITSkip.java b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITSkip.java
index bb44c3a09..007337f0b 100644
--- a/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITSkip.java
+++ b/japicmp-testbase/japicmp-test-maven-plugin/src/test/java/japicmp/test/ITSkip.java
@@ -21,6 +21,11 @@ public void testHtmlReportNotGenerated() throws IOException {
assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "skip.xml")), is(false));
}
+ @Test
+ public void testMarkdownReportGenerated() throws IOException {
+ assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "skip.md")), is(false));
+ }
+
@Test
public void testDiffReportGenerated() throws IOException {
assertThat(Files.exists(Paths.get(System.getProperty("user.dir"), "target", "japicmp", "skip.diff")), is(false));
diff --git a/japicmp/src/main/java/japicmp/cli/CliParser.java b/japicmp/src/main/java/japicmp/cli/CliParser.java
index b0c05216b..7afcfde0e 100644
--- a/japicmp/src/main/java/japicmp/cli/CliParser.java
+++ b/japicmp/src/main/java/japicmp/cli/CliParser.java
@@ -64,6 +64,8 @@ public Options parse(String[] args) throws IllegalArgumentException {
options.setHtmlOutputFile(Optional.fromNullable(pathToHtmlOutputFile));
} else if ("-s".equals(arg) || "--semantic-versioning".equals(arg)) {
options.setSemanticVersioning(true);
+ } else if ("--markdown".equals(arg)) {
+ options.setMarkdown(true);
} else if ("--include-synthetic".equals(arg)) {
options.setIncludeSynthetic(true);
} else if (IGNORE_MISSING_CLASSES.equals(arg)) {
@@ -128,6 +130,7 @@ public static void printHelp() {
" [--old-classpath ]\n" +
" [--report-only-filename] [--report-only-summary]\n" +
" [(-s | --semantic-versioning)]\n" +
+ " [--markdown]\n" +
" [(-x | --xml-file )]\n" +
" [--error-on-binary-incompatibility]\n" +
" [--error-on-source-incompatibility]\n" +
@@ -215,6 +218,9 @@ public static void printHelp() {
" -s, --semantic-versioning\n" +
" Tells you which part of the version to increment.\n" +
"\n" +
+ " --markdown\n" +
+ " Generates output in Markdown format.\n" +
+ "\n" +
" -x , --xml-file \n" +
" Provides the path to the xml output file.\n" +
"\n" +
diff --git a/japicmp/src/main/java/japicmp/cli/JApiCli.java b/japicmp/src/main/java/japicmp/cli/JApiCli.java
index 9ebf17816..9cd4a8487 100644
--- a/japicmp/src/main/java/japicmp/cli/JApiCli.java
+++ b/japicmp/src/main/java/japicmp/cli/JApiCli.java
@@ -9,6 +9,7 @@
import japicmp.output.html.HtmlOutputGenerator;
import japicmp.output.html.HtmlOutputGeneratorOptions;
import japicmp.output.incompatible.IncompatibleErrorOutput;
+import japicmp.output.markdown.MarkdownOutputGenerator;
import japicmp.output.semver.SemverOut;
import japicmp.output.stdout.StdoutOutputGenerator;
import japicmp.output.xml.XmlOutput;
@@ -69,6 +70,12 @@ private void generateOutput(Options options, List jApiClasses, JarArc
throw new JApiCmpException(JApiCmpException.Reason.IoException, "Could not write HTML file: " + e.getMessage(), e);
}
}
+ if (options.isMarkdown()) {
+ MarkdownOutputGenerator markdownOutputGenerator = new MarkdownOutputGenerator(options, jApiClasses);
+ String output = markdownOutputGenerator.generate();
+ System.out.println(output);
+ return;
+ }
StdoutOutputGenerator stdoutOutputGenerator = new StdoutOutputGenerator(options, jApiClasses);
String output = stdoutOutputGenerator.generate();
System.out.println(output);
diff --git a/japicmp/src/main/java/japicmp/config/Options.java b/japicmp/src/main/java/japicmp/config/Options.java
index f0e132740..c9a696068 100644
--- a/japicmp/src/main/java/japicmp/config/Options.java
+++ b/japicmp/src/main/java/japicmp/config/Options.java
@@ -42,6 +42,7 @@ public class Options {
private boolean reportOnlyFilename;
private boolean reportOnlySummary;
private boolean semanticVersioning;
+ private boolean markdown;
private boolean errorOnBinaryIncompatibility;
private boolean errorOnSourceIncompatibility;
private boolean errorOnExclusionIncompatibility = true;
@@ -398,6 +399,14 @@ public boolean isSemanticVersioning() {
return semanticVersioning;
}
+ public void setMarkdown(boolean markdown) {
+ this.markdown = markdown;
+ }
+
+ public boolean isMarkdown() {
+ return markdown;
+ }
+
public boolean isErrorOnBinaryIncompatibility() {
return errorOnBinaryIncompatibility;
}
diff --git a/japicmp/src/main/java/japicmp/output/markdown/Markdown.java b/japicmp/src/main/java/japicmp/output/markdown/Markdown.java
new file mode 100644
index 000000000..eba4769ad
--- /dev/null
+++ b/japicmp/src/main/java/japicmp/output/markdown/Markdown.java
@@ -0,0 +1,55 @@
+package japicmp.output.markdown;
+
+import static java.util.stream.Collectors.joining;
+
+import java.util.stream.Collector;
+
+public abstract class Markdown {
+
+ public static final String EOL = "\n";
+ public static final String PARAGRAPH = "\n\n";
+ public static final String SPACE = " ";
+ public static final String EMPTY = "";
+ public static final String DASH = "-";
+ public static final String UNDERSCORE = "_";
+ public static final String QUOTE = "\"";
+ public static final String BACKSLASH = "\\";
+ public static final String PARENTHESIS_OPEN = "(";
+ public static final String PARENTHESIS_CLOSE = ")";
+ public static final String ANGLE_OPEN = "<";
+ public static final String ANGLE_CLOSE = ">";
+ public static final String BRACKET_OPEN = "[";
+ public static final String BRACKET_CLOSE = "]";
+ public static final String BANG = "!";
+ public static final String HASH = "#";
+ public static final String COLON = ":";
+ public static final String EQUAL = "=";
+ public static final String DOT = ".";
+ public static final char PIPE = '|';
+ public static final String BACKTICK = "`";
+ public static final String MARKDOWN_HORIZONTAL_RULE = "___";
+ public static final Collector LINES = joining(EOL);
+ public static final Collector SPACES = joining(SPACE);
+ public static final Collector CSV = joining(", ");
+ public static final Collector BR = joining("
");
+
+ public static String quotes(String text) {
+ return QUOTE + text + QUOTE;
+ }
+
+ public static String backticks(String text) {
+ return BACKTICK + text + BACKTICK;
+ }
+
+ public static String angles(String text) {
+ return ANGLE_OPEN + text + ANGLE_CLOSE;
+ }
+
+ public static String brackets(String text) {
+ return BRACKET_OPEN + text + BRACKET_CLOSE;
+ }
+
+ public static String parenthesis(String text) {
+ return PARENTHESIS_OPEN + text + PARENTHESIS_CLOSE;
+ }
+}
diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownBadge.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownBadge.java
new file mode 100644
index 000000000..5df2345d1
--- /dev/null
+++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownBadge.java
@@ -0,0 +1,53 @@
+package japicmp.output.markdown;
+
+public class MarkdownBadge extends Markdown {
+
+ static final String BASE_URL = "https://img.shields.io/badge/";
+
+ final String label;
+ final String message;
+ final String color;
+ final String logo;
+
+ public MarkdownBadge(String label, String message, String color, String logo) {
+ this.label = label;
+ this.message = message;
+ this.color = color;
+ this.logo = logo;
+ }
+
+ public MarkdownBadge(String label, String message, String color) {
+ this(label, message, color, null);
+ }
+
+ @Override
+ public String toString() {
+ final String alt = label != null ? label + SPACE + message : message;
+ return new MarkdownImage(alt, getHref(), alt).toString();
+ }
+
+ public MarkdownRefImage toRefImage(MarkdownReferences references, String alt, String title) {
+ return references.make(getHref(), alt, title).toImage(alt);
+ }
+
+ public MarkdownRefImage toRefImage(MarkdownReferences references, String title) {
+ return toRefImage(references, title, title);
+ }
+
+ public MarkdownRefImage toRefImage(MarkdownReferences references) {
+ return toRefImage(references, message);
+ }
+
+ private String getHref() {
+ final String pre = label == null ? EMPTY : label
+ .replace(DASH, UNDERSCORE)
+ .replace(SPACE, UNDERSCORE)
+ .replace(HASH, COLON) + DASH;
+ final String msg = message
+ .replace(DASH, UNDERSCORE)
+ .replace(SPACE, UNDERSCORE)
+ .replace(HASH, COLON);
+ final String arg = logo == null ? EMPTY : "?logo" + EQUAL + logo;
+ return BASE_URL + pre + msg + DASH + color + arg;
+ }
+}
diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownImage.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownImage.java
new file mode 100644
index 000000000..cae245db4
--- /dev/null
+++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownImage.java
@@ -0,0 +1,13 @@
+package japicmp.output.markdown;
+
+final class MarkdownImage extends MarkdownLink {
+
+ MarkdownImage(String alt, String href, String title) {
+ super(alt, href, title);
+ }
+
+ @Override
+ public String toString() {
+ return BANG + super.toString();
+ }
+}
diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownLink.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownLink.java
new file mode 100644
index 000000000..eedb0a194
--- /dev/null
+++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownLink.java
@@ -0,0 +1,16 @@
+package japicmp.output.markdown;
+
+class MarkdownLink extends MarkdownReference {
+
+ final String text;
+
+ MarkdownLink(String text, String href, String title) {
+ super(href, title);
+ this.text = text == null ? EMPTY : text;
+ }
+
+ @Override
+ public String toString() {
+ return brackets(text) + parenthesis(super.toString());
+ }
+}
diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownList.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownList.java
new file mode 100644
index 000000000..369033d88
--- /dev/null
+++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownList.java
@@ -0,0 +1,33 @@
+package japicmp.output.markdown;
+
+import static java.util.Arrays.*;
+import static java.util.stream.Collectors.toList;
+
+import java.util.List;
+import java.util.stream.Stream;
+
+class MarkdownList extends Markdown {
+
+ private final String pad;
+ private final List elements;
+
+ MarkdownList(String... elements) {
+ this.pad = EMPTY;
+ this.elements = asList(elements);
+ }
+
+ MarkdownList(int level, Stream elements) {
+ final String format = "%-" + (level * 2) + "s";
+ this.pad = String.format(format, EMPTY);
+ this.elements = elements.collect(toList());
+ }
+
+ MarkdownList(int level, String... elements) {
+ this(level, stream(elements));
+ }
+
+ @Override
+ public String toString() {
+ return (pad.isEmpty() || elements.isEmpty() ? EMPTY : EOL) + elements.stream().filter(x -> x != null && !x.isEmpty()).map(e -> pad + "- " + e).collect(LINES);
+ }
+}
diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownOutputGenerator.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownOutputGenerator.java
new file mode 100644
index 000000000..0666647ef
--- /dev/null
+++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownOutputGenerator.java
@@ -0,0 +1,602 @@
+package japicmp.output.markdown;
+
+import static japicmp.model.JApiChangeStatus.*;
+import static japicmp.output.markdown.Markdown.*;
+import static japicmp.util.JApiClassFileFormatVersionHelper.*;
+import static japicmp.util.MemberValueHelper.formatMemberValue;
+import static japicmp.util.ModifierHelper.*;
+import static japicmp.util.OptionalHelper.N_A;
+import static japicmp.util.TypeNameHelper.*;
+import static java.lang.String.format;
+import static java.util.Collections.*;
+import static java.util.stream.Collectors.*;
+
+import japicmp.cmp.JApiCmpArchive;
+import japicmp.config.*;
+import japicmp.filter.Filter;
+import japicmp.model.*;
+import japicmp.model.JApiJavaObjectSerializationCompatibility.JApiJavaObjectSerializationChangeStatus;
+import japicmp.output.*;
+import japicmp.output.markdown.config.MarkdownOptions;
+import japicmp.output.semver.SemverOut;
+import japicmp.util.Optional;
+import java.util.*;
+import java.util.regex.Pattern;
+import java.util.stream.Stream;
+import javassist.bytecode.annotation.MemberValue;
+
+public class MarkdownOutputGenerator extends OutputGenerator {
+
+ final MarkdownOptions md;
+ final MarkdownReferences references = new MarkdownReferences();
+
+ public MarkdownOutputGenerator(MarkdownOptions mdOptions, List jApiClasses) {
+ super(mdOptions.options, jApiClasses);
+ md = mdOptions;
+ }
+
+ public MarkdownOutputGenerator(Options options, List jApiClasses) {
+ this(MarkdownOptions.newDefault(options), jApiClasses);
+ }
+
+ @Override
+ public String generate() {
+ final String semver = new SemverOut(options, jApiClasses).generate();
+ return renderHeading(0, md.title.report) +
+ md.message.getSemverBadge(semver) + EOL +
+ renderHeading(1, md.title.summary) +
+ renderReportSummary(md.message.getSummaryMessage(semver), options) + PARAGRAPH +
+ renderHtmlDetails(md.message.expandOptions, renderReportOptions(options)) +
+ renderReportResults(options) + EOL +
+ renderMissingClassesWarning(options.getIgnoreMissingClasses()) +
+ MARKDOWN_HORIZONTAL_RULE + PARAGRAPH +
+ format(md.message.generatedOn, md.message.getCurrentTimestamp()) + PARAGRAPH +
+ references + EOL;
+ }
+
+ private String renderHeading(int level, String text) {
+ final StringBuilder tmp = new StringBuilder();
+ tmp.append(EOL);
+ for (int repeat = 0; repeat < md.title.topHeadingLevel + level && repeat < 6; repeat++) {
+ tmp.append(HASH);
+ }
+ tmp.append(" ");
+ tmp.append(text);
+ tmp.append(PARAGRAPH);
+ return tmp.toString();
+ }
+
+ private String renderReportSummary(String summary, Options options) {
+ final String newVersion = renderArchivesVersion(md.targetNewVersion, options.getNewArchives(), md.message.oneNewVersion, md.message.manyNewArchives);
+ final String oldVersion = renderArchivesVersion(md.targetOldVersion, options.getOldArchives(), md.message.oneOldVersion, md.message.manyOldArchives);
+ return format(summary, newVersion, oldVersion);
+ }
+
+ private String renderReportOptions(Options options) {
+ final List patterns = options.getIgnoreMissingClasses().getIgnoreMissingClassRegularExpression();
+ return new MarkdownList(
+ format(md.message.reportOnlySummary, md.message.yesNo(options.isReportOnlySummary())),
+ format(md.message.reportOnlyChanges, md.message.yesNo(options.isOutputOnlyModifications())),
+ format(md.message.reportOnlyBinaryIncompatibleChanges, md.message.yesNo(options.isOutputOnlyBinaryIncompatibleModifications())),
+ format(md.message.accessModifierFilter, options.getAccessModifier()),
+ format(md.message.oldArchives, new MarkdownList(1, options.getOldArchives().stream().map(this::renderArchive))),
+ format(md.message.newArchives, new MarkdownList(1, options.getNewArchives().stream().map(this::renderArchive))),
+ format(md.message.evaluateAnnotations, md.message.yesNo(!options.isNoAnnotations())),
+ format(md.message.includeSynthetic, md.message.yesNo(options.isIncludeSynthetic())),
+ format(md.message.includeSpecificElements, md.message.yesNo(!options.getIncludes().isEmpty()) + new MarkdownList(1, options.getIncludes().stream().filter(Objects::nonNull).map(Filter::toString).distinct().map(this::renderCode))),
+ format(md.message.excludeSpecificElements, md.message.yesNo(!options.getExcludes().isEmpty()) + new MarkdownList(1, options.getExcludes().stream().filter(Objects::nonNull).map(Filter::toString).distinct().map(this::renderCode))),
+ format(md.message.ignoreAllMissingClasses, md.message.yesNo(options.getIgnoreMissingClasses().isIgnoreAllMissingClasses())),
+ format(md.message.ignoreSpecificMissingClasses, md.message.yesNo(!patterns.isEmpty()) + new MarkdownList(1, patterns.stream().map(Pattern::pattern).map(this::renderCode))),
+ format(md.message.treatChangesAsErrors, new MarkdownList(1,
+ format(md.message.anyChanges, md.message.yesNo(options.isErrorOnModifications())),
+ format(md.message.binaryIncompatibleChanges, md.message.yesNo(options.isErrorOnBinaryIncompatibility())),
+ format(md.message.sourceIncompatibleChanges, md.message.yesNo(options.isErrorOnSourceIncompatibility())),
+ format(md.message.incompatibleChangesCausedByExcludedClasses, md.message.yesNo(options.isErrorOnExclusionIncompatibility())),
+ format(md.message.semanticallyIncompatibleChanges, md.message.yesNo(options.isErrorOnSemanticIncompatibility())),
+ format(md.message.semanticallyIncompatibleChangesIncludingDevelopmentVersions, md.message.yesNo(options.isErrorOnSemanticIncompatibilityForMajorVersionZero())))
+ ),
+ format(md.message.classpathMode, options.getClassPathMode()),
+ format(md.message.oldClasspath, options.getOldClassPath().or(EMPTY)),
+ format(md.message.newClasspath, options.getNewClassPath().or(EMPTY))
+ ) + EOL;
+ }
+
+ private String renderArchivesVersion(Optional version, List archives, String one, String many) {
+ if (version.isPresent()) {
+ return format(one, version.get());
+ }
+ if (archives.isEmpty()) {
+ return format(one, md.message.unknownVersion);
+ }
+ if (archives.size() == 1) {
+ final JApiCmpArchive archive = archives.get(0);
+ final String archiveVersion = archive.getVersion().getStringVersion();
+ if (archiveVersion != null && !archiveVersion.equals(N_A)) {
+ return format(one, archiveVersion);
+ }
+ return format(one, renderSimpleArchiveName(archive));
+ }
+ return many;
+ }
+
+ private String renderReportResults(Options options) {
+ new OutputFilter(options).filter(jApiClasses);
+ if (jApiClasses.isEmpty()) {
+ return EMPTY;
+ }
+ return new MarkdownSection<>(renderHeading(1, md.title.results), jApiClasses, md.sort.classes)
+ .column(md.header.status, this::renderStatus)
+ .column(md.header.type, this::renderClassLink)
+ .column(md.header.serialization, this::renderSerializationChange)
+ .column(md.header.compatibilityChanges, this::renderAllCompatibilityChanges) +
+ (md.options.isReportOnlySummary() ? "" : renderHtmlDetails(md.message.expandResults, jApiClasses.stream().sorted(md.sort.classes).map(this::renderClass).collect(joining())));
+ }
+
+ private String renderMissingClassesWarning(IgnoreMissingClasses missing) {
+ if (missing.isIgnoreAllMissingClasses()) {
+ return md.message.warningAllMissingClassesIgnored;
+ } else if (!missing.getIgnoreMissingClassRegularExpression().isEmpty()) {
+ return md.message.warningSomeMissingClassesIgnored;
+ }
+ return EMPTY;
+ }
+
+ private String renderClass(JApiClass clazz) {
+ final String name = clazz.getFullyQualifiedName();
+ return MARKDOWN_HORIZONTAL_RULE + PARAGRAPH +
+ renderHtmlAnchor(name) +
+ renderHeading(2, renderCode(name)) +
+ renderCompatibilityList(clazz) + PARAGRAPH +
+ renderClassInfo(clazz) +
+ renderGenericTemplates(clazz) +
+ renderImplementedInterfaces(clazz) +
+ renderAnnotations(clazz) +
+ renderConstructors(clazz) +
+ renderMethods(clazz) +
+ renderFields(clazz);
+ }
+
+ private String renderHtmlAnchor(String id) {
+ return angles("a" + SPACE + "id" + EQUAL + quotes(renderSlug(id))) + angles("/a");
+ }
+
+ private String renderHtmlDetails(String summary, String details) {
+ return angles("details" + SPACE + "markdown" + EQUAL + quotes("1")) + EOL +
+ angles("summary") + summary + angles("/summary") + PARAGRAPH +
+ details + EOL +
+ angles("/details") + PARAGRAPH;
+ }
+
+ private String renderSlug(String id) {
+ return "user-content-" + id.toLowerCase();
+ }
+
+ private Markdown renderCompatibilityList(JApiClass clazz) {
+ return new MarkdownList(
+ format(md.message.compatibilityBinary, md.message.checkbox(clazz.isBinaryCompatible())),
+ format(md.message.compatibilitySource, md.message.checkbox(clazz.isSourceCompatible())),
+ format(md.message.compatibilitySerialization, md.message.checkbox(
+ !clazz.getJavaObjectSerializationCompatible().isIncompatible())));
+ }
+
+ private Markdown renderClassInfo(JApiClass clazz) {
+ return new MarkdownSection<>(EMPTY, clazz)
+ .column(md.header.status, this::renderStatus)
+ .column(md.header.modifiers, this::renderModifiers)
+ .column(md.header.classType, this::renderClassType)
+ .column(md.header.className, this::renderClassSimpleName)
+ .column(md.header.superclass, this::renderClassSuperclass)
+ .column(md.header.classJdk, this::renderClassJdk)
+ .column(md.header.serialization, this::renderSerializationChange)
+ .column(md.header.compatibilityChanges, this::renderClassLevelCompatibilityChanges);
+ }
+
+ private Markdown renderGenericTemplates(JApiClass clazz) {
+ return new MarkdownSection<>(renderHeading(3, md.title.generics), clazz.getGenericTemplates(), md.sort.generics)
+ .column(md.header.status, this::renderStatus)
+ .column(md.header.genericTemplateName, this::renderGenericTemplateName)
+ .column(md.header.genericTemplateType, this::renderGenericTemplateType)
+ .column(md.header.compatibilityChanges, this::renderCompatibilityChanges);
+ }
+
+ private Markdown renderImplementedInterfaces(JApiClass clazz) {
+ return new MarkdownSection<>(renderHeading(3, md.title.interfaces), clazz.getInterfaces(), md.sort.interfaces)
+ .column(md.header.status, this::renderStatus)
+ .column(md.header.interfaceName, this::renderImplementedInterfaceName)
+ .column(md.header.compatibilityChanges, this::renderCompatibilityChanges);
+ }
+
+ private Markdown renderAnnotations(JApiClass clazz) {
+ return new MarkdownSection<>(renderHeading(3, md.title.annotations), clazz.getAnnotations(), md.sort.annotations)
+ .column(md.header.status, this::renderStatus)
+ .column(md.header.annotationName, this::renderAnnotation)
+ .column(md.header.compatibilityChanges, this::renderAllCompatibilityChanges);
+ }
+
+ private Markdown renderConstructors(JApiClass clazz) {
+ return new MarkdownSection<>(renderHeading(3, md.title.constructors), clazz.getConstructors(), md.sort.constructors)
+ .column(md.header.status, this::renderStatus)
+ .column(md.header.modifiers, this::renderModifiers)
+ .column(md.header.generics, this::renderGenericTemplates)
+ .column(md.header.constructorNameAndParameters, this::renderNameAndParameters)
+ .column(md.header.annotations, this::renderInlineAnnotations)
+ .column(md.header.exceptions, this::renderExceptions)
+ .column(md.header.compatibilityChanges, this::renderAllCompatibilityChanges);
+ }
+
+ private Markdown renderMethods(JApiClass clazz) {
+ return new MarkdownSection<>(renderHeading(3, md.title.methods), clazz.getMethods(), md.sort.methods)
+ .column(md.header.status, this::renderStatus)
+ .column(md.header.modifiers, this::renderModifiers)
+ .column(md.header.generics, this::renderGenericTemplates)
+ .column(md.header.methodReturnType, this::renderReturnType)
+ .column(md.header.methodNameAndParameters, this::renderNameAndParameters)
+ .column(md.header.annotations, this::renderInlineAnnotations)
+ .column(md.header.exceptions, this::renderExceptions)
+ .column(md.header.compatibilityChanges, this::renderAllCompatibilityChanges);
+ }
+
+ private Markdown renderFields(JApiClass clazz) {
+ return new MarkdownSection<>(renderHeading(3, md.title.fields), clazz.getFields(), md.sort.fields)
+ .column(md.header.status, this::renderStatus)
+ .column(md.header.modifiers, this::renderModifiers)
+ .column(md.header.fieldType, this::renderFieldType)
+ .column(md.header.fieldName, this::renderFieldName)
+ .column(md.header.annotations, this::renderInlineAnnotations)
+ .column(md.header.compatibilityChanges, this::renderCompatibilityChanges);
+ }
+
+ private String renderStatus(JApiHasChangeStatus element) {
+ final boolean isBinaryCompatible = ((JApiCompatibility) element).isBinaryCompatible();
+ final boolean isSourceCompatible = ((JApiCompatibility) element).isSourceCompatible();
+ final boolean isSerializationCompatible = !(element instanceof JApiJavaObjectSerializationCompatibility)
+ || !((JApiJavaObjectSerializationCompatibility) element).getJavaObjectSerializationCompatible().isIncompatible();
+ final boolean isFullyCompatible = isBinaryCompatible && isSourceCompatible && isSerializationCompatible;
+ if (element.getChangeStatus() != UNCHANGED || isFullyCompatible) {
+ return renderLiteralStatus(element);
+ } else if (!isBinaryCompatible && !isSourceCompatible) {
+ return md.message.statusIncompatible;
+ } else if (!isBinaryCompatible) {
+ return md.message.statusBinaryIncompatible;
+ } else if (!isSourceCompatible) {
+ return md.message.statusSourceIncompatible;
+ }
+ return md.message.statusSerializationIncompatible;
+ }
+
+ private String renderLiteralStatus(JApiHasChangeStatus element) {
+ switch (element.getChangeStatus()) {
+ case NEW:
+ return md.message.statusNew;
+ case REMOVED:
+ return md.message.statusRemoved;
+ case UNCHANGED:
+ return md.message.statusUnchanged;
+ default:
+ case MODIFIED:
+ return md.message.statusModified;
+ }
+ }
+
+ private String renderClassLink(JApiClass clazz) {
+ final String name = clazz.getFullyQualifiedName();
+ return md.options.isReportOnlySummary() ? name : references.link(HASH + renderSlug(name), name, null).toString();
+ }
+
+ private String renderClassSimpleName(JApiClass clazz) {
+ final String simpleName = formatTypeName(clazz.getFullyQualifiedName(), emptyList(), true);
+ return renderChange(clazz, renderCode(simpleName));
+ }
+
+ private String renderClassType(JApiClass clazz) {
+ final JApiClassType classType = clazz.getClassType();
+ return renderChange(classType, md.message.getClassType(classType.getOldTypeOptional()), md.message.getClassType(classType.getNewTypeOptional()));
+ }
+
+ private String renderClassSuperclass(JApiClass clazz) {
+ final JApiSuperclass superclass = clazz.getSuperclass();
+ final JApiClass correspondingClass = superclass.getCorrespondingJApiClass().or((JApiClass) null);
+ return renderChange(superclass,
+ renderTypeWithGenericTemplates(superclass.getOldSuperclassName().or((String) null), superclass, correspondingClass),
+ renderTypeWithGenericTemplates(superclass.getNewSuperclassName().or((String) null), superclass, correspondingClass));
+ }
+
+ private String renderClassJdk(JApiClass clazz) {
+ final JApiClassFileFormatVersion version = clazz.getClassFileFormatVersion();
+ return renderChange(version, getOldJdkVersion(version), getNewJdkVersion(version));
+ }
+
+ private String renderGenericTemplateName(JApiGenericTemplate genericTemplate) {
+ return renderChange(genericTemplate, renderCode(genericTemplate.getName()));
+ }
+
+ private String renderGenericTemplateType(JApiGenericTemplate genericTemplate) {
+ return renderChange(genericTemplate,
+ renderTypeWithGenericTypes(genericTemplate.getOldType(), genericTemplate.getOldGenericTypes()),
+ renderTypeWithGenericTypes(genericTemplate.getNewType(), genericTemplate.getNewGenericTypes()));
+ }
+
+ private String renderImplementedInterfaceName(JApiImplementedInterface implInterface) {
+ return renderChange(implInterface, renderTypeWithGenericTemplates(
+ implInterface.getFullyQualifiedName(), implInterface, implInterface.getCorrespondingJApiClass().or((JApiClass) null)));
+ }
+
+ private String renderNameAndParameters(JApiBehavior behavior) {
+ final String name = behavior.getName();
+ final int pos = name != null ? name.lastIndexOf('$') : -1;
+ final String simpleName = pos > 0 ? name.substring(pos + 1) : name;
+ return renderChange(behavior, renderCode(simpleName)) + renderParameters(behavior);
+ }
+
+ private String renderParameters(JApiBehavior behavior) {
+ return parenthesis(behavior.getParameters().stream().map(x -> renderParameter(behavior, x)).collect(CSV));
+ }
+
+ private String renderParameter(JApiBehavior method, JApiParameter parameter) {
+ if (parameter.getTemplateNameOptional().isPresent()) {
+ return renderChange(parameter, renderCode(parameter.getTemplateName()));
+ }
+ final JApiChangeStatus status = method.getChangeStatus();
+ final JApiModifier varargs = method.getVarargsModifier();
+ final String oldType = (status == NEW) ? null : renderParameterType(method, parameter, varargs.getOldModifier(), parameter.getOldGenericTypes());
+ final String newType = (status == REMOVED) ? null : renderParameterType(method, parameter, varargs.getNewModifier(), parameter.getNewGenericTypes());
+ return renderChange(parameter, oldType, newType);
+ }
+
+ private String renderGenericTemplates(JApiBehavior behavior) {
+ final List genericTemplates = behavior.getGenericTemplates();
+ if (genericTemplates.isEmpty()) {
+ return EMPTY;
+ }
+ return BACKSLASH + ANGLE_OPEN +
+ genericTemplates.stream().map(this::renderGenericTemplate).collect(CSV) +
+ BACKSLASH + ANGLE_CLOSE;
+ }
+
+ private String renderGenericTemplate(JApiGenericTemplate genericTemplate) {
+ final String name = genericTemplate.getName();
+ final String oldTemplate = renderGenericTemplate(name, genericTemplate.getOldTypeOptional().or((String) null), genericTemplate.getOldGenericTypes());
+ final String newTemplate = renderGenericTemplate(name, genericTemplate.getNewTypeOptional().or((String) null), genericTemplate.getNewGenericTypes());
+ return renderChange(genericTemplate, oldTemplate, newTemplate);
+ }
+
+ private String renderGenericTemplate(String name, String type, List genericTypes) {
+ final String fullType = formatGenericTemplate(name, type, genericTypes, false);
+ final String simpleType = formatGenericTemplate(name, type, genericTypes, true);
+ return renderCodeWithTooltip(fullType, simpleType);
+ }
+
+ private String renderCompatibilityChanges(List changes) {
+ if (changes.isEmpty()) {
+ return renderNoChangesBadge();
+ }
+ return changes.stream().map(this::renderChangeBadge).collect(SPACES);
+ }
+
+ private String renderCompatibilityChanges(JApiCompatibility hasCompatibilityChanges) {
+ return renderCompatibilityChanges(hasCompatibilityChanges.getCompatibilityChanges());
+ }
+
+ @SafeVarargs
+ private final String renderCompatibilityChanges(List extends JApiCompatibility>... haveCompatibilityChanges) {
+ return renderCompatibilityChanges(Stream.of(haveCompatibilityChanges).flatMap(List::stream)
+ .map(JApiCompatibility::getCompatibilityChanges).flatMap(List::stream).distinct().collect(toList()));
+ }
+
+ private String renderAllCompatibilityChanges(JApiClass clazz) {
+ final Stream> allCompatibilityChanges = Stream.of(
+ singletonList(clazz),
+ singletonList(clazz.getClassFileFormatVersion()),
+ singletonList(clazz.getSuperclass()),
+ clazz.getGenericTemplates(),
+ clazz.getInterfaces(),
+ clazz.getAnnotations(),
+ clazz.getAnnotations().stream().map(JApiAnnotation::getElements).flatMap(List::stream).collect(toList()),
+ clazz.getConstructors(),
+ clazz.getConstructors().stream().map(JApiConstructor::getParameters).flatMap(List::stream).collect(toList()),
+ clazz.getMethods(),
+ clazz.getMethods().stream().map(JApiMethod::getReturnType).collect(toList()),
+ clazz.getMethods().stream().map(JApiMethod::getParameters).flatMap(List::stream).collect(toList()),
+ clazz.getFields());
+ return renderCompatibilityChanges(allCompatibilityChanges
+ .flatMap(List::stream)
+ .map(JApiCompatibility::getCompatibilityChanges)
+ .flatMap(List::stream)
+ .distinct().sorted(Comparator.comparing(JApiCompatibilityChange::getType))
+ .collect(toList()));
+ }
+
+ private String renderClassLevelCompatibilityChanges(JApiClass clazz) {
+ return renderCompatibilityChanges(Arrays.asList(clazz, clazz.getClassFileFormatVersion(), clazz.getSuperclass()));
+ }
+
+ private String renderAllCompatibilityChanges(JApiAnnotation annotation) {
+ return renderCompatibilityChanges(singletonList(annotation), annotation.getElements());
+ }
+
+ private String renderAllCompatibilityChanges(JApiConstructor constructor) {
+ return renderCompatibilityChanges(singletonList(constructor), constructor.getParameters());
+ }
+
+ private String renderAllCompatibilityChanges(JApiMethod method) {
+ return renderCompatibilityChanges(singletonList(method), singletonList(method.getReturnType()), method.getParameters());
+ }
+
+ private String renderNoChangesBadge() {
+ return new MarkdownBadge(null, md.message.noCompatibilityChanges, md.message.colorNoChanges)
+ .toRefImage(references).toString();
+ }
+
+ private String renderChangeBadge(JApiCompatibilityChange change) {
+ final JApiCompatibilityChangeType type = change.getType();
+ return new MarkdownBadge(null, md.message.compatibilityChangeType.getOrDefault(type, type.name()), md.message.getSemanticColor(change.getSemanticVersionLevel()))
+ .toRefImage(references).toString();
+ }
+
+ private String renderSerializationChange(JApiClass clazz) {
+ final JApiJavaObjectSerializationChangeStatus change = clazz.getJavaObjectSerializationCompatible();
+ final String text = md.message.serializationCompatibility.getOrDefault(change, change.getDescription());
+ final String color = change.isIncompatible() ? md.message.colorMajorChanges : md.message.colorNoChanges;
+ final String msg = change.isIncompatible() ? md.message.statusIncompatible : text;
+ return new MarkdownBadge(null, msg, color).toRefImage(references, text).toString();
+ }
+
+ private String renderChange(JApiHasChangeStatus hasStatus, String oldValue, String newValue) {
+ if (oldValue == null && newValue == null) {
+ return null;
+ }
+ switch (hasStatus.getChangeStatus()) {
+ case NEW:
+ return newValue == null ? null : format(md.message.added, newValue);
+ case REMOVED:
+ return oldValue == null ? null : format(md.message.removed, oldValue);
+ case UNCHANGED:
+ if (newValue == null) {
+ return format(md.message.unchanged, oldValue);
+ } else if (oldValue == null || newValue.equals(oldValue)) {
+ return format(md.message.unchanged, newValue);
+ }
+ return format(md.message.modified, oldValue, newValue);
+ default:
+ case MODIFIED:
+ if (oldValue == null) {
+ return format(md.message.added, newValue);
+ } else if (newValue == null) {
+ return format(md.message.removed, oldValue);
+ } else if (newValue.equals(oldValue)) {
+ return format(md.message.unchanged, newValue);
+ }
+ return format(md.message.modified, oldValue, newValue);
+ }
+ }
+
+ private String renderChange(JApiHasChangeStatus status, String value) {
+ return renderChange(status, value, value);
+ }
+
+ private String renderModifiers(JApiHasModifiers clazz) {
+ return clazz.getModifiers().stream().map(this::renderModifier)
+ .filter(Objects::nonNull).collect(SPACES);
+ }
+
+ private String renderModifier(JApiModifier extends Enum extends Enum>>> modifier) {
+ final String oldName = getOldModifierName(modifier).or((String) null);
+ final String newName = getNewModifierName(modifier).or((String) null);
+ return renderChange(modifier, renderCode(oldName), renderCode(newName));
+ }
+
+ private String renderTypeWithGenericTypes(String type, List genericTypes) {
+ if (type == null) {
+ return null;
+ }
+ final String fullType = formatTypeName(type, genericTypes, false);
+ final String simpleType = formatTypeName(type, genericTypes, true);
+ return renderCodeWithTooltip(fullType, simpleType);
+ }
+
+ private String renderTypeWithGenericTemplates(String type, JApiHasChangeStatus hasChangeStatus, JApiHasGenericTemplates hasGenericTemplates) {
+ if (type == null) {
+ return null;
+ }
+ final String fullType = formatTypeName(type, hasChangeStatus, hasGenericTemplates, false);
+ final String simpleType = formatTypeName(type, hasChangeStatus, hasGenericTemplates, true);
+ return renderCodeWithTooltip(fullType, simpleType);
+ }
+
+ private String renderParameterType(JApiBehavior method, JApiParameter parameter, Optional varargs, List genericTypes) {
+ if (parameter.getType() == null) {
+ return null;
+ }
+ final String fullType = formatParameterTypeName(method, parameter, varargs, genericTypes, false);
+ final String simpleType = formatParameterTypeName(method, parameter, varargs, genericTypes, true);
+ return renderCodeWithTooltip(fullType, simpleType);
+ }
+
+ private String renderMemberValue(Optional optionalValue) {
+ if (!optionalValue.isPresent()) {
+ return EMPTY;
+ }
+ final String fullValue = formatMemberValue(optionalValue.get(), false);
+ final String simpleValue = formatMemberValue(optionalValue.get(), true);
+ return renderCodeWithTooltip(fullValue, simpleValue);
+ }
+
+ private String renderReturnType(JApiMethod method) {
+ final JApiReturnType returnType = method.getReturnType();
+ return renderChange(returnType,
+ renderTypeWithGenericTypes(returnType.getOldReturnType(), returnType.getOldGenericTypes()),
+ renderTypeWithGenericTypes(returnType.getNewReturnType(), returnType.getNewGenericTypes()));
+ }
+
+ private String renderFieldType(JApiField field) {
+ final JApiType fieldType = field.getType();
+ return renderChange(fieldType,
+ renderTypeWithGenericTypes(fieldType.getOldValue(), field.getOldGenericTypes()),
+ renderTypeWithGenericTypes(fieldType.getNewValue(), field.getNewGenericTypes()));
+ }
+
+ private String renderFieldName(JApiField field) {
+ return renderCode(field.getName());
+ }
+
+ private String renderExceptions(JApiBehavior behavior) {
+ return behavior.getExceptions().stream().map(this::renderException).collect(CSV);
+ }
+
+ private String renderException(JApiException exception) {
+ return renderChange(exception, renderTypeWithGenericTypes(exception.getName(), emptyList()));
+ }
+
+ private String renderInlineAnnotations(JApiHasAnnotations hasAnnotations) {
+ return hasAnnotations.getAnnotations().stream().map(this::renderAnnotation).collect(BR);
+ }
+
+ private String renderAnnotation(JApiAnnotation annotation) {
+ final String typeName = renderTypeWithGenericTemplates(annotation.getFullyQualifiedName(), annotation, annotation.getCorrespondingJApiClass().or((JApiClass) null));
+ return renderChange(annotation, typeName) +
+ (annotation.getElements().isEmpty() ? EMPTY : COLON + SPACE) +
+ annotation.getElements().stream().map(this::renderAnnotationElement).collect(CSV);
+ }
+
+ private String renderAnnotationElement(JApiAnnotationElement element) {
+ return renderChange(element, renderCode(element.getName())) + EQUAL +
+ renderChange(element, renderMemberValue(element.getOldValue()), renderMemberValue(element.getNewValue()));
+ }
+
+ private String renderCode(String text) {
+ return text == null || text.isEmpty() ? text : backticks(text);
+ }
+
+ private String renderCodeWithTooltip(String fullType, String simpleType) {
+ if (fullType.equals(simpleType)) {
+ return renderCode(simpleType);
+ }
+ return references.link(null, renderCode(simpleType), fullType).toString();
+ }
+
+ String renderArchive(JApiCmpArchive archive) {
+ final String label = renderSimpleArchiveName(archive);
+ final String version = archive.getVersion().getStringVersion();
+ final String message = version != null && !version.equals(N_A) ? version : md.message.unknownVersion;
+ return new MarkdownBadge(label, message, md.message.colorVersionNumber).toString();
+ }
+
+ String renderSimpleArchiveName(JApiCmpArchive archive) {
+ final String version = archive.getVersion().getStringVersion();
+ String name = archive.getFile().getName();
+ // Drop version from archive name
+ if (version != null && name.contains(version)) {
+ name = name.replace(version, EMPTY);
+ }
+ // Drop extension from archive name
+ final int dot = name.lastIndexOf(DOT);
+ if (dot > 0) {
+ name = name.substring(0, dot);
+ }
+ // Drop trailing dashes or underscores
+ if (name.endsWith(DASH) || name.endsWith(UNDERSCORE)) {
+ name = name.substring(0, name.length() - 1);
+ }
+ return name;
+ }
+}
diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownRefImage.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownRefImage.java
new file mode 100644
index 000000000..aa7a5297a
--- /dev/null
+++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownRefImage.java
@@ -0,0 +1,13 @@
+package japicmp.output.markdown;
+
+final class MarkdownRefImage extends MarkdownRefLink {
+
+ MarkdownRefImage(String alt, MarkdownStoredReference reference) {
+ super(alt, reference);
+ }
+
+ @Override
+ public String toString() {
+ return BANG + super.toString();
+ }
+}
diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownRefLink.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownRefLink.java
new file mode 100644
index 000000000..50119f923
--- /dev/null
+++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownRefLink.java
@@ -0,0 +1,17 @@
+package japicmp.output.markdown;
+
+class MarkdownRefLink extends Markdown {
+ private final String text;
+ private final MarkdownStoredReference reference;
+
+ MarkdownRefLink(String text, MarkdownStoredReference reference) {
+ this.text = text != null ? text : EMPTY;
+ this.reference = reference;
+ }
+
+ @Override
+ public String toString() {
+ return brackets(text) +
+ (text.equals(reference.id) ? EMPTY : brackets(reference.id));
+ }
+}
diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownReference.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownReference.java
new file mode 100644
index 000000000..ce2a09d47
--- /dev/null
+++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownReference.java
@@ -0,0 +1,40 @@
+package japicmp.output.markdown;
+
+import japicmp.util.Optional;
+import java.util.Objects;
+
+class MarkdownReference extends Markdown {
+
+ final String href;
+ final String title;
+
+ MarkdownReference(String href, String title) {
+ this.href = Optional.fromNullable(href).or(HASH);
+ this.title = title;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ } else if (obj instanceof MarkdownReference) {
+ final MarkdownReference that = (MarkdownReference) obj;
+ return Objects.equals(href, that.href) && Objects.equals(title, that.title);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(href, title);
+ }
+
+ @Override
+ public String toString() {
+ if (title == null || title.isEmpty()) {
+ return href;
+ }
+ final String sanitizedTitle = title.replace(QUOTE, BACKSLASH + QUOTE);
+ return href + SPACE + quotes(sanitizedTitle);
+ }
+}
diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownReferences.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownReferences.java
new file mode 100644
index 000000000..8e2c4a2d3
--- /dev/null
+++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownReferences.java
@@ -0,0 +1,48 @@
+package japicmp.output.markdown;
+
+import static java.util.Comparator.comparing;
+
+import java.util.ArrayList;
+import java.util.List;
+
+final class MarkdownReferences extends Markdown {
+
+ private final List references = new ArrayList<>();
+ private int referenceId;
+
+ MarkdownStoredReference make(String href, String id, String title) {
+ final MarkdownReference reference = new MarkdownReference(href, title);
+ return references.stream().filter(reference::equals).findAny()
+ .orElseGet(() -> storeReference(id, reference));
+ }
+
+ MarkdownRefLink link(String href, String text, String title) {
+ return make(href, text, title).toLink(text);
+ }
+
+ private MarkdownStoredReference storeReference(String id, MarkdownReference reference) {
+ final MarkdownStoredReference stored;
+ if (isIllegalReferenceId(id) || alreadyUsedReferenceId(id)) {
+ stored = new MarkdownStoredReference(++referenceId, reference);
+ } else {
+ stored = new MarkdownStoredReference(id, reference);
+ }
+ references.add(stored);
+ return stored;
+ }
+
+ private boolean isIllegalReferenceId(String text) {
+ return text == null || text.isEmpty() || text.contains(BRACKET_OPEN) || text.contains(BRACKET_CLOSE);
+ }
+
+ private boolean alreadyUsedReferenceId(String id) {
+ return references.stream().map(MarkdownStoredReference::getId).anyMatch(id::equals);
+ }
+
+ @Override
+ public String toString() {
+ return references.stream()
+ .sorted(comparing(MarkdownStoredReference::getIndex).thenComparing(MarkdownStoredReference::getId))
+ .map(MarkdownStoredReference::toString).collect(LINES);
+ }
+}
diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownSection.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownSection.java
new file mode 100644
index 000000000..4b42b5db0
--- /dev/null
+++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownSection.java
@@ -0,0 +1,54 @@
+package japicmp.output.markdown;
+
+import static java.util.Collections.singletonList;
+import static java.util.stream.Collectors.toList;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+final class MarkdownSection extends Markdown {
+
+ private final String title;
+ private final List list;
+ private final Comparator super T> comparator;
+ private final List> columns = new ArrayList<>();
+
+ MarkdownSection(String title, List list, Comparator super T> comparator) {
+ this.title = title;
+ this.list = list;
+ this.comparator = comparator;
+ }
+
+ MarkdownSection(String title, T one) {
+ this(title, singletonList(one), null);
+ }
+
+ MarkdownSection column(String header, Function mapper) {
+ this.columns.add(new Column<>(header, mapper));
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ if (list.isEmpty()) {
+ return EMPTY;
+ }
+ final Stream stream = comparator == null ? list.stream() : list.stream().sorted(comparator);
+ final MarkdownTable table = new MarkdownTable(columns.stream().map(column -> column.header).collect(toList()));
+ stream.forEach(x -> table.addRow(columns.stream().map(column -> column.mapper.apply(x)).collect(toList())));
+ return title + table;
+ }
+
+ private static final class Column {
+ final String header;
+ final Function mapper;
+
+ Column(String header, Function mapper) {
+ this.header = header;
+ this.mapper = mapper;
+ }
+ }
+}
diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownStoredReference.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownStoredReference.java
new file mode 100644
index 000000000..da41bb672
--- /dev/null
+++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownStoredReference.java
@@ -0,0 +1,41 @@
+package japicmp.output.markdown;
+
+final class MarkdownStoredReference extends MarkdownReference {
+ final int index;
+ final String id;
+
+ MarkdownStoredReference(int index, String id, MarkdownReference reference) {
+ super(reference.href, reference.title);
+ this.index = index;
+ this.id = id;
+ }
+
+ MarkdownStoredReference(String id, MarkdownReference reference) {
+ this(Integer.MAX_VALUE, id, reference);
+ }
+
+ MarkdownStoredReference(int index, MarkdownReference reference) {
+ this(index, String.valueOf(index), reference);
+ }
+
+ int getIndex() {
+ return index;
+ }
+
+ String getId() {
+ return id;
+ }
+
+ MarkdownRefImage toImage(String alt) {
+ return new MarkdownRefImage(alt, this);
+ }
+
+ MarkdownRefLink toLink(String text) {
+ return new MarkdownRefLink(text, this);
+ }
+
+ @Override
+ public String toString() {
+ return brackets(id) + COLON + SPACE + super.toString();
+ }
+}
diff --git a/japicmp/src/main/java/japicmp/output/markdown/MarkdownTable.java b/japicmp/src/main/java/japicmp/output/markdown/MarkdownTable.java
new file mode 100644
index 000000000..66af1154e
--- /dev/null
+++ b/japicmp/src/main/java/japicmp/output/markdown/MarkdownTable.java
@@ -0,0 +1,97 @@
+package japicmp.output.markdown;
+
+import static java.util.stream.Collectors.joining;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.*;
+
+final class MarkdownTable extends Markdown {
+
+ final int columns;
+ final List> rows = new ArrayList<>();
+
+ MarkdownTable(List headers) {
+ columns = headers.size();
+ rows.add(headers);
+ }
+
+ static String getColumnFormat(int width) {
+ return width < 1 ? "%s" : "%-" + width + "s";
+ }
+
+ void addRow(List row) {
+ rows.add(row);
+ }
+
+ @Override
+ public String toString() {
+ if (rows.size() == 1) {
+ return EMPTY;
+ }
+ final Map colWidths = calculateColumnWidths();
+ return IntStream.range(0, rows.size()).mapToObj(r -> {
+ final List row = rows.get(r);
+ final StringBuilder tmp = new StringBuilder();
+ tmp.append(new Row(row, colWidths));
+ if (r == 0) {
+ tmp.append(PIPE);
+ IntStream.range(0, columns).forEach(index -> tmp
+ .append(DASH)
+ .append(String.format(getColumnFormat(colWidths.get(index)), EMPTY).replace(SPACE, DASH))
+ .append(DASH)
+ .append(PIPE));
+ tmp.append(EOL);
+ }
+ return tmp.toString();
+ }).collect(joining()) + EOL;
+ }
+
+ private Map calculateColumnWidths() {
+ return IntStream.range(0, columns).mapToObj(Integer.class::cast)
+ .collect(Collectors.toMap(Function.identity(), this::calculateMaxWidth));
+ }
+
+ private int calculateMaxWidth(int index) {
+ if (index + 1 < columns) {
+ // Columns adjust dynamically up to a fixed limit
+ return rows.stream().map(x -> x.get(index)).mapToInt(String::length).filter(x -> x <= 64).max().orElse(0);
+ }
+ // Last column adjusts to heading size
+ return rows.get(0).get(index).length();
+ }
+
+ private class Row {
+
+ final List data;
+ final Map widths;
+ int offset = 0;
+
+ Row(List data, Map widths) {
+ this.data = data;
+ this.widths = widths;
+ }
+
+ String formatColumn(int index) {
+ final int width = widths.get(index);
+ final int maxWidth = Math.max(0, width - offset);
+ final String formatted = String.format(getColumnFormat(maxWidth), data.get(index));
+ final int length = formatted.length();
+ if (length <= width) {
+ offset -= width - length;
+ } else if (length > maxWidth) {
+ offset += length - maxWidth;
+ }
+ offset = Math.max(0, offset);
+ return formatted;
+ }
+
+ @Override
+ public String toString() {
+ return PIPE + IntStream.range(0, columns)
+ .mapToObj(index -> SPACE + formatColumn(index) + SPACE + PIPE)
+ .collect(joining()) +
+ EOL;
+ }
+ }
+}
diff --git a/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownHeaderOptions.java b/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownHeaderOptions.java
new file mode 100644
index 000000000..487ed83da
--- /dev/null
+++ b/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownHeaderOptions.java
@@ -0,0 +1,26 @@
+package japicmp.output.markdown.config;
+
+public class MarkdownHeaderOptions {
+
+ public String annotationName = "Annotation";
+ public String annotations = "Annotations";
+ public String className = "Name";
+ public String classType = "Type";
+ public String compatibilityChanges = "Compatibility Changes";
+ public String constructorNameAndParameters = "Constructor";
+ public String exceptions = "Throws";
+ public String fieldName = "Name";
+ public String fieldType = "Type";
+ public String genericTemplateName = "Name";
+ public String genericTemplateType = "Extends";
+ public String generics = "Generics";
+ public String interfaceName = "Interface";
+ public String classJdk = "JDK";
+ public String methodNameAndParameters = "Method";
+ public String methodReturnType = "Type";
+ public String modifiers = "Modifiers";
+ public String serialization = "Serialization";
+ public String status = "Status";
+ public String superclass = "Extends";
+ public String type = "Type";
+}
diff --git a/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownMessageOptions.java b/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownMessageOptions.java
new file mode 100644
index 000000000..3acb77331
--- /dev/null
+++ b/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownMessageOptions.java
@@ -0,0 +1,187 @@
+package japicmp.output.markdown.config;
+
+import static japicmp.output.markdown.Markdown.*;
+import static japicmp.output.semver.SemverOut.*;
+import static java.util.Arrays.stream;
+import static java.util.function.Function.identity;
+import static java.util.stream.Collectors.toMap;
+
+import japicmp.model.*;
+import japicmp.model.JApiJavaObjectSerializationCompatibility.JApiJavaObjectSerializationChangeStatus;
+import japicmp.output.markdown.MarkdownBadge;
+import japicmp.util.Optional;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Map;
+
+public class MarkdownMessageOptions {
+
+ public String summaryMajorChanges = "> [!CAUTION]\n>\n> Incompatible changes found while checking backward compatibility of %s with %s.";
+ public String summaryMinorChanges = "> [!WARNING]\n>\n> Compatible changes found while checking backward compatibility of %s with %s.";
+ public String summaryPatchChanges = "> [!IMPORTANT]\n>\n> Compatible bug fixes found while checking backward compatibility of %s with %s.";
+ public String summaryNoChanges = "> [!NOTE]\n>\n> No incompatible changes found while checking backward compatibility of %s with %s.";
+
+ public String oneNewVersion = "version `%s`";
+ public String oneOldVersion = "the previous version `%s`";
+ public String manyNewArchives = "several archives";
+ public String manyOldArchives = "their previous versions";
+ public String unknownVersion = "unknown";
+ public String expandResults = "Expand for details.";
+ public String expandOptions = "Expand to see options used.";
+
+ public String warningAllMissingClassesIgnored = "> [!WARNING]\n>\n> All missing classes, i.e. superclasses and interfaces that could not be found on the classpath were ignored.\n>\n> Hence changes caused by these superclasses and interfaces are not reflected in the output.\n\n";
+ public String warningSomeMissingClassesIgnored = "> [!WARNING]\n>\n> Certain classes, i.e. superclasses and interfaces that could not be found on the classpath were ignored.\n>\n> Hence changes caused by these superclasses and interfaces are not reflected in the output.\n\n";
+
+ public String generatedOn = "*Generated on: %s*.";
+ public String dateTimeFormat = "yyyy-MM-dd HH:mm:ss.SSSZ";
+
+ public String classpathMode = "**Classpath mode**: `%s`";
+ public String oldArchives = "**Old archives**:%s";
+ public String newArchives = "**New archives**:%s";
+ public String oldClasspath = "**Old classpath**:\n```\n%s\n```";
+ public String newClasspath = "**New classpath**:\n```\n%s\n```";
+ public String accessModifierFilter = "**Access modifier filter**: `%s`";
+ public String evaluateAnnotations = "**Evaluate annotations**: %s";
+ public String reportOnlySummary = "**Report only summary**: %s";
+ public String reportOnlyChanges = "**Report only changes**: %s";
+ public String reportOnlyBinaryIncompatibleChanges = "**Report only binary-incompatible changes**: %s";
+ public String includeSpecificElements = "**Include specific elements**: %s";
+ public String includeSynthetic = "**Include synthetic classes and class members**: %s";
+ public String excludeSpecificElements = "**Exclude specific elements**: %s";
+ public String ignoreAllMissingClasses = "**Ignore all missing classes**: %s";
+ public String ignoreSpecificMissingClasses = "**Ignore specific missing classes**: %s";
+ public String treatChangesAsErrors = "**Treat changes as errors**:%s";
+
+ public String anyChanges = "Any changes: %s";
+ public String binaryIncompatibleChanges = "Binary incompatible changes: %s";
+ public String sourceIncompatibleChanges = "Source incompatible changes: %s";
+ public String incompatibleChangesCausedByExcludedClasses = "Incompatible changes caused by excluded classes: %s";
+ public String semanticallyIncompatibleChanges = "Semantically incompatible changes: %s";
+ public String semanticallyIncompatibleChangesIncludingDevelopmentVersions = "Semantically incompatible changes, including development versions: %s";
+
+ public String added = "**%s**";
+ public String removed = "~~%s~~";
+ public String modified = "~~%s~~ → **%s**";
+ public String unchanged = "%s";
+
+ public String yes = "Yes";
+ public String no = "No";
+
+ public String checked = "[X]";
+ public String unchecked = "[ ]";
+
+ public String compatibilityBinary = "%s Binary-compatible";
+ public String compatibilitySource = "%s Source-compatible";
+ public String compatibilitySerialization = "%s Serialization-compatible";
+
+ public String noCompatibilityChanges = "No changes";
+
+ public String colorMajorChanges = "red";
+ public String colorMinorChanges = "orange";
+ public String colorPatchChanges = "yellow";
+ public String colorNoChanges = "green";
+ public String colorVersionNumber = "blue";
+
+ public String badgeMajorChanges = new MarkdownBadge("semver", "MAJOR", colorMajorChanges, "semver").toString();
+ public String badgeMinorChanges = new MarkdownBadge("semver", "MINOR", colorMinorChanges, "semver").toString();
+ public String badgePatchChanges = new MarkdownBadge("semver", "PATCH", colorPatchChanges, "semver").toString();
+ public String badgeNoChanges = new MarkdownBadge("semver", "OK", colorNoChanges, "semver").toString();
+
+ public String typeAnnotation = "Annotation";
+ public String typeInterface = "Interface";
+ public String typeClass = "Class";
+ public String typeEnum = "Enum";
+
+ public String statusNew = "Added";
+ public String statusRemoved = "Removed";
+ public String statusModified = "Modified";
+ public String statusUnchanged = "Unchanged";
+ public String statusIncompatible = "Incompatible";
+ public String statusSourceIncompatible = "Source-incompatible";
+ public String statusBinaryIncompatible = "Binary-incompatible";
+ public String statusSerializationIncompatible = "Serialization-incompatible";
+
+ public Map serializationCompatibility =
+ stream(JApiJavaObjectSerializationChangeStatus.values()).collect(toMap(identity(), e -> capitalize(e.getDescription())));
+
+ public Map compatibilityChangeType =
+ stream(JApiCompatibilityChangeType.values()).collect(toMap(identity(), e -> capitalize(e.name())));
+
+ private static String capitalize(String text) {
+ return text.substring(0, 1).toUpperCase() + text.substring(1).toLowerCase().replace(UNDERSCORE, SPACE);
+ }
+
+ public String getSemanticColor(JApiSemanticVersionLevel level) {
+ switch (level) {
+ default:
+ case MAJOR:
+ return colorMajorChanges;
+ case MINOR:
+ return colorMinorChanges;
+ case PATCH:
+ return colorPatchChanges;
+ }
+ }
+
+ public String getSemverBadge(String semver) {
+ switch (semver) {
+ case SEMVER_MAJOR:
+ return badgeMajorChanges;
+ case SEMVER_MINOR:
+ return badgeMinorChanges;
+ case SEMVER_PATCH:
+ return badgePatchChanges;
+ case SEMVER_COMPATIBLE:
+ default:
+ return badgeNoChanges;
+ }
+ }
+
+ public String getSummaryMessage(String semver) {
+ switch (semver) {
+ case SEMVER_MAJOR:
+ return summaryMajorChanges;
+ case SEMVER_MINOR:
+ return summaryMinorChanges;
+ case SEMVER_PATCH:
+ return summaryPatchChanges;
+ case SEMVER_COMPATIBLE:
+ default:
+ return summaryNoChanges;
+ }
+ }
+
+ public String getClassType(Optional classType) {
+ if (!classType.isPresent()) {
+ return EMPTY;
+ }
+ switch (classType.get()) {
+ case ANNOTATION:
+ return typeAnnotation;
+ case INTERFACE:
+ return typeInterface;
+ default:
+ case CLASS:
+ return typeClass;
+ case ENUM:
+ return typeEnum;
+ }
+ }
+
+ public String getCurrentTimestamp() {
+ final ZonedDateTime now = ZonedDateTime.now();
+ try {
+ return DateTimeFormatter.ofPattern(dateTimeFormat).format(now);
+ } catch (Exception e) {
+ return now.toString();
+ }
+ }
+
+ public String yesNo(boolean value) {
+ return value ? yes : no;
+ }
+
+ public String checkbox(boolean value) {
+ return value ? checked : unchecked;
+ }
+}
diff --git a/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownOptions.java b/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownOptions.java
new file mode 100644
index 000000000..2898620ee
--- /dev/null
+++ b/japicmp/src/main/java/japicmp/output/markdown/config/MarkdownOptions.java
@@ -0,0 +1,37 @@
+package japicmp.output.markdown.config;
+
+import japicmp.config.Options;
+import japicmp.util.Optional;
+
+public class MarkdownOptions {
+
+ public Options options;
+
+ public Optional targetOldVersion = Optional.absent();
+ public Optional