Update to Mockito 2.25.0 and impl InlineMockMaker.

In certain specific, rare cases inline mocking causes memory leaks.
Mockito introduced a new API to explicitly clear mock state in version
2.25.0. To make that work we need to implement the new InlineMockMaker
interface, hence I make this pull request.

This fixes #137.

Bug: 138669713
Test: Builds.
Change-Id: Idd609892cd219a4b668a7464bc69142bc2b8f2d0
diff --git a/README.md b/README.md
index a2e0b8a..bbb58ba 100644
--- a/README.md
+++ b/README.md
@@ -107,19 +107,18 @@
 Use it in your app
 ------------------
 
-Maven users can get dexmaker from Sonatype's central repository. The Mockito dependency is optional.
+For Mockito support, download the latest .jar via Maven:
+```xml
+    <dependency>
+      <groupId>com.linkedin.dexmaker</groupId>
+      <artifactId>dexmaker-mockito</artifactId>
+      <version>2.25.0</version>
+      <type>pom</type>
+    </dependency>
+```
 
 ```
-  <dependency>
-    <groupId>com.google.dexmaker</groupId>
-    <artifactId>dexmaker</artifactId>
-    <version>1.2</version>
-  </dependency>
-  <dependency>
-    <groupId>com.google.dexmaker</groupId>
-    <artifactId>dexmaker-mockito</artifactId>
-    <version>1.2</version>
-  </dependency>
+    androidTestCompile 'com.linkedin.dexmaker:dexmaker-mockito:2.25.0'
 ```
 
 Download [dexmaker-1.2.jar](http://search.maven.org/remotecontent?filepath=com/google/dexmaker/dexmaker/1.2/dexmaker-1.2.jar)
diff --git a/README.version b/README.version
index ee1122d..d51834c 100644
--- a/README.version
+++ b/README.version
@@ -15,3 +15,4 @@
         Temporarily ignore failing test (Ibf7b6c2eb05c5ff83f0817f9224369e20c0b775d)
         Restrict InspectClass to current thread. (Ic62951ff81bed60ac7512455fad65210e4b728a9, need upstreaming)
         Exclude Stress#mockALot from presubmit (Ic9a2927ffa07924bd759429e31c56dc1b71a826c)
+        Update to Mockito 2.25.0 and impl InlineMockMaker (29a8674036d345e4ec8635b1d38d8b2a4fe91980a, need upstreaming)
diff --git a/dexmaker-mockito-inline-extended-tests/build.gradle b/dexmaker-mockito-inline-extended-tests/build.gradle
index fcff13c..b5664f2 100644
--- a/dexmaker-mockito-inline-extended-tests/build.gradle
+++ b/dexmaker-mockito-inline-extended-tests/build.gradle
@@ -50,5 +50,5 @@
     implementation 'com.android.support.test:runner:1.0.2'
     implementation 'com.android.support.test:rules:1.0.2'
 
-    api 'org.mockito:mockito-core:2.21.0', { exclude group: 'net.bytebuddy' }
+    api 'org.mockito:mockito-core:2.25.0', { exclude group: 'net.bytebuddy' }
 }
diff --git a/dexmaker-mockito-inline-extended/build.gradle b/dexmaker-mockito-inline-extended/build.gradle
index 3234e33..fee152e 100644
--- a/dexmaker-mockito-inline-extended/build.gradle
+++ b/dexmaker-mockito-inline-extended/build.gradle
@@ -119,5 +119,5 @@
 dependencies {
     implementation project(':dexmaker-mockito-inline')
 
-    implementation 'org.mockito:mockito-core:2.21.0', { exclude group: 'net.bytebuddy' }
+    implementation 'org.mockito:mockito-core:2.25.0', { exclude group: 'net.bytebuddy' }
 }
diff --git a/dexmaker-mockito-inline-tests/build.gradle b/dexmaker-mockito-inline-tests/build.gradle
index c731115..02d0751 100644
--- a/dexmaker-mockito-inline-tests/build.gradle
+++ b/dexmaker-mockito-inline-tests/build.gradle
@@ -50,5 +50,5 @@
 
     implementation 'junit:junit:4.12'
     implementation 'com.android.support.test:runner:1.0.2'
-    api 'org.mockito:mockito-core:2.21.0', { exclude group: 'net.bytebuddy' }
+    api 'org.mockito:mockito-core:2.25.0', { exclude group: 'net.bytebuddy' }
 }
diff --git a/dexmaker-mockito-inline-tests/src/main/java/com/android/dx/mockito/inline/tests/MemoryLeaks.java b/dexmaker-mockito-inline-tests/src/main/java/com/android/dx/mockito/inline/tests/MemoryLeaks.java
new file mode 100644
index 0000000..d78bb10
--- /dev/null
+++ b/dexmaker-mockito-inline-tests/src/main/java/com/android/dx/mockito/inline/tests/MemoryLeaks.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.dx.mockito.inline.tests;
+
+import static org.mockito.Mockito.framework;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class MemoryLeaks {
+    private static final int ARRAY_LENGTH = 1 << 20;  // 4 MB
+
+    @Test
+    public void callMethodWithMocksCycalically() {
+        for (int i = 0; i < 100; ++i) {
+            final A a = mock(A.class);
+            a.largeArray = new int[ARRAY_LENGTH];
+            final B b = mock(B.class);
+
+            a.accept(b);
+            b.accept(a);
+
+            framework().clearInlineMocks();
+        }
+    }
+
+    @Test
+    public void spyRefersToItself() {
+        for (int i = 0; i < 100; ++i) {
+            final DeepRefSelfClass instance = spy(new DeepRefSelfClass());
+            instance.refInstance(instance);
+
+            framework().clearInlineMocks();
+        }
+    }
+
+    private static class A {
+        private int[] largeArray;
+
+        void accept(B b) {}
+    }
+
+    private static class B {
+        void accept(A a) {}
+    }
+
+    private static class DeepRefSelfClass {
+        private final DeepRefSelfClass[] array = new DeepRefSelfClass[1];
+
+        private final int[] largeArray = new int[ARRAY_LENGTH];
+
+        private void refInstance(DeepRefSelfClass instance) {
+            array[0] = instance;
+        }
+    }
+}
diff --git a/dexmaker-mockito-inline/build.gradle b/dexmaker-mockito-inline/build.gradle
index 8ca3d3c..00913a4 100644
--- a/dexmaker-mockito-inline/build.gradle
+++ b/dexmaker-mockito-inline/build.gradle
@@ -113,6 +113,6 @@
 dependencies {
     implementation project(':dexmaker')
 
-    implementation 'org.mockito:mockito-core:2.21.0', { exclude group: 'net.bytebuddy' }
+    implementation 'org.mockito:mockito-core:2.25.0', { exclude group: 'net.bytebuddy' }
 }
 
diff --git a/dexmaker-mockito-inline/src/main/java/com/android/dx/mockito/inline/InlineDexmakerMockMaker.java b/dexmaker-mockito-inline/src/main/java/com/android/dx/mockito/inline/InlineDexmakerMockMaker.java
index fc2a641..0a594e0 100644
--- a/dexmaker-mockito-inline/src/main/java/com/android/dx/mockito/inline/InlineDexmakerMockMaker.java
+++ b/dexmaker-mockito-inline/src/main/java/com/android/dx/mockito/inline/InlineDexmakerMockMaker.java
@@ -29,6 +29,7 @@
 import org.mockito.internal.util.reflection.LenientCopyTool;
 import org.mockito.invocation.MockHandler;
 import org.mockito.mock.MockCreationSettings;
+import org.mockito.plugins.InlineMockMaker;
 import org.mockito.plugins.InstantiatorProvider2;
 import org.mockito.plugins.MockMaker;
 
@@ -54,7 +55,7 @@
  * <p>This is done by transforming the byte code of the classes to add method entry hooks.
  */
 
-public final class InlineDexmakerMockMaker implements MockMaker {
+public final class InlineDexmakerMockMaker implements InlineMockMaker {
     private static final String DISPATCHER_CLASS_NAME =
             "com.android.dx.mockito.inline.MockMethodDispatcher";
     private static final String DISPATCHER_JAR = "dispatcher.jar";
@@ -346,6 +347,16 @@
     }
 
     @Override
+    public void clearMock(Object mock) {
+        mocks.remove(mock);
+    }
+
+    @Override
+    public void clearAllMocks() {
+        mocks.clear();
+    }
+
+    @Override
     public MockHandler getHandler(Object mock) {
         InvocationHandlerAdapter adapter = getInvocationHandlerAdapter(mock);
         return adapter != null ? adapter.getHandler() : null;
diff --git a/dexmaker-mockito-inline/src/main/java/com/android/dx/mockito/inline/MockMakerMultiplexer.java b/dexmaker-mockito-inline/src/main/java/com/android/dx/mockito/inline/MockMakerMultiplexer.java
index c5f8db6..8949d46 100644
--- a/dexmaker-mockito-inline/src/main/java/com/android/dx/mockito/inline/MockMakerMultiplexer.java
+++ b/dexmaker-mockito-inline/src/main/java/com/android/dx/mockito/inline/MockMakerMultiplexer.java
@@ -20,6 +20,7 @@
 
 import org.mockito.invocation.MockHandler;
 import org.mockito.mock.MockCreationSettings;
+import org.mockito.plugins.InlineMockMaker;
 import org.mockito.plugins.MockMaker;
 
 import java.lang.reflect.InvocationTargetException;
@@ -28,7 +29,7 @@
 /**
  * Multiplexes multiple mock makers
  */
-public final class MockMakerMultiplexer implements MockMaker {
+public final class MockMakerMultiplexer implements InlineMockMaker {
     private static final String LOG_TAG = MockMakerMultiplexer.class.getSimpleName();
     private final static MockMaker[] MOCK_MAKERS;
 
@@ -103,4 +104,28 @@
 
         return null;
     }
+
+    @Override
+    public void clearMock(Object mock) {
+        for (MockMaker mockMaker : MOCK_MAKERS) {
+            if (!(mockMaker instanceof InlineMockMaker)) {
+                continue;
+            }
+
+            InlineMockMaker inlineMockMaker = (InlineMockMaker) mockMaker;
+            inlineMockMaker.clearMock(mock);
+        }
+    }
+
+    @Override
+    public void clearAllMocks() {
+        for (MockMaker mockMaker : MOCK_MAKERS) {
+            if (!(mockMaker instanceof InlineMockMaker)) {
+                continue;
+            }
+
+            InlineMockMaker inlineMockMaker = (InlineMockMaker) mockMaker;
+            inlineMockMaker.clearAllMocks();
+        }
+    }
 }
diff --git a/dexmaker-mockito-tests/build.gradle b/dexmaker-mockito-tests/build.gradle
index f051535..9379d17 100644
--- a/dexmaker-mockito-tests/build.gradle
+++ b/dexmaker-mockito-tests/build.gradle
@@ -42,5 +42,5 @@
 
     implementation 'com.android.support.test:runner:0.5'
     implementation 'junit:junit:4.12'
-    api 'org.mockito:mockito-core:2.21.0', { exclude group: 'net.bytebuddy' }
+    api 'org.mockito:mockito-core:2.25.0', { exclude group: 'net.bytebuddy' }
 }
diff --git a/dexmaker-mockito/build.gradle b/dexmaker-mockito/build.gradle
index 46cdd8f..b15b30c 100644
--- a/dexmaker-mockito/build.gradle
+++ b/dexmaker-mockito/build.gradle
@@ -26,5 +26,5 @@
 dependencies {
     implementation project(':dexmaker')
 
-    implementation 'org.mockito:mockito-core:2.21.0', { exclude group: 'net.bytebuddy' }
+    implementation 'org.mockito:mockito-core:2.25.0', { exclude group: 'net.bytebuddy' }
 }