// Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

package com.android.tools.r8.smali;

import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.code.Const4;
import com.android.tools.r8.code.ConstString;
import com.android.tools.r8.code.ConstWide;
import com.android.tools.r8.code.ConstWideHigh16;
import com.android.tools.r8.code.DivInt;
import com.android.tools.r8.code.DivInt2Addr;
import com.android.tools.r8.code.Goto;
import com.android.tools.r8.code.Instruction;
import com.android.tools.r8.code.InvokeStatic;
import com.android.tools.r8.code.InvokeStaticRange;
import com.android.tools.r8.code.InvokeVirtual;
import com.android.tools.r8.code.MoveResult;
import com.android.tools.r8.code.MoveResultWide;
import com.android.tools.r8.code.Return;
import com.android.tools.r8.code.ReturnObject;
import com.android.tools.r8.code.ReturnVoid;
import com.android.tools.r8.code.ReturnWide;
import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.smali.SmaliBuilder.MethodSignature;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.InternalOptions.OutlineOptions;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.function.Consumer;
import org.junit.Assert;
import org.junit.Test;

public class OutlineTest extends SmaliTestBase {

  private static final String stringBuilderAppendSignature =
      "Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;";
  private static final String stringBuilderAppendDoubleSignature =
      "Ljava/lang/StringBuilder;->append(D)Ljava/lang/StringBuilder;";
  private static final String stringBuilderAppendIntSignature =
      "Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;";
  private static final String stringBuilderAppendLongSignature =
      "Ljava/lang/StringBuilder;->append(J)Ljava/lang/StringBuilder;";
  private static final String stringBuilderToStringSignature =
      "Ljava/lang/StringBuilder;->toString()Ljava/lang/String;";

  private Consumer<InternalOptions> configureOptions(Consumer<InternalOptions> optionsConsumer) {
    return options -> {
      // Disable inlining to make sure that code looks as expected.
      options.enableInlining = false;
      // Also apply outline options.
      optionsConsumer.accept(options);
    };
  }

  private Consumer<InternalOptions> configureOutlineOptions(
      Consumer<OutlineOptions> optionsConsumer) {
    return options -> {
      // Disable inlining to make sure that code looks as expected.
      options.enableInlining = false;
      // Also apply outline options.
      optionsConsumer.accept(options.outline);
    };
  }

  private String firstOutlineMethodName() {
    return OutlineOptions.CLASS_NAME + '.' + OutlineOptions.METHOD_PREFIX + "0";
  }

  private boolean isOutlineMethodName(String qualifiedName) {
    String qualifiedPrefix = OutlineOptions.CLASS_NAME + '.' + OutlineOptions.METHOD_PREFIX;
    return qualifiedName.indexOf(qualifiedPrefix) == 0;
  }

  @Test
  public void a() throws Exception {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    String returnType = "java.lang.String";
    List<String> parameters = Collections.singletonList("java.lang.StringBuilder");
    MethodSignature signature =
        builder.addStaticMethod(
            returnType,
            DEFAULT_METHOD_NAME,
            parameters,
            2,
            "    move-object         v0, p0",
            "    const-string        v1, \"Test\"",
            "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
            "    move-result-object  v0",
            "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
            "    move-result-object  v0",
            "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
            "    move-result-object  v0",
            "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
            "    move-result-object  v0",
            "    invoke-virtual      { v0 }, " + stringBuilderToStringSignature,
            "    move-result-object  v0",
            "    return-object       v0");

    builder.addMainMethod(
        2,
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    new-instance        v1, Ljava/lang/StringBuilder;",
        "    invoke-direct       { v1 }, Ljava/lang/StringBuilder;-><init>()V",
        "    invoke-static       { v1 },"
            + " LTest;->method(Ljava/lang/StringBuilder;)Ljava/lang/String;",
        "    move-result-object  v1",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(Ljava/lang/String;)V",
        "    return-void");

    for (int i = 2; i < 6; i++) {
      final int j = i;
      Consumer<InternalOptions> options =
          configureOutlineOptions(
              outline -> {
                outline.threshold = 1;
                outline.minSize = j;
                outline.maxSize = j;
              });

      AndroidApp originalApplication = buildApplication(builder);
      AndroidApp processedApplication = processApplication(originalApplication, options);
      assertEquals(2, getNumberOfProgramClasses(processedApplication));

      // Return the processed method for inspection.
      DexEncodedMethod method = getMethod(processedApplication, signature);

      DexCode code = method.getCode().asDexCode();
      assertTrue(code.instructions[0] instanceof ConstString);
      assertTrue(code.instructions[1] instanceof InvokeStatic);
      InvokeStatic invoke = (InvokeStatic) code.instructions[1];
      assertTrue(isOutlineMethodName(invoke.getMethod().qualifiedName()));

      // Run code and check result.
      String result = runArt(processedApplication);
      assertEquals("TestTestTestTest", result);
    }
  }

  @Test
  public void b() throws Exception {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    String returnType = "java.lang.String";
    List<String> parameters = Collections.singletonList("java.lang.StringBuilder");
    MethodSignature signature =
        builder.addStaticMethod(
            returnType,
            DEFAULT_METHOD_NAME,
            parameters,
            2,
            "    move-object         v0, p0",
            "    const-string        v1, \"Test1\"",
            "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
            "    move-result-object  v0",
            "    const-string        v1, \"Test2\"",
            "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
            "    move-result-object  v0",
            "    const-string        v1, \"Test3\"",
            "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
            "    move-result-object  v0",
            "    const-string        v1, \"Test4\"",
            "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
            "    move-result-object  v0",
            "    invoke-virtual      { v0 }, " + stringBuilderToStringSignature,
            "    move-result-object  v0",
            "    return-object       v0");

    builder.addMainMethod(
        2,
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    new-instance        v1, Ljava/lang/StringBuilder;",
        "    invoke-direct       { v1 }, Ljava/lang/StringBuilder;-><init>()V",
        "    invoke-static       { v1 },"
            + " LTest;->method(Ljava/lang/StringBuilder;)Ljava/lang/String;",
        "    move-result-object  v1",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(Ljava/lang/String;)V",
        "    return-void");

    for (int i = 2; i < 6; i++) {
      final int finalI = i;
      Consumer<InternalOptions> options =
          configureOutlineOptions(
              outline -> {
                outline.threshold = 1;
                outline.minSize = finalI;
                outline.maxSize = finalI;
              });

      AndroidApp originalApplication = buildApplication(builder);
      AndroidApp processedApplication = processApplication(originalApplication, options);
      assertEquals(2, getNumberOfProgramClasses(processedApplication));

      // Return the processed method for inspection.
      DexEncodedMethod method = getMethod(processedApplication, signature);

      DexCode code = method.getCode().asDexCode();

      // Up to 4 const instructions before the invoke of the outline.
      int firstOutlineInvoke = Math.min(i, 4);
      for (int j = 0; j < firstOutlineInvoke; j++) {
        assertTrue(code.instructions[j] instanceof ConstString);
      }
      assertTrue(code.instructions[firstOutlineInvoke] instanceof InvokeStatic);
      InvokeStatic invoke = (InvokeStatic) code.instructions[firstOutlineInvoke];
      assertTrue(isOutlineMethodName(invoke.getMethod().qualifiedName()));

      // Run code and check result.
      String result = runArt(processedApplication);
      assertEquals("Test1Test2Test3Test4", result);
    }
  }

  @Test
  public void c() throws Exception {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    // Method with const instructions after the outline.
    String returnType = "int";
    List<String> parameters = Collections.singletonList("java.lang.StringBuilder");
    MethodSignature signature =
        builder.addStaticMethod(
            returnType,
            DEFAULT_METHOD_NAME,
            parameters,
            2,
            "    move-object         v0, p0",
            "    const-string        v1, \"Test\"",
            "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
            "    move-result-object  v0",
            "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
            "    move-result-object  v0",
            "    invoke-virtual      { v0 }, " + stringBuilderToStringSignature,
            "    move-result-object  v0",
            "    const               v0, 0",
            "    const               v1, 1",
            "    add-int             v1, v1, v0",
            "    return              v1");

    builder.addMainMethod(
        2,
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    new-instance        v1, Ljava/lang/StringBuilder;",
        "    invoke-direct       { v1 }, Ljava/lang/StringBuilder;-><init>()V",
        "    invoke-static       { v1 }, LTest;->method(Ljava/lang/StringBuilder;)I",
        "    move-result         v1",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(I)V",
        "    return-void"
    );

    Consumer<InternalOptions> options = configureOutlineOptions(outline -> outline.threshold = 1);
    AndroidApp originalApplication = buildApplication(builder);
    AndroidApp processedApplication = processApplication(originalApplication, options);
    assertEquals(2, getNumberOfProgramClasses(processedApplication));

    // Return the processed method for inspection.
    DexEncodedMethod method = getMethod(processedApplication, signature);

    DexCode code = method.getCode().asDexCode();
    assertTrue(code.instructions[0] instanceof ConstString);
    assertTrue(code.instructions[1] instanceof InvokeStatic);
    InvokeStatic invoke = (InvokeStatic) code.instructions[1];
    assertTrue(isOutlineMethodName(invoke.getMethod().qualifiedName()));

    // Run code and check result.
    String result = runArt(processedApplication);
    assertEquals("1", result);
  }

  @Test
  public void d() throws Exception {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    // Method with mixed use of arguments and locals.
    String returnType = "java.lang.String";
    List<String> parameters = ImmutableList.of(
        "java.lang.StringBuilder", "java.lang.String", "java.lang.String");
    MethodSignature signature =
        builder.addStaticMethod(
            returnType,
            DEFAULT_METHOD_NAME,
            parameters,
            2,
            "    invoke-virtual      { p0, p1 }, " + stringBuilderAppendSignature,
            "    move-result-object  p0",
            "    const-string        v0, \"Test1\"",
            "    invoke-virtual      { p0, v0 }, " + stringBuilderAppendSignature,
            "    move-result-object  p0",
            "    invoke-virtual      { p0, p2 }, " + stringBuilderAppendSignature,
            "    move-result-object  p0",
            "    const-string        v1, \"Test2\"",
            "    invoke-virtual      { p0, v1 }, " + stringBuilderAppendSignature,
            "    move-result-object  p0",
            "    const-string        v1, \"Test3\"",
            "    invoke-virtual      { p0, v1 }, " + stringBuilderAppendSignature,
            "    move-result-object  p0",
            "    invoke-virtual      { p0 }, " + stringBuilderToStringSignature,
            "    move-result-object  v1",
            "    return-object  v1");

    builder.addMainMethod(
        4,
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    new-instance        v1, Ljava/lang/StringBuilder;",
        "    invoke-direct       { v1 }, Ljava/lang/StringBuilder;-><init>()V",
        "    const-string        v2, \"TestX\"",
        "    const-string        v3, \"TestY\"",
        "    invoke-static       { v1, v2, v3 },"
            + " LTest;->method(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
        "    move-result-object  v1",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(Ljava/lang/String;)V",
        "    return-void");

    Consumer<InternalOptions> options = configureOutlineOptions(outline -> outline.threshold = 1);
    AndroidApp originalApplication = buildApplication(builder);
    AndroidApp processedApplication = processApplication(originalApplication, options);
    assertEquals(2, getNumberOfProgramClasses(processedApplication));

    // Return the processed method for inspection.
    DexEncodedMethod method = getMethod(processedApplication, signature);

    DexCode code = method.getCode().asDexCode();
    assertTrue(code.instructions[0] instanceof ConstString);
    assertTrue(code.instructions[1] instanceof ConstString);
    assertTrue(code.instructions[2] instanceof InvokeStatic);
    InvokeStatic invoke = (InvokeStatic) code.instructions[2];
    assertTrue(isOutlineMethodName(invoke.getMethod().qualifiedName()));

    // Run code and check result.
    String result = runArt(processedApplication);
    assertEquals("TestXTest1TestYTest2Test3", result);
  }

  @Test
  public void longArguments() throws Throwable {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    String returnType = "java.lang.String";
    List<String> parameters = Collections.singletonList("java.lang.StringBuilder");
    MethodSignature signature =
        builder.addStaticMethod(
            returnType,
            DEFAULT_METHOD_NAME,
            parameters,
            3,
            "    move-object         v0, p0",
            "    const-wide          v1, 0x7fffffff00000000L",
            "    invoke-virtual      { v0, v1, v2 }, " + stringBuilderAppendLongSignature,
            "    move-result-object  v0",
            "    invoke-virtual      { v0, v1, v2 }, " + stringBuilderAppendLongSignature,
            "    move-result-object  v0",
            "    invoke-virtual      { v0, v1, v2 }, " + stringBuilderAppendLongSignature,
            "    move-result-object  v0",
            "    invoke-virtual      { v0, v1, v2 }, " + stringBuilderAppendLongSignature,
            "    move-result-object  v0",
            "    invoke-virtual      { v0 }, " + stringBuilderToStringSignature,
            "    move-result-object  v0",
            "    return-object       v0");

    builder.addMainMethod(
        2,
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    new-instance        v1, Ljava/lang/StringBuilder;",
        "    invoke-direct       { v1 }, Ljava/lang/StringBuilder;-><init>()V",
        "    invoke-static       { v1 },"
            + " LTest;->method(Ljava/lang/StringBuilder;)Ljava/lang/String;",
        "    move-result-object  v1",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(Ljava/lang/String;)V",
        "    return-void");

    for (int i = 2; i < 4; i++) {
      final int finalI = i;
      Consumer<InternalOptions> options =
          configureOutlineOptions(
              outline -> {
                outline.threshold = 1;
                outline.minSize = finalI;
                outline.maxSize = finalI;
              });

      AndroidApp originalApplication = buildApplicationWithAndroidJar(builder);
      AndroidApp processedApplication = processApplication(originalApplication, options);
      assertEquals(2, getNumberOfProgramClasses(processedApplication));

      // Return the processed method for inspection.
      DexEncodedMethod method = getMethod(processedApplication, signature);

      DexCode code = method.getCode().asDexCode();
      assertTrue(code.instructions[0] instanceof ConstWide);
      if (i < 3) {
        assertTrue(code.instructions[1] instanceof InvokeStatic);
        InvokeStatic invoke = (InvokeStatic) code.instructions[1];
        assertTrue(isOutlineMethodName(invoke.getMethod().qualifiedName()));
      } else {
        assertTrue(code.instructions[1] instanceof InvokeVirtual);
        assertTrue(code.instructions[2] instanceof InvokeVirtual);
        assertTrue(code.instructions[3] instanceof InvokeStatic);
        InvokeStatic invoke = (InvokeStatic) code.instructions[3];
        assertTrue(isOutlineMethodName(invoke.getMethod().qualifiedName()));
      }

      // Run code and check result.
      String result = runArt(processedApplication);
      StringBuilder resultBuilder = new StringBuilder();
      for (int j = 0; j < 4; j++) {
        resultBuilder.append(0x7fffffff00000000L);
      }
      assertEquals(resultBuilder.toString(), result);
    }
  }

  @Test
  public void doubleArguments() throws Exception {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    String returnType = "java.lang.String";
    List<String> parameters = Collections.singletonList("java.lang.StringBuilder");
    MethodSignature signature =
        builder.addStaticMethod(
            returnType,
            DEFAULT_METHOD_NAME,
            parameters,
            3,
            "    move-object         v0, p0",
            "    const-wide          v1, 0x3ff0000000000000L",
            "    invoke-virtual      { v0, v1, v2 }, " + stringBuilderAppendDoubleSignature,
            "    move-result-object  v0",
            "    invoke-virtual      { v0, v1, v2 }, " + stringBuilderAppendDoubleSignature,
            "    move-result-object  v0",
            "    invoke-virtual      { v0, v1, v2 }, " + stringBuilderAppendDoubleSignature,
            "    move-result-object  v0",
            "    invoke-virtual      { v0, v1, v2 }, " + stringBuilderAppendDoubleSignature,
            "    move-result-object  v0",
            "    invoke-virtual      { v0 }, " + stringBuilderToStringSignature,
            "    move-result-object  v0",
            "    return-object       v0");

    builder.addMainMethod(
        2,
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    new-instance        v1, Ljava/lang/StringBuilder;",
        "    invoke-direct       { v1 }, Ljava/lang/StringBuilder;-><init>()V",
        "    invoke-static       { v1 },"
            + " LTest;->method(Ljava/lang/StringBuilder;)Ljava/lang/String;",
        "    move-result-object  v1",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(Ljava/lang/String;)V",
        "    return-void");

    for (int i = 2; i < 4; i++) {
      final int finalI = i;
      Consumer<InternalOptions> options =
          configureOutlineOptions(
              outline -> {
                outline.threshold = 1;
                outline.minSize = finalI;
                outline.maxSize = finalI;
              });

      AndroidApp originalApplication = buildApplicationWithAndroidJar(builder);
      AndroidApp processedApplication = processApplication(originalApplication, options);
      assertEquals(2, getNumberOfProgramClasses(processedApplication));

      // Return the processed method for inspection.
      DexEncodedMethod method = getMethod(processedApplication, signature);

      DexCode code = method.getCode().asDexCode();
      assertTrue(code.instructions[0] instanceof ConstWideHigh16);
      if (i < 3) {
        assertTrue(code.instructions[1] instanceof InvokeStatic);
        InvokeStatic invoke = (InvokeStatic) code.instructions[1];
        assertTrue(isOutlineMethodName(invoke.getMethod().qualifiedName()));
      } else {
        assertTrue(code.instructions[1] instanceof InvokeVirtual);
        assertTrue(code.instructions[2] instanceof InvokeVirtual);
        assertTrue(code.instructions[3] instanceof InvokeStatic);
        InvokeStatic invoke = (InvokeStatic) code.instructions[3];
        assertTrue(isOutlineMethodName(invoke.getMethod().qualifiedName()));
      }

      // Run code and check result.
      String result = runArt(processedApplication);
      StringBuilder resultBuilder = new StringBuilder();
      for (int j = 0; j < 4; j++) {
        resultBuilder.append(1.0d);
      }
      assertEquals(resultBuilder.toString(), result);
    }
  }

  @Test
  public void invokeStatic() throws Exception {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    String returnType = "void";
    List<String> parameters = ImmutableList.of("java.lang.StringBuilder", "int");
    builder.addStaticMethod(
        returnType,
        DEFAULT_METHOD_NAME,
        parameters,
        1,
        "    invoke-virtual      { p0, p1 }, " + stringBuilderAppendIntSignature,
        "    move-result-object  v0",
        "    invoke-virtual      { p0, p1 }, " + stringBuilderAppendIntSignature,
        "    move-result-object  v0",
        "    return-void");

    MethodSignature mainSignature =
        builder.addMainMethod(
            2,
            "    new-instance        v0, Ljava/lang/StringBuilder;",
            "    invoke-direct       { v0 }, Ljava/lang/StringBuilder;-><init>()V",
            "    const/4             v1, 0x1",
            "    invoke-static       { v0, v1 }, LTest;->method(Ljava/lang/StringBuilder;I)V",
            "    const/4             v1, 0x2",
            "    invoke-static       { v0, v1 }, LTest;->method(Ljava/lang/StringBuilder;I)V",
            "    invoke-virtual      { v0 }, " + stringBuilderToStringSignature,
            "    move-result-object  v1",
            "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
            "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(Ljava/lang/String;)V",
            "    return-void");

    for (int i = 2; i < 6; i++) {
      final int finalI = i;
      Consumer<InternalOptions> options =
          configureOutlineOptions(
              outline -> {
                outline.threshold = 1;
                outline.minSize = finalI;
                outline.maxSize = finalI;
              });

      AndroidApp originalApplication = buildApplicationWithAndroidJar(builder);
      AndroidApp processedApplication = processApplication(originalApplication, options);
      assertEquals(2, getNumberOfProgramClasses(processedApplication));

      // Return the processed main method for inspection.
      DexEncodedMethod mainMethod = getMethod(processedApplication, mainSignature);
      DexCode mainCode = mainMethod.getCode().asDexCode();

      if (i == 2 || i == 3) {
        assert mainCode.instructions.length == 10;
      } else if (i == 4) {
        assert mainCode.instructions.length == 9;
      } else {
        assert i == 5;
        assert mainCode.instructions.length == 7;
      }
      if (i == 2) {
        InvokeStatic invoke = (InvokeStatic) mainCode.instructions[4];
        assertTrue(isOutlineMethodName(invoke.getMethod().qualifiedName()));
      } else if (i == 3) {
        InvokeStatic invoke = (InvokeStatic) mainCode.instructions[1];
        assertTrue(isOutlineMethodName(invoke.getMethod().qualifiedName()));
      } else {
        assert i == 4 || i == 5;
        InvokeStatic invoke = (InvokeStatic) mainCode.instructions[2];
        assertTrue(isOutlineMethodName(invoke.getMethod().qualifiedName()));
      }

      // Run code and check result.
      String result = runArt(processedApplication);
      assertEquals("1122", result);
    }
  }

  @Test
  public void constructor() throws Exception {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    MethodSignature signature1 =
        builder.addStaticMethod(
            "java.lang.String",
            "method1",
            Collections.emptyList(),
            3,
            "    new-instance        v0, Ljava/lang/StringBuilder;",
            "    invoke-direct       { v0 }, Ljava/lang/StringBuilder;-><init>()V",
            "    const-string        v1, \"Test1\"",
            "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
            "    move-result-object  v0",
            "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
            "    move-result-object  v0",
            "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
            "    move-result-object  v0",
            "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
            "    move-result-object  v0",
            "    invoke-virtual      { v0 }, " + stringBuilderToStringSignature,
            "    move-result-object  v0",
            "    return-object       v0");

    MethodSignature signature2 =
        builder.addStaticMethod(
            "java.lang.String",
            "method2",
            Collections.emptyList(),
            3,
            "    const/4             v1, 7",
            "    new-instance        v0, Ljava/lang/StringBuilder;",
            "    invoke-direct       { v0, v1 }, Ljava/lang/StringBuilder;-><init>(I)V",
            "    const-string        v1, \"Test2\"",
            "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
            "    move-result-object  v0",
            "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
            "    move-result-object  v0",
            "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
            "    move-result-object  v0",
            "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
            "    move-result-object  v0",
            "    invoke-virtual      { v0 }, " + stringBuilderToStringSignature,
            "    move-result-object  v0",
            "    return-object       v0");

    builder.addMainMethod(
        2,
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    invoke-static       {}, LTest;->method1()Ljava/lang/String;",
        "    move-result-object  v1",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(Ljava/lang/String;)V",
        "    invoke-static       {}, LTest;->method2()Ljava/lang/String;",
        "    move-result-object  v1",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(Ljava/lang/String;)V",
        "    return-void");

    Consumer<InternalOptions> options =
        configureOutlineOptions(
            outline -> {
              outline.threshold = 1;
              outline.minSize = 7;
              outline.maxSize = 7;
            });

    AndroidApp originalApplication = buildApplicationWithAndroidJar(builder);
    AndroidApp processedApplication = processApplication(originalApplication, options);
    assertEquals(2, getNumberOfProgramClasses(processedApplication));

    DexCode code1 = getMethod(processedApplication, signature1).getCode().asDexCode();
    assertEquals(4, code1.instructions.length);
    assertTrue(code1.instructions[1] instanceof InvokeStatic);
    InvokeStatic invoke1 = (InvokeStatic) code1.instructions[1];
    assertTrue(isOutlineMethodName(invoke1.getMethod().qualifiedName()));

    DexCode code2 = getMethod(processedApplication, signature2).getCode().asDexCode();
    assertEquals(5, code2.instructions.length);
    assertTrue(code2.instructions[2] instanceof InvokeStatic);
    InvokeStatic invoke2 = (InvokeStatic) code2.instructions[2];
    assertTrue(isOutlineMethodName(invoke1.getMethod().qualifiedName()));

    // Run code and check result.
    String result = runArt(processedApplication);
    assertEquals("Test1Test1Test1Test1Test2Test2Test2Test2", result);
  }

  @Test
  public void constructorDontSplitNewInstanceAndInit() throws Exception {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    MethodSignature signature =
        builder.addStaticMethod(
            "java.lang.String",
            DEFAULT_METHOD_NAME,
            ImmutableList.of("java.lang.StringBuilder"),
            2,
            "    const-string        v0, \"Test1\"",
            "    invoke-virtual      { p0, v0 }, " + stringBuilderAppendSignature,
            "    move-result-object  p0",
            "    invoke-virtual      { p0, v0 }, " + stringBuilderAppendSignature,
            "    move-result-object  p0",
            "    new-instance        v1, Ljava/lang/StringBuilder;",
            "    invoke-direct       { v1 }, Ljava/lang/StringBuilder;-><init>()V",
            "    const-string        v0, \"Test2\"",
            "    invoke-virtual      { v1, v0 }, " + stringBuilderAppendSignature,
            "    move-result-object  v1",
            "    invoke-virtual      { v1, v0 }, " + stringBuilderAppendSignature,
            "    move-result-object  v1",
            "    invoke-virtual      { v1 }, " + stringBuilderToStringSignature,
            "    move-result-object  v0",
            "    return-object       v0");

    builder.addMainMethod(
        2,
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    new-instance        v1, Ljava/lang/StringBuilder;",
        "    invoke-direct       { v1 }, Ljava/lang/StringBuilder;-><init>()V",
        "    invoke-static       { v1 },"
            + " LTest;->method(Ljava/lang/StringBuilder;)Ljava/lang/String;",
        "    move-result-object  v1",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(Ljava/lang/String;)V",
        "    return-void");

    for (int i = 2; i < 8; i++) {
      final int finalI = i;
      Consumer<InternalOptions> options =
          configureOutlineOptions(
              outline -> {
                outline.threshold = 1;
                outline.minSize = finalI;
                outline.maxSize = finalI;
              });

      AndroidApp originalApplication = buildApplicationWithAndroidJar(builder);
      AndroidApp processedApplication = processApplication(originalApplication, options);
      assertEquals(2, getNumberOfProgramClasses(processedApplication));

      DexCode code = getMethod(processedApplication, signature).getCode().asDexCode();
      int outlineInstructionIndex;
      switch (i) {
        case 2:
        case 4:
          outlineInstructionIndex = 1;
          break;
        case 3:
          outlineInstructionIndex = 4;
          break;
        default:
          outlineInstructionIndex = 2;
      }
      Instruction instruction = code.instructions[outlineInstructionIndex];
      if (instruction instanceof InvokeStatic) {
        InvokeStatic invoke = (InvokeStatic) instruction;
        assertTrue(isOutlineMethodName(invoke.getMethod().qualifiedName()));
      } else {
        InvokeStaticRange invoke = (InvokeStaticRange) instruction;
        assertTrue(isOutlineMethodName(invoke.getMethod().qualifiedName()));
      }

      // Run code and check result.
      String result = runArt(processedApplication);
      assertEquals("Test2Test2", result);
    }
  }

  @Test
  public void outlineWithoutArguments() throws Exception {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    MethodSignature signature1 =
        builder.addStaticMethod(
            "java.lang.String",
            DEFAULT_METHOD_NAME,
            Collections.emptyList(),
            1,
            "    new-instance        v0, Ljava/lang/StringBuilder;",
            "    invoke-direct       { v0 }, Ljava/lang/StringBuilder;-><init>()V",
            "    invoke-virtual      { v0 }, " + stringBuilderToStringSignature,
            "    move-result-object  v0",
            "    return-object       v0");

    builder.addMainMethod(
        2,
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    invoke-static       {}, LTest;->method()Ljava/lang/String;",
        "    move-result-object  v1",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(Ljava/lang/String;)V",
        "    return-void");

    Consumer<InternalOptions> options =
        configureOutlineOptions(
            outline -> {
              outline.threshold = 1;
              outline.minSize = 3;
              outline.maxSize = 3;
            });

    AndroidApp originalApplication = buildApplicationWithAndroidJar(builder);
    AndroidApp processedApplication = processApplication(originalApplication, options);
    assertEquals(2, getNumberOfProgramClasses(processedApplication));

    DexCode code = getMethod(processedApplication, signature1).getCode().asDexCode();
    InvokeStatic invoke;
    assertTrue(code.instructions[0] instanceof InvokeStatic);
    invoke = (InvokeStatic) code.instructions[0];
    assertTrue(isOutlineMethodName(invoke.getMethod().qualifiedName()));

    // Run code and check result.
    String result = runArt(processedApplication);
    assertEquals("", result);
  }

  @Test
  public void outlineDifferentReturnType() throws Exception {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    List<String> parameters = Collections.singletonList("java.lang.StringBuilder");

    // The naming of the methods in this test is important. The method name that don't use the
    // output from StringBuilder.toString must sort before the method name that does.
    String returnType1 = "void";
    builder.addStaticMethod(
        returnType1,
        "method1",
        parameters,
        2,
        "    move-object         v0, p0",
        "    const-string        v1, \"Test\"",
        "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
        "    move-result-object  v0",
        "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
        "    move-result-object  v0",
        "    invoke-virtual      { v0 }, " + stringBuilderToStringSignature,
        "    return-void");

    String returnType2 = "java.lang.String";
    builder.addStaticMethod(
        returnType2,
        "method2",
        parameters,
        2,
        "    move-object         v0, p0",
        "    const-string        v1, \"Test\"",
        "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
        "    move-result-object  v0",
        "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
        "    move-result-object  v0",
        "    invoke-virtual      { v0 }, " + stringBuilderToStringSignature,
        "    move-result-object  v0",
        "    return-object       v0");

    builder.addMainMethod(
        3,
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    new-instance        v1, Ljava/lang/StringBuilder;",
        "    invoke-direct       { v1 }, Ljava/lang/StringBuilder;-><init>()V",
        "    invoke-static       { v1 }, LTest;->method1(Ljava/lang/StringBuilder;)V",
        "    invoke-static       { v1 },"
            + " LTest;->method2(Ljava/lang/StringBuilder;)Ljava/lang/String;",
        "    move-result-object  v2",
        "    invoke-virtual      { v0, v2 }, Ljava/io/PrintStream;->print(Ljava/lang/String;)V",
        "    return-void");

    Consumer<InternalOptions> options =
        configureOutlineOptions(
            outline -> {
              outline.threshold = 1;
              outline.minSize = 3;
              outline.maxSize = 3;
            });

    AndroidApp originalApplication = buildApplicationWithAndroidJar(builder);
    AndroidApp processedApplication = processApplication(originalApplication, options);
    assertEquals(2, getNumberOfProgramClasses(processedApplication));

    // Check that three outlining methods was created.
    CodeInspector inspector = new CodeInspector(processedApplication);
    ClassSubject clazz = inspector.clazz(OutlineOptions.CLASS_NAME);
    assertTrue(clazz.isPresent());
    assertEquals(3, clazz.getDexClass().directMethods().size());
    // Collect the return types of the putlines for the body of method1 and method2.
    List<DexType> r = new ArrayList<>();
    for (int i = 0; i < clazz.getDexClass().directMethods().size(); i++) {
      if (clazz.getDexClass().directMethods().get(i).getCode().asDexCode().instructions[0]
          instanceof InvokeVirtual) {
        r.add(clazz.getDexClass().directMethods().get(i).method.proto.returnType);
      }
    }
    assert r.size() == 2;
    DexType r1 = r.get(0);
    DexType r2 = r.get(1);
    DexItemFactory factory = inspector.getFactory();
    assertTrue(r1 == factory.voidType && r2 == factory.stringType ||
        r1 == factory.stringType && r2 == factory.voidType);

    // Run the code.
    String result = runArt(processedApplication);
    assertEquals("TestTestTestTest", result);
  }

  @Test
  public void outlineMultipleTimes() throws Exception {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    String returnType = "java.lang.String";
    List<String> parameters = Collections.singletonList("java.lang.StringBuilder");
    builder.addStaticMethod(
        returnType,
        DEFAULT_METHOD_NAME,
        parameters,
        2,
        "    move-object         v0, p0",
        "    const-string        v1, \"Test\"",
        "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
        "    move-result-object  v0",
        "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
        "    move-result-object  v0",
        "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
        "    move-result-object  v0",
        "    invoke-virtual      { v0, v1 }, " + stringBuilderAppendSignature,
        "    move-result-object  v0",
        "    invoke-virtual      { v0 }, " + stringBuilderToStringSignature,
        "    move-result-object  v0",
        "    return-object       v0");

    builder.addMainMethod(
        2,
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    new-instance        v1, Ljava/lang/StringBuilder;",
        "    invoke-direct       { v1 }, Ljava/lang/StringBuilder;-><init>()V",
        "    invoke-static       { v1 },"
            + " LTest;->method(Ljava/lang/StringBuilder;)Ljava/lang/String;",
        "    move-result-object  v1",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(Ljava/lang/String;)V",
        "    return-void");

    Consumer<InternalOptions> options =
        configureOutlineOptions(
            outline -> {
              outline.threshold = 1;
              outline.minSize = 3;
              outline.maxSize = 3;
            });

    AndroidApp originalApplication = buildApplicationWithAndroidJar(builder);
    AndroidApp processedApplication = processApplication(originalApplication, options);
    assertEquals(2, getNumberOfProgramClasses(processedApplication));

    final int count = 10;
    // Process the application several times. Each time will outline the previous outline.
    for (int i = 0; i < count; i++) {
      // Build a new application with the Outliner class.
      originalApplication = processedApplication;
      processedApplication = processApplication(originalApplication, options);
      assertEquals(i + 3, getNumberOfProgramClasses(processedApplication));
    }

    // Process the application several times. No more outlining as threshold has been raised.
    options =
        configureOutlineOptions(
            outline -> {
              outline.threshold = 2;
              outline.minSize = 3;
              outline.maxSize = 3;
            });
    for (int i = 0; i < count; i++) {
      // Build a new application with the Outliner class.
      originalApplication = processedApplication;
      processedApplication = processApplication(originalApplication, options);
      assertEquals(count - 1 + 3, getNumberOfProgramClasses(processedApplication));
    }

    // Run the application with several levels of outlining.
    String result = runArt(processedApplication);
    assertEquals("TestTestTestTest", result);
  }

  @Test
  public void outlineReturnLong() throws Exception {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    MethodSignature signature = builder.addStaticMethod(
        "long",
        DEFAULT_METHOD_NAME,
        ImmutableList.of("int"),
        2,
        "    new-instance        v0, Ljava/util/GregorianCalendar;",
        "    invoke-direct       { v0 }, Ljava/util/GregorianCalendar;-><init>()V",
        "    invoke-virtual      { v0, p0, p0 }, Ljava/util/Calendar;->set(II)V",
        "    invoke-virtual      { v0, p0, p0 }, Ljava/util/Calendar;->set(II)V",
        "    invoke-virtual      { v0 }, Ljava/util/Calendar;->getTimeInMillis()J",
        "    move-result-wide    v0",
        "    return-wide         v0"
    );

    builder.addMainMethod(
        3,
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    const/4             v1, 0",
        "    invoke-static       { v1 }, LTest;->method(I)J",
        "    move-result-wide    v1",
        "    invoke-virtual      { v0, v1, v2 }, Ljava/io/PrintStream;->print(J)V",
        "    return-void"
    );

    Consumer<InternalOptions> options =
        configureOutlineOptions(
            outline -> {
              outline.threshold = 1;
              outline.minSize = 5;
              outline.maxSize = 5;
            });

    AndroidApp originalApplication = buildApplicationWithAndroidJar(builder);
    AndroidApp processedApplication = processApplication(originalApplication, options);
    assertEquals(2, getNumberOfProgramClasses(processedApplication));

    // Return the processed method for inspection.
    DexEncodedMethod method = getMethod(processedApplication, signature);
    // The calls to set, set and getTimeInMillis was outlined.
    DexCode code = method.getCode().asDexCode();
    assertEquals(3, code.instructions.length);
    assertTrue(code.instructions[0] instanceof InvokeStatic);
    assertTrue(code.instructions[1] instanceof MoveResultWide);
    assertTrue(code.instructions[2] instanceof ReturnWide);
    InvokeStatic invoke = (InvokeStatic) code.instructions[0];
    assertEquals(firstOutlineMethodName(), invoke.getMethod().qualifiedName());

    // Run the code and expect a parsable long.
    String result = runArt(processedApplication);
    Long.parseLong(result);
  }

  @Test
  public void noOutlineSuperCalls() throws Exception {
    SmaliBuilder builder = new SmaliBuilder("Super");
    builder.addDefaultConstructor();
    builder.addInstanceMethod("void", "set", ImmutableList.of("int", "int"), 0,
        "return-void");

    builder.addInstanceMethod("java.lang.String", "toString", Collections.emptyList(), 1,
        "const-string     v0, \"Hello\"",
        "return-object    v0");

    builder.addClass(DEFAULT_CLASS_NAME, "Super");
    builder.addDefaultConstructor();

    builder.addStaticMethod(
        "java.lang.String",
        DEFAULT_METHOD_NAME,
        ImmutableList.of("int"),
        2,
        "    new-instance        v0, LTest;",
        "    invoke-direct       { v0 }, LTest;-><init>()V",
        "    invoke-super        { v0, p0, p0 }, LTest;->set(II)V",
        "    invoke-super        { v0, p0, p0 }, LTest;->set(II)V",
        "    invoke-virtual      { v0 }, LTest;->toString()Ljava/lang/String;",
        "    move-result-object  v0",
        "    return-object       v0"
    );

    builder.addMainMethod(
        3,
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    const/4             v1, 0",
        "    invoke-static       { v1 }, LTest;->method(I)Ljava/lang/String;",
        "    move-result-object  v1",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(Ljava/lang/String;)V",
        "    return-void"
    );

    Consumer<InternalOptions> options =
        configureOutlineOptions(
            outline -> {
              outline.threshold = 1;
              outline.minSize = 5;
              outline.maxSize = 5;
            });

    AndroidApp originalApplication = buildApplicationWithAndroidJar(builder);
    AndroidApp processedApplication = processApplication(originalApplication, options);
    assertEquals(2, getNumberOfProgramClasses(processedApplication));

    String originalResult = runArt(originalApplication);
    String processedResult = runArt(processedApplication);
    Assert.assertEquals(originalResult, processedResult);
  }

  @Test
  public void outlineArrayType() throws Exception {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    builder.addStaticMethod(
        "void",
        "addToList",
        ImmutableList.of("java.util.List", "int[]"),
        0,
        "    invoke-interface    { p0, p1 }, Ljava/util/List;->add(Ljava/lang/Object;)Z",
        "    return-void "
    );

    MethodSignature signature = builder.addStaticMethod(
        "int[]",
        DEFAULT_METHOD_NAME,
        ImmutableList.of("int[]", "int[]"),
        1,
        "    new-instance        v0, Ljava/util/ArrayList;",
        "    invoke-direct       { v0 }, Ljava/util/ArrayList;-><init>()V",
        "    invoke-static       { v0, p0 }, LTest;->addToList(Ljava/util/List;[I)V",
        "    invoke-static       { v0, p1 }, LTest;->addToList(Ljava/util/List;[I)V",
        "    return-object       p0"
    );

    builder.addMainMethod(
        3,
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    const/4             v1, 0",
        "    invoke-static       { v1, v1 }, LTest;->method([I[I)[I",
        "    move-result-object  v1",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(Ljava/lang/Object;)V",
        "    return-void"
    );

    Consumer<InternalOptions> options =
        configureOutlineOptions(
            outline -> {
              outline.threshold = 1;
              outline.minSize = 4;
              outline.maxSize = 4;
            });

    AndroidApp originalApplication = buildApplicationWithAndroidJar(builder);
    AndroidApp processedApplication = processApplication(originalApplication, options);
    assertEquals(2, getNumberOfProgramClasses(processedApplication));

    // Return the processed method for inspection.
    DexEncodedMethod method = getMethod(processedApplication, signature);
    DexCode code = method.getCode().asDexCode();
    assertEquals(2, code.instructions.length);
    assertTrue(code.instructions[0] instanceof InvokeStatic);
    assertTrue(code.instructions[1] instanceof ReturnObject);
    InvokeStatic invoke = (InvokeStatic) code.instructions[0];
    assertEquals(firstOutlineMethodName(), invoke.getMethod().qualifiedName());

    // Run code and check result.
    String result = runArt(processedApplication);
    assertEquals("null", result);
  }

  @Test
  public void outlineArithmeticBinop() throws Exception {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    builder.addStaticMethod(
        "void",
        "addToList",
        ImmutableList.of("java.util.List", "int[]"),
        0,
        "    invoke-interface    { p0, p1 }, Ljava/util/List;->add(Ljava/lang/Object;)Z",
        "    return-void "
    );

    MethodSignature signature1 = builder.addStaticMethod(
        "int",
        "method1",
        ImmutableList.of("int", "int"),
        1,
        "    add-int             v0, v1, v2",
        "    sub-int             v0, v0, v1",
        "    mul-int             v0, v2, v0",
        "    div-int             v0, v0, v1",
        "    return              v0"
    );

    MethodSignature signature2 = builder.addStaticMethod(
        "int",
        "method2",
        ImmutableList.of("int", "int"),
        1,
        "    add-int             v0, v2, v1",
        "    sub-int             v0, v0, v1",
        "    mul-int             v0, v0, v2",
        "    div-int             v0, v0, v1",
        "    return              v0"
    );

    builder.addMainMethod(
        4,
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    const/4             v1, 1",
        "    const/4             v2, 2",
        "    invoke-static       { v1, v2 }, LTest;->method1(II)I",
        "    move-result         v4",
        "    invoke-virtual      { v0, v4 }, Ljava/io/PrintStream;->print(I)V",
        "    invoke-static       { v1, v2 }, LTest;->method2(II)I",
        "    move-result         v4",
        "    invoke-virtual      { v0, v4 }, Ljava/io/PrintStream;->print(I)V",
        "    return-void"
    );

    Consumer<InternalOptions> options =
        configureOutlineOptions(
            outline -> {
              outline.threshold = 1;
              outline.minSize = 4;
              outline.maxSize = 4;
            });

    AndroidApp originalApplication = buildApplicationWithAndroidJar(builder);
    AndroidApp processedApplication = processApplication(originalApplication, options);
    assertEquals(2, getNumberOfProgramClasses(processedApplication));

    // Return the processed method for inspection.
    DexEncodedMethod method1 = getMethod(processedApplication, signature1);
    DexCode code1 = method1.getCode().asDexCode();
    assertEquals(3, code1.instructions.length);
    assertTrue(code1.instructions[0] instanceof InvokeStatic);
    assertTrue(code1.instructions[1] instanceof MoveResult);
    assertTrue(code1.instructions[2] instanceof Return);
    InvokeStatic invoke1 = (InvokeStatic) code1.instructions[0];
    assertTrue(isOutlineMethodName(invoke1.getMethod().qualifiedName()));

    DexEncodedMethod method2 = getMethod(processedApplication, signature2);
    DexCode code2 = method2.getCode().asDexCode();
    assertTrue(code2.instructions[0] instanceof InvokeStatic);
    InvokeStatic invoke2 = (InvokeStatic) code2.instructions[0];
    assertEquals(invoke1.getMethod().qualifiedName(), invoke2.getMethod().qualifiedName());

    // Run code and check result.
    String result = runArt(processedApplication);
    assertEquals("44", result);
  }

  @Test
  public void outlineWithHandler() throws Exception {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    builder.addStaticMethod(
        "void",
        "addToList",
        ImmutableList.of("java.util.List", "int[]"),
        0,
        "    invoke-interface    { p0, p1 }, Ljava/util/List;->add(Ljava/lang/Object;)Z",
        "    return-void "
    );

    MethodSignature signature = builder.addStaticMethod(
        "int",
        "method",
        ImmutableList.of("int", "int"),
        1,
        "    :try_start",
        // Throwing instruction to ensure the handler range does not get collapsed.
        "    div-int             v0, v1, v2",
        "    add-int             v0, v1, v2",
        "    sub-int             v0, v0, v1",
        "    mul-int             v0, v2, v0",
        "    div-int             v0, v0, v1",
        "    :try_end",
        "    :return",
        "    return              v0",
        "    .catch Ljava/lang/ArithmeticException; {:try_start .. :try_end} :catch",
        "    :catch",
        "    const/4             v0, -1",
        "    goto :return"
    );

    builder.addMainMethod(
        4,
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    const/4             v1, 1",
        "    const/4             v2, 2",
        "    invoke-static       { v1, v2 }, LTest;->method(II)I",
        "    move-result         v4",
        "    invoke-virtual      { v0, v4 }, Ljava/io/PrintStream;->print(I)V",
        "    return-void"
    );

    Consumer<InternalOptions> options =
        configureOutlineOptions(
            outline -> {
              outline.threshold = 1;
              outline.minSize = 3; // Outline add, sub and mul.
              outline.maxSize = 3;
            });

    AndroidApp originalApplication = buildApplicationWithAndroidJar(builder);
    AndroidApp processedApplication = processApplication(originalApplication, options);
    assertEquals(2, getNumberOfProgramClasses(processedApplication));

    // Return the processed method for inspection.
    DexEncodedMethod method = getMethod(processedApplication, signature);
    DexCode code = method.getCode().asDexCode();
    assertEquals(7, code.instructions.length);
    assertTrue(code.instructions[0] instanceof DivInt);
    assertTrue(code.instructions[1] instanceof InvokeStatic);
    assertTrue(code.instructions[2] instanceof MoveResult);
    assertTrue(code.instructions[3] instanceof DivInt2Addr);
    assertTrue(code.instructions[4] instanceof Goto);
    assertTrue(code.instructions[5] instanceof Const4);
    assertTrue(code.instructions[6] instanceof Return);
    InvokeStatic invoke = (InvokeStatic) code.instructions[1];
    assertTrue(isOutlineMethodName(invoke.getMethod().qualifiedName()));

    // Run code and check result.
    String result = runArt(processedApplication);
    assertEquals("4", result);
  }

  @Test
  public void outlineUnusedOutValue() throws Exception {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    // The result from neither the div-int is never used.
    MethodSignature signature = builder.addStaticMethod(
        "void",
        DEFAULT_METHOD_NAME,
        ImmutableList.of("int", "int"),
        1,
        "    div-int             v0, p0, p1",
        "    new-instance        v0, Ljava/lang/StringBuilder;",
        "    invoke-direct       { v0 }, Ljava/lang/StringBuilder;-><init>()V",
        "    return-void"
    );

    builder.addMainMethod(
        2,
        "    const               v0, 1",
        "    const               v1, 2",
        "    invoke-static       { v0, v1 }, LTest;->method(II)V",
        "    return-void"
    );

    Consumer<InternalOptions> options =
        configureOptions(
            opts -> {
              opts.outline.threshold = 1;
              opts.outline.minSize = 3;
              opts.outline.maxSize = 3;

              // Do not allow dead code elimination of the new-instance and invoke-direct
              // instructions.
              // This can be achieved by not assuming that StringBuilder is present.
              DexItemFactory dexItemFactory = opts.itemFactory;
              dexItemFactory.libraryTypesAssumedToBePresent =
                  new HashSet<>(dexItemFactory.libraryTypesAssumedToBePresent);
              dexItemFactory.libraryTypesAssumedToBePresent.remove(
                  dexItemFactory.stringBuilderType);
              // ... and not assuming that StringBuilder.<init>() cannot have side effects.
              dexItemFactory.libraryMethodsWithoutSideEffects =
                  new IdentityHashMap<>(dexItemFactory.libraryMethodsWithoutSideEffects);
              dexItemFactory.libraryMethodsWithoutSideEffects.remove(
                  dexItemFactory.stringBuilderMethods.defaultConstructor);
            });

    AndroidApp originalApplication = buildApplicationWithAndroidJar(builder);
    AndroidApp processedApplication = processApplication(originalApplication, options);
    assertEquals(2, getNumberOfProgramClasses(processedApplication));

    // Return the processed method for inspection.
    DexEncodedMethod method = getMethod(processedApplication, signature);
    DexCode code = method.getCode().asDexCode();
    assertEquals(2, code.instructions.length);
    assertTrue(code.instructions[0] instanceof InvokeStatic);
    assertTrue(code.instructions[1] instanceof ReturnVoid);
    InvokeStatic invoke = (InvokeStatic) code.instructions[0];
    assertEquals(firstOutlineMethodName(), invoke.getMethod().qualifiedName());

    // Run code and check result.
    String result = runArt(processedApplication);
    assertEquals("", result);
  }

  @Test
  public void outlineUnusedNewInstanceOutValue() throws Exception {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    // The result from the new-instance instructions are never used (<init> is not even called).
    MethodSignature signature = builder.addStaticMethod(
        "void",
        DEFAULT_METHOD_NAME,
        ImmutableList.of(),
        1,
        "    new-instance        v0, Ljava/lang/StringBuilder;",
        "    new-instance        v0, Ljava/lang/StringBuilder;",
        "    new-instance        v0, Ljava/lang/StringBuilder;",
        "    return-void"
    );

    builder.addMainMethod(
        0,
        "    invoke-static       { }, LTest;->method()V",
        "    return-void"
    );

    Consumer<InternalOptions> options =
        configureOptions(
            opts -> {
              opts.outline.threshold = 1;
              opts.outline.minSize = 3;
              opts.outline.maxSize = 3;

              // Do not allow dead code elimination of the new-instance instructions. This can be
              // achieved
              // by not assuming that StringBuilder is present.
              DexItemFactory dexItemFactory = opts.itemFactory;
              opts.itemFactory.libraryTypesAssumedToBePresent =
                  new HashSet<>(dexItemFactory.libraryTypesAssumedToBePresent);
              dexItemFactory.libraryTypesAssumedToBePresent.remove(
                  dexItemFactory.stringBuilderType);
            });

    AndroidApp originalApplication = buildApplicationWithAndroidJar(builder);
    AndroidApp processedApplication = processApplication(originalApplication, options);
    assertEquals(2, getNumberOfProgramClasses(processedApplication));

    // Return the processed method for inspection.
    DexEncodedMethod method = getMethod(processedApplication, signature);
    DexCode code = method.getCode().asDexCode();
    assertEquals(2, code.instructions.length);
    assertTrue(code.instructions[0] instanceof InvokeStatic);
    assertTrue(code.instructions[1] instanceof ReturnVoid);
    InvokeStatic invoke = (InvokeStatic) code.instructions[0];
    assertEquals(firstOutlineMethodName(), invoke.getMethod().qualifiedName());

    // Run code and check result.
    String result = runArt(processedApplication);
    assertEquals("", result);
  }

  @Test
  public void regress33733666() throws Exception {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    builder.addStaticMethod(
        "void",
        DEFAULT_METHOD_NAME,
        Collections.emptyList(),
        4,
        "    new-instance        v0, Ljava/util/Hashtable;",
        "    invoke-direct       { v0 }, Ljava/util/Hashtable;-><init>()V",
        "    const-string        v1, \"http://schemas.google.com/g/2005#home\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x01  # 1",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    const-string        v1, \" http://schemas.google.com/g/2005#work\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x02  # 2",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    const-string        v1, \"http://schemas.google.com/g/2005#other\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x03  # 3",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    const-string        v1, \"http://schemas.google.com/g/2005#primary\"",
        "    const/4             v2, 0x04  # 4",
        "    invoke-static       { v2 }, Ljava/lang/Byte;->valueOf(B)Ljava/lang/Byte;",
        "    move-result-object  v2",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    sput-object         v0, LA;->A:Ljava/util/Hashtable;",
        "    invoke-static       { v0 }, LA;->a(Ljava/util/Hashtable;)Ljava/util/Hashtable;",
        "    move-result-object  v0",
        "    sput-object         v0, LA;->B:Ljava/util/Hashtable;",
        "    new-instance        v0, Ljava/util/Hashtable;",
        "    invoke-direct       { v0 }, Ljava/util/Hashtable;-><init>()V",
        "    const-string        v1, \"http://schemas.google.com/g/2005#home\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x02  # 2",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    const-string        v1, \"http://schemas.google.com/g/2005#mobile\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x01  # 1",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    const-string        v1, \"http://schemas.google.com/g/2005#pager\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x06  # 6",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    const-string        v1, \"http://schemas.google.com/g/2005#work\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x03  # 3",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    const-string        v1, \"http://schemas.google.com/g/2005#home_fax\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x05  # 5",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    const-string        v1, \"http://schemas.google.com/g/2005#work_fax\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x04  # 4",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    const-string        v1, \"http://schemas.google.com/g/2005#other\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x07  # 7",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    sput-object         v0, LA;->C:Ljava/util/Hashtable;",
        "    invoke-static       { v0 }, LA;->a(Ljava/util/Hashtable;)Ljava/util/Hashtable;",
        "    move-result-object  v0",
        "    sput-object         v0, LA;->D:Ljava/util/Hashtable;",
        "    new-instance        v0, Ljava/util/Hashtable;",
        "    invoke-direct       { v0 }, Ljava/util/Hashtable;-><init>()V",
        "    const-string        v1, \"http://schemas.google.com/g/2005#home\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x01  # 1",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    const-string        v1, \"http://schemas.google.com/g/2005#work\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x02  # 2",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    const-string        v1, \"http://schemas.google.com/g/2005#other\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x03  # 3",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    sput-object         v0, LA;->E:Ljava/util/Hashtable;",
        "    invoke-static       { v0 }, LA;->a(Ljava/util/Hashtable;)Ljava/util/Hashtable;",
        "    move-result-object  v0",
        "    sput-object         v0, LA;->F:Ljava/util/Hashtable;",
        "    new-instance        v0, Ljava/util/Hashtable;",
        "    invoke-direct       { v0 }, Ljava/util/Hashtable;-><init>()V",
        "    const-string        v1, \"http://schemas.google.com/g/2005#home\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x01  # 1",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    const-string        v1, \"http://schemas.google.com/g/2005#work\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x02  # 2",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    const-string        v1, \"http://schemas.google.com/g/2005#other\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x03  # 3",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    sput-object         v0, LA;->G:Ljava/util/Hashtable;",
        "    invoke-static       { v0 }, LA;->a(Ljava/util/Hashtable;)Ljava/util/Hashtable;",
        "    move-result-object  v0",
        "    sput-object         v0, LA;->H:Ljava/util/Hashtable;",
        "    new-instance        v0, Ljava/util/Hashtable;",
        "    invoke-direct       { v0 }, Ljava/util/Hashtable;-><init>()V",
        "    const-string        v1, \"http://schemas.google.com/g/2005#work\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x01  # 1",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    const-string        v1, \"http://schemas.google.com/g/2005#other\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x02  # 2",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    sput-object         v0, LA;->I:Ljava/util/Hashtable;",
        "    invoke-static       { v0 }, LA;->a(Ljava/util/Hashtable;)Ljava/util/Hashtable;",
        "    move-result-object  v0",
        "    sput-object         v0, LA;->J:Ljava/util/Hashtable;",
        "    new-instance        v0, Ljava/util/Hashtable;",
        "    invoke-direct       { v0 }, Ljava/util/Hashtable;-><init>()V",
        "    const-string        v1, \"http://schemas.google.com/g/2005#AIM\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x02  # 2",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    const-string        v1, \"http://schemas.google.com/g/2005#MSN\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x03  # 3",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    const-string        v1, \"http://schemas.google.com/g/2005#YAHOO\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x04  # 4",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    const-string        v1, \"http://schemas.google.com/g/2005#SKYPE\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x05  # 5",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    const-string        v1, \"http://schemas.google.com/g/2005#QQ\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x06  # 6",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    const-string        v1, \"http://schemas.google.com/g/2005#GOOGLE_TALK\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/4             v3, 0x07  # 7",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    const-string        v1, \"http://schemas.google.com/g/2005#ICQ\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/16            v3, 0x0008  # 8",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    const-string        v1, \"http://schemas.google.com/g/2005#JABBER\"",
        "    new-instance        v2, Ljava/lang/Byte;",
        "    const/16            v3, 0x0009  # 9",
        "    invoke-direct       { v2, v3 }, Ljava/lang/Byte;-><init>(B)V",
        "    invoke-virtual      { v0, v1, v2 },"
            + " Ljava/util/Hashtable;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
        "    sput-object         v0, LA;->K:Ljava/util/Hashtable;",
        "    invoke-static       { v0 }, LA;->a(Ljava/util/Hashtable;)Ljava/util/Hashtable;",
        "    move-result-object  v0",
        "    sput-object         v0, LA;->L:Ljava/util/Hashtable;",
        "    return-void");

    Consumer<InternalOptions> options = configureOutlineOptions(outline -> outline.threshold = 2);

    AndroidApp originalApplication = buildApplicationWithAndroidJar(builder);
    AndroidApp processedApplication = processApplication(originalApplication, options);
    assertEquals(2, getNumberOfProgramClasses(processedApplication));

    // Verify the code.
    runDex2Oat(processedApplication);
  }

  private static boolean isOutlineInvoke(Instruction instruction) {
    return instruction instanceof InvokeStatic
        && instruction.getMethod().holder.toSourceString().equals(OutlineOptions.CLASS_NAME);
  }

  private void assertHasOutlineInvoke(DexEncodedMethod method) {
    assertTrue(
        Arrays
            .stream(method.getCode().asDexCode().instructions)
            .anyMatch(OutlineTest::isOutlineInvoke));
  }

  @Test
  public void b113145696_superClassUseFirst() throws Exception {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    // Code where the outline argument is first used as java.lang.Object and afterwards
    // java.util.ArrayList.
    List<String> codeToOutline = ImmutableList.of(
        "    invoke-virtual      { v1, v2 }, Ljava/io/PrintStream;->print(Ljava/lang/Object;)V",
        "    invoke-virtual      { v2 }, Ljava/util/ArrayList;->isEmpty()Z",
        "    move-result         v0",
        "    return              v0"
    );

    String returnType = "boolean";
    List<String> parameters = ImmutableList.of("java.io.PrintStream", "java.util.ArrayList");
    MethodSignature signature1 = builder.addPrivateInstanceMethod(
        returnType,
        DEFAULT_METHOD_NAME + "1",
        parameters,
        0,
        codeToOutline.toArray(StringUtils.EMPTY_ARRAY)
    );

    MethodSignature signature2 = builder.addPrivateInstanceMethod(
        returnType,
        DEFAULT_METHOD_NAME + "2",
        parameters,
        0,
        codeToOutline.toArray(StringUtils.EMPTY_ARRAY)
    );

    builder.addMainMethod(
        3,
        "    new-instance        v0, LTest;",
        "    invoke-direct       { v0 }, LTest;-><init>()V",
        "    sget-object         v1, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    new-instance        v2, Ljava/util/ArrayList;",
        "    invoke-direct       { v2 }, Ljava/util/ArrayList;-><init>()V",
        "    invoke-virtual      { v0, v1, v2 }, " +
        "                            LTest;->method1(Ljava/io/PrintStream;Ljava/util/ArrayList;)Z",
        "    move-result         v3",
        "    invoke-virtual      { v1, v3 }, Ljava/io/PrintStream;->print(Z)V",
        "    invoke-virtual      { v0, v1, v2 }, " +
        "                            LTest;->method2(Ljava/io/PrintStream;Ljava/util/ArrayList;)Z",
        "    move-result         v3",
        "    invoke-virtual      { v1, v3 }, Ljava/io/PrintStream;->print(Z)V",
        "    return-void"
    );

    // Outline 2 times two instructions.
    Consumer<InternalOptions> options =
        configureOutlineOptions(
            outline -> {
              outline.threshold = 2;
              outline.minSize = 2;
              outline.maxSize = 2;
            });

    AndroidApp originalApplication = buildApplication(builder);
    AndroidApp processedApplication = processApplication(originalApplication, options);
    assertEquals(2, getNumberOfProgramClasses(processedApplication));

    // Check that outlining happened.
    assertHasOutlineInvoke(getMethod(processedApplication, signature1));
    assertHasOutlineInvoke(getMethod(processedApplication, signature2));
    assertThat(
        new CodeInspector(processedApplication)
            .clazz(OutlineOptions.CLASS_NAME)
            .method(
                "boolean",
                "outline0",
                ImmutableList.of("java.io.PrintStream", "java.util.ArrayList")),
        isPresent());

    // Run code and check result.
    String result = runArt(processedApplication);
    assertEquals("[]true[]true", result);
  }

  @Test
  public void b113145696_superInterfaceUseFirst() throws Exception {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    List<String> codeToOutline = ImmutableList.of(
        "    invoke-interface      { v1 }, Ljava/lang/Iterable;->iterator()Ljava/util/Iterator;",
        "    invoke-interface      { v1 }, Ljava/util/Collection;->isEmpty()Z",
        "    move-result         v0",
        "    return              v0"
    );

    String returnType = "boolean";
    List<String> parameters = ImmutableList.of("java.util.List");
    MethodSignature signature1 = builder.addPrivateInstanceMethod(
        returnType,
        DEFAULT_METHOD_NAME + "1",
        parameters,
        0,
        codeToOutline.toArray(StringUtils.EMPTY_ARRAY)
    );

    MethodSignature signature2 = builder.addPrivateInstanceMethod(
        returnType,
        DEFAULT_METHOD_NAME + "2",
        parameters,
        0,
        codeToOutline.toArray(StringUtils.EMPTY_ARRAY)
    );

    builder.addMainMethod(
        3,
        "    new-instance        v0, LTest;",
        "    invoke-direct       { v0 }, LTest;-><init>()V",
        "    sget-object         v1, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    new-instance        v2, Ljava/util/ArrayList;",
        "    invoke-direct       { v2 }, Ljava/util/ArrayList;-><init>()V",
        "    invoke-virtual      { v0, v2 }, LTest;->method1(Ljava/util/List;)Z",
        "    move-result         v3",
        "    invoke-virtual      { v1, v3 }, Ljava/io/PrintStream;->print(Z)V",
        "    invoke-virtual      { v0, v2 }, LTest;->method2(Ljava/util/List;)Z",
        "    move-result         v3",
        "    invoke-virtual      { v1, v3 }, Ljava/io/PrintStream;->print(Z)V",
        "    return-void"
    );

    // Outline 2 times two instructions.
    Consumer<InternalOptions> options =
        configureOutlineOptions(
            outline -> {
              outline.threshold = 2;
              outline.minSize = 2;
              outline.maxSize = 2;
            });

    AndroidApp originalApplication = buildApplication(builder);
    AndroidApp processedApplication = processApplication(originalApplication, options);
    assertEquals(2, getNumberOfProgramClasses(processedApplication));

    // Check that outlining happened.
    assertHasOutlineInvoke(getMethod(processedApplication, signature1));
    assertHasOutlineInvoke(getMethod(processedApplication, signature2));
    assertThat(
        new CodeInspector(processedApplication)
            .clazz(OutlineOptions.CLASS_NAME)
            .method("boolean", "outline0", ImmutableList.of("java.util.List")),
        isPresent());

    // Run code and check result.
    String result = runArt(processedApplication);
    assertEquals("truetrue", result);
  }

  @Test
  public void b113145696_interfaceUseFirst() throws Exception {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    // Code where the outline argument is first used as java.lang.Iterable and afterwards
    // java.util.ArrayList.
    List<String> codeToOutline = ImmutableList.of(
        "    invoke-interface    { v1 }, Ljava/lang/Iterable;->iterator()Ljava/util/Iterator;",
        "    invoke-virtual      { v1 }, Ljava/util/ArrayList;->isEmpty()Z",
        "    move-result         v0",
        "    return              v0"
    );

    String returnType = "boolean";
    List<String> parameters = ImmutableList.of("java.util.ArrayList");
    MethodSignature signature1 = builder.addPrivateInstanceMethod(
        returnType,
        DEFAULT_METHOD_NAME + "1",
        parameters,
        0,
        codeToOutline.toArray(StringUtils.EMPTY_ARRAY)
    );

    MethodSignature signature2 = builder.addPrivateInstanceMethod(
        returnType,
        DEFAULT_METHOD_NAME + "2",
        parameters,
        0,
        codeToOutline.toArray(StringUtils.EMPTY_ARRAY)
    );

    builder.addMainMethod(
        3,
        "    new-instance        v0, LTest;",
        "    invoke-direct       { v0 }, LTest;-><init>()V",
        "    sget-object         v1, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    new-instance        v2, Ljava/util/ArrayList;",
        "    invoke-direct       { v2 }, Ljava/util/ArrayList;-><init>()V",
        "    invoke-virtual      { v0, v2 }, LTest;->method1(Ljava/util/ArrayList;)Z",
        "    move-result         v3",
        "    invoke-virtual      { v1, v3 }, Ljava/io/PrintStream;->print(Z)V",
        "    invoke-virtual      { v0, v2 }, LTest;->method2(Ljava/util/ArrayList;)Z",
        "    move-result         v3",
        "    invoke-virtual      { v1, v3 }, Ljava/io/PrintStream;->print(Z)V",
        "    return-void"
    );

    // Outline 2 times two instructions.
    Consumer<InternalOptions> options =
        configureOutlineOptions(
            outline -> {
              outline.threshold = 2;
              outline.minSize = 2;
              outline.maxSize = 2;
            });

    AndroidApp originalApplication = buildApplication(builder);
    AndroidApp processedApplication = processApplication(originalApplication, options);
    assertEquals(2, getNumberOfProgramClasses(processedApplication));

    // Check that outlining happened.
    assertHasOutlineInvoke(getMethod(processedApplication, signature1));
    assertHasOutlineInvoke(getMethod(processedApplication, signature2));
    assertThat(
        new CodeInspector(processedApplication)
            .clazz(OutlineOptions.CLASS_NAME)
            .method("boolean", "outline0", ImmutableList.of("java.util.ArrayList")),
        isPresent());

    // Run code and check result.
    String result = runArt(processedApplication);
    assertEquals("truetrue", result);
  }

  @Test
  public void b113145696_classUseFirst() throws Exception {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    // Code where the outline argument is first used as java.lang.Iterable and afterwards
    // java.util.ArrayList.
    List<String> codeToOutline = ImmutableList.of(
        "    invoke-virtual      { v1 }, Ljava/util/ArrayList;->isEmpty()Z",
        "    move-result         v0",
        "    invoke-interface    { v1 }, Ljava/lang/Iterable;->iterator()Ljava/util/Iterator;",
        "    return              v0"
    );

    String returnType = "boolean";
    List<String> parameters = ImmutableList.of("java.util.ArrayList");
    MethodSignature signature1 = builder.addPrivateInstanceMethod(
        returnType,
        DEFAULT_METHOD_NAME + "1",
        parameters,
        0,
        codeToOutline.toArray(StringUtils.EMPTY_ARRAY)
    );

    MethodSignature signature2 = builder.addPrivateInstanceMethod(
        returnType,
        DEFAULT_METHOD_NAME + "2",
        parameters,
        0,
        codeToOutline.toArray(StringUtils.EMPTY_ARRAY)
    );

    builder.addMainMethod(
        3,
        "    new-instance        v0, LTest;",
        "    invoke-direct       { v0 }, LTest;-><init>()V",
        "    sget-object         v1, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    new-instance        v2, Ljava/util/ArrayList;",
        "    invoke-direct       { v2 }, Ljava/util/ArrayList;-><init>()V",
        "    invoke-virtual      { v0, v2 }, LTest;->method1(Ljava/util/ArrayList;)Z",
        "    move-result         v3",
        "    invoke-virtual      { v1, v3 }, Ljava/io/PrintStream;->print(Z)V",
        "    invoke-virtual      { v0, v2 }, LTest;->method2(Ljava/util/ArrayList;)Z",
        "    move-result         v3",
        "    invoke-virtual      { v1, v3 }, Ljava/io/PrintStream;->print(Z)V",
        "    return-void"
    );

    // Outline 2 times two instructions.
    Consumer<InternalOptions> options =
        configureOutlineOptions(
            outline -> {
              outline.threshold = 2;
              outline.minSize = 2;
              outline.maxSize = 2;
            });

    AndroidApp originalApplication = buildApplication(builder);
    AndroidApp processedApplication = processApplication(originalApplication, options);
    assertEquals(2, getNumberOfProgramClasses(processedApplication));

    // Check that outlining happened.
    assertHasOutlineInvoke(getMethod(processedApplication, signature1));
    assertHasOutlineInvoke(getMethod(processedApplication, signature2));
    assertThat(
        new CodeInspector(processedApplication)
            .clazz(OutlineOptions.CLASS_NAME)
            .method("boolean", "outline0", ImmutableList.of("java.util.ArrayList")),
        isPresent());

    // Run code and check result.
    String result = runArt(processedApplication);
    assertEquals("truetrue", result);
  }
}
