anchor.diff:      return list;
     }
   
  -  List<List<List<DartType>>> fillTypes3(int n,
  -      {int limit2 = 4, int limit1 = 4}) {
  -    final list = <List<List<DartType>>>[];
  -    for (int i = 0; i < n; i++) {
  -      list.add(fillTypes2(limit2: limit2, limit1: limit1));
  -    }
  -    return list;
  -  }
  -
     List<DartType> getCurrentProto() {
       if (currentClass != null) {
         if (currentMethod != null) {
  -        return classMethods[currentClass][currentMethod];
  +        return classMethods[currentClass][currentMethod].parameters;
         }
       } else if (currentMethod != null) {
  -      return globalMethods[currentMethod];
  +      return globalMethods[currentMethod].parameters;
       }
       return null;
     }
  
positive.code:     if (currentClass == null) {
        // Outside a class but inside a method: call backward in global methods.
        if (currentMethod != null &&
            pickedCall(depth, tp, methodName, globalMethods, currentMethod,
                rhsFilter: rhsFilter)) {
          return;
        }
  
negative.code: const localName = 'loc';
  const fieldName = 'fld';
  const methodName = 'foo';
  
  /// Enum for the different types of methods generated by the fuzzer.
  enum MethodType { globalMethod, ffiMethod, instanceMethod, extensionMethod }
  
  /// Base class for all methods in the program generated by DartFuzz.
  abstract class Method {
    Method(this.name, this.parameters, this.fuzzer);
  
    DartType get returnType => parameters[0];
  
    void emitFunctionBody() {
      if (fuzzer.rollDice(10)) {
        // Emit a method using "=>" syntax.
        fuzzer.emit(' => ');
        fuzzer.emitExpr(0, returnType, includeSemicolon: true);
      } else {
        fuzzer.emitBraceWrapped(() {
          assert(fuzzer.localVars.isEmpty);
          if (fuzzer.emitStatements(0)) {
            fuzzer.emitReturn();
          }
          assert(fuzzer.localVars.isEmpty);
        });
      }
    }
  
    void emitFunctionDefinition() {
      final type = returnType.name;
      fuzzer.emitLn('$type ${name}', newline: false);
      fuzzer.emitParenWrapped(() => fuzzer.emitParDecls(parameters));
      emitFunctionBody();
      fuzzer.emitNewline();
      fuzzer.emitNewline();
    }
  
    void emitCall(int depth,
        {RhsFilter rhsFilter,
        bool includeSemicolon = false,
        bool extensionApplication = false}) {
      String outputName = name;
      fuzzer.emitLn(outputName, newline: false);
      fuzzer.emitExprList(depth + 1, parameters, rhsFilter: rhsFilter);
      if (includeSemicolon) {
        fuzzer.emit(';');
      }
    }
  
    // Main emitter for a method.
    void emit() {
      emitFunctionDefinition();
    }
  
    final String name;
    final List<DartType> parameters;
    final DartFuzz fuzzer;
  }
  
  /// Class for global methods generated by DartFuzz.
  class GlobalMethod extends Method {
    GlobalMethod(String name, List<DartType> parameters, DartFuzz fuzzer)
        : super(name, parameters, fuzzer);
  }
  
  /// Class for ffi methods generated by DartFuzz.
  class FfiMethod extends Method {
    FfiMethod(
        String namePrefix, int index, List<DartType> parameters, DartFuzz fuzzer)
        : ffiCastName = "${namePrefix}FfiCast${index}",
          super("${namePrefix}Ffi${index}", parameters, fuzzer) {}
  
    @override
    void emitFunctionBody() {
      fuzzer.emitBraceWrapped(() {
        assert(fuzzer.localVars.isEmpty);
        if (fuzzer.emitStatements(0)) {
          fuzzer.emitReturn();
        }
        assert(fuzzer.localVars.isEmpty);
      });
    }
  
    @override
    void emit() {
      fuzzer.emitFfiTypedef(this);
      emitFunctionDefinition();
      fuzzer.emitFfiCast("${ffiCastName}", "${name}", "${name}Type", parameters);
      fuzzer.emitNewline();
      fuzzer.emitNewline();
    }
  
    final String ffiCastName;
  }
  
  /// Class for instance methods generated by DartFuzz.
  class InstanceMethod extends Method {
    InstanceMethod(
        String name, List<DartType> parameters, DartFuzz fuzzer, this.className)
        : super(name, parameters, fuzzer) {}
  
    @override
    void emitCall(int depth,
        {RhsFilter rhsFilter,
        bool includeSemicolon = false,
        bool extensionApplication = false}) {
      String outputName = name;
      if (fuzzer.currentClass == null) {
        // If we're calling an instance method from outside the class, then we
        // should construct an object of that class first.
        outputName = "${className}().${name}";
      }
      fuzzer.emitLn(outputName, newline: false);
      fuzzer.emitExprList(depth + 1, parameters, rhsFilter: rhsFilter);
      if (includeSemicolon) {
        fuzzer.emit(';');
      }
    }
  
    final String className;
  }
  
  // Class for extension methods generated by DartFuzz.
  class ExtensionMethod extends Method {
    ExtensionMethod(String name, List<DartType> parameters, DartFuzz fuzzer,
        this.className, this.extensionName)
        : super(name, parameters, fuzzer) {}
  
    @override
    void emitCall(int depth,
        {RhsFilter rhsFilter,
        bool includeSemicolon = false,
        bool extensionApplication = false}) {
      String outputName = name;
      if (fuzzer.currentClass == null) {
        // If we're calling an extension method from outside the class, we can
        // call it using an object of the class or using explicit extension
        // application.
        if (extensionApplication) {
          outputName = "${extensionName}(${className}()).${name}";
        } else {
          outputName = "${className}().${name}";
        }
      }
      fuzzer.emitLn(outputName, newline: false);
      fuzzer.emitExprList(depth + 1, parameters, rhsFilter: rhsFilter);
      if (includeSemicolon) {
        fuzzer.emit(';');
      }
    }
  
    final String className;
    final String extensionName;
  }
  
  // Class that tracks the state of the filter applied to the
  // right-hand-side of an assignment in order to avoid generating
  