// Copyright (c) 2012, the Dart 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.

import 'dart:isolate';
import 'dart:async';

class Expect {
  static void equals(x, y) {
    if (x != y) throw new ArgumentError('not equal');
  }
}

class Fields {
  Fields(int i, int j)
      : fld1 = i,
        fld2 = j,
        fld5 = true {}
  int fld1;
  final int fld2;
  static int fld3;
  static const int fld4 = 10;
  bool fld5;
}

class FieldsTest {
  static Fields testMain() {
    Fields obj = new Fields(10, 20);
    Expect.equals(10, obj.fld1);
    Expect.equals(20, obj.fld2);
    Expect.equals(10, Fields.fld4);
    Expect.equals(true, obj.fld5);
    return obj;
  }
}
// Benchpress: A collection of micro-benchmarks.
// Ported from internal v8 benchmark suite.

class Error {
  static void error(String msg) {
    throw msg;
  }
}

// F i b o n a c c i
class Fibonacci {
  static int fib(int n) {
    if (n <= 1) return 1;
    return fib(n - 1) + fib(n - 2);
  }
}

class FibBenchmark extends BenchmarkBase {
  const FibBenchmark() : super("Fibonacci");

  void warmup() {
    Fibonacci.fib(10);
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    var result = Fibonacci.fib(20);
    if (result != 10946)
      Error.error("Wrong result: $result. Should be: 10946.");
  }

  static void main() {
    new FibBenchmark().report();
  }
}

// L o o p
class Loop {
  static int loop(int outerIterations) {
    int sum = 0;
    for (int i = 0; i < outerIterations; i++) {
      for (int j = 0; j < 100; j++) {
        sum++;
      }
    }
    return sum;
  }
}

class LoopBenchmark extends BenchmarkBase {
  const LoopBenchmark() : super("Loop");

  void warmup() {
    Loop.loop(10);
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    var result = Loop.loop(200);
    if (result != 20000) Error.error("Wrong result: $result. Should be: 20000");
  }

  static void main() {
    new LoopBenchmark().report();
  }
}

// T o w e r s
class TowersDisk {
  final int size;
  TowersDisk next;

  TowersDisk(size)
      : this.size = size,
        next = null {}
}

class Towers {
  List<TowersDisk> piles;
  int movesDone;
  Towers(int disks)
      : piles = new List<TowersDisk>(3),
        movesDone = 0 {
    build(0, disks);
  }

  void build(int pile, int disks) {
    for (var i = disks - 1; i >= 0; i--) {
      push(pile, new TowersDisk(i));
    }
  }

  void push(int pile, TowersDisk disk) {
    TowersDisk top = piles[pile];
    if ((top != null) && (disk.size >= top.size))
      Error.error("Cannot put a big disk on a smaller disk.");
    disk.next = top;
    piles[pile] = disk;
  }

  TowersDisk pop(int pile) {
    var top = piles[pile];
    if (top == null)
      Error.error("Attempting to remove a disk from an empty pile.");
    piles[pile] = top.next;
    top.next = null;
    return top;
  }

  void moveTop(int from, int to) {
    push(to, pop(from));
    movesDone++;
  }

  void move(int from, int to, int disks) {
    if (disks == 1) {
      moveTop(from, to);
    } else {
      int other = 3 - from - to;
      move(from, other, disks - 1);
      moveTop(from, to);
      move(other, to, disks - 1);
    }
  }
}

class TowersBenchmark extends BenchmarkBase {
  const TowersBenchmark() : super("Towers");

  void warmup() {
    new Towers(6).move(0, 1, 6);
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    var towers = new Towers(13);
    towers.move(0, 1, 13);
    if (towers.movesDone != 8191) {
      var moves = towers.movesDone;
      Error.error("Error in result: $moves should be: 8191");
    }
  }

  static void main() {
    new TowersBenchmark().report();
  }
}

// S i e v e
class SieveBenchmark extends BenchmarkBase {
  const SieveBenchmark() : super("Sieve");

  static int sieve(int size) {
    int primeCount = 0;
    List<bool> flags = new List<bool>(size + 1);
    for (int i = 1; i < size; i++) flags[i] = true;
    for (int i = 2; i < size; i++) {
      if (flags[i]) {
        primeCount++;
        for (int k = i + 1; k <= size; k += i) flags[k - 1] = false;
      }
    }
    return primeCount;
  }

  void warmup() {
    sieve(100);
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    int result = sieve(1000);
    if (result != 168) Error.error("Wrong result: $result should be: 168");
  }

  static void main() {
    new SieveBenchmark().report();
  }
}

// P e r m u t e
// The original benchmark uses one-based indexing. Even though arrays in JS and
// lists in dart are zero-based, we stay with one-based indexing
// (wasting one element).
class Permute {
  int permuteCount;
  Permute() {}

  void swap(int n, int k, List<int> list) {
    int tmp = list[n];
    list[n] = list[k];
    list[k] = tmp;
  }

  void doPermute(int n, List<int> list) {
    permuteCount++;
    if (n != 1) {
      doPermute(n - 1, list);
      for (int k = n - 1; k >= 1; k--) {
        swap(n, k, list);
        doPermute(n - 1, list);
        swap(n, k, list);
      }
    }
  }

  int permute(int size) {
    permuteCount = 0;
    List<int> list = new List<int>(size);
    for (int i = 1; i < size; i++) list[i] = i - 1;
    doPermute(size - 1, list);
    return permuteCount;
  }
}

class PermuteBenchmark extends BenchmarkBase {
  const PermuteBenchmark() : super("Permute");

  void warmup() {
    new Permute().permute(4);
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    int result = new Permute().permute(8);
    if (result != 8660) Error.error("Wrong result: $result should be: 8660");
  }

  static void main() {
    new PermuteBenchmark().report();
  }
}

// Q u e e n s
// The original benchmark uses one-based indexing. Even though arrays in JS and
// lists in dart are zero-based, we stay with one-based indexing
// (wasting one element).
class Queens {
  static bool tryQueens(
      int i, List<bool> a, List<bool> b, List<bool> c, List<int> x) {
    int j = 0;
    bool q = false;
    while ((!q) && (j != 8)) {
      j++;
      q = false;
      if (b[j] && a[i + j] && c[i - j + 7]) {
        x[i] = j;
        b[j] = false;
        a[i + j] = false;
        c[i - j + 7] = false;
        if (i < 8) {
          q = tryQueens(i + 1, a, b, c, x);
          if (!q) {
            b[j] = true;
            a[i + j] = true;
            c[i - j + 7] = true;
          }
        } else {
          q = true;
        }
      }
    }
    return q;
  }

  static void queens() {
    List<bool> a = new List<bool>(9);
    List<bool> b = new List<bool>(17);
    List<bool> c = new List<bool>(15);
    List<int> x = new List<int>(9);
    b[1] = false;
    for (int i = -7; i <= 16; i++) {
      if ((i >= 1) && (i <= 8)) a[i] = true;
      if (i >= 2) b[i] = true;
      if (i <= 7) c[i + 7] = true;
    }

    if (!tryQueens(1, b, a, c, x)) Error.error("Error in queens");
  }
}

class QueensBenchmark extends BenchmarkBase {
  const QueensBenchmark() : super("Queens");

  void warmup() {
    Queens.queens();
  }

  void exercise() {
    Queens.queens();
  }

  static void main() {
    new QueensBenchmark().report();
  }
}

// R e c u r s e
class Recurse {
  static int recurse(int n) {
    if (n <= 0) return 1;
    recurse(n - 1);
    return recurse(n - 1);
  }
}

class RecurseBenchmark extends BenchmarkBase {
  const RecurseBenchmark() : super("Recurse");

  void warmup() {
    Recurse.recurse(7);
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    Recurse.recurse(13);
  }

  static void main() {
    new RecurseBenchmark().report();
  }
}

// S u m
class SumBenchmark extends BenchmarkBase {
  const SumBenchmark() : super("Sum");

  static int sum(int start, int end) {
    var sum = 0;
    for (var i = start; i <= end; i++) sum += i;
    return sum;
  }

  void warmup() {
    sum(1, 1000);
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    int result = sum(1, 10000);
    if (result != 50005000)
      Error.error("Wrong result: $result should be 50005000");
  }

  static void main() {
    new SumBenchmark().report();
  }
}

// H e l p e r   f u n c t i o n s   f o r   s o r t s
class Random {
  static const int INITIAL_SEED = 74755;
  int seed;
  Random() : seed = INITIAL_SEED {}

  int random() {
    seed = ((seed * 1309) + 13849) % 65536;
    return seed;
  }
}

//
class SortData {
  List<int> list;
  int min;
  int max;

  SortData(int length) {
    Random r = new Random();
    list = new List<int>(length);
    for (int i = 0; i < length; i++) list[i] = r.random();

    int min, max;
    min = max = list[0];
    for (int i = 0; i < length; i++) {
      int e = list[i];
      if (e > max) max = e;
      if (e < min) min = e;
    }

    this.min = min;
    this.max = max;
  }

  void check() {
    List<int> a = list;
    int len = a.length;
    if ((a[0] != min) || a[len - 1] != max) Error.error("List is not sorted");
    for (var i = 1; i < len; i++) {
      if (a[i - 1] > a[i]) Error.error("List is not sorted");
    }
  }
}

// B u b b l e S o r t
class BubbleSort {
  static void sort(List<int> a) {
    int len = a.length;
    for (int i = len - 2; i >= 0; i--) {
      for (int j = 0; j <= i; j++) {
        int c = a[j];
        int n = a[j + 1];
        if (c > n) {
          a[j] = n;
          a[j + 1] = c;
        }
      }
    }
  }
}

class BubbleSortBenchmark extends BenchmarkBase {
  const BubbleSortBenchmark() : super("BubbleSort");

  void warmup() {
    SortData data = new SortData(30);
    BubbleSort.sort(data.list);
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    SortData data = new SortData(130);
    BubbleSort.sort(data.list);
    data.check();
  }

  static void main() {
    new BubbleSortBenchmark().report();
  }
}

// Q u i c k S o r t
class QuickSort {
  static void sort(List<int> a, int low, int high) {
    int pivot = a[(low + high) >> 1];
    int i = low;
    int j = high;
    while (i <= j) {
      while (a[i] < pivot) i++;
      while (pivot < a[j]) j--;
      if (i <= j) {
        int tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
        i++;
        j--;
      }
    }

    if (low < j) sort(a, low, j);
    if (i < high) sort(a, i, high);
  }
}

class QuickSortBenchmark extends BenchmarkBase {
  const QuickSortBenchmark() : super("QuickSort");

  void warmup() {
    SortData data = new SortData(100);
    QuickSort.sort(data.list, 0, data.list.length - 1);
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    SortData data = new SortData(800);
    QuickSort.sort(data.list, 0, data.list.length - 1);
    data.check();
  }

  static void main() {
    new QuickSortBenchmark().report();
  }
}

// T r e e S o r t
class TreeNodePress {
  int value;
  TreeNodePress left;
  TreeNodePress right;

  TreeNodePress(int n) : value = n {}

  void insert(int n) {
    if (n < value) {
      if (left == null)
        left = new TreeNodePress(n);
      else
        left.insert(n);
    } else {
      if (right == null)
        right = new TreeNodePress(n);
      else
        right.insert(n);
    }
  }

  void check() {
    TreeNodePress left = this.left;
    TreeNodePress right = this.right;
    int value = this.value;

    return ((left == null) || ((left.value < value) && left.check())) &&
        ((right == null) || ((right.value >= value) && right.check()));
  }
}

class TreeSort {
  static void sort(List<int> a) {
    int len = a.length;
    TreeNodePress tree = new TreeNodePress(a[0]);
    for (var i = 1; i < len; i++) tree.insert(a[i]);
    if (!tree.check()) Error.error("Invalid result, tree not sorted");
  }
}

class TreeSortBenchmark extends BenchmarkBase {
  const TreeSortBenchmark() : super("TreeSort");

  void warmup() {
    TreeSort.sort(new SortData(100).list);
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    TreeSort.sort(new SortData(1000).list);
  }
}

// T a k
class TakBenchmark extends BenchmarkBase {
  const TakBenchmark() : super("Tak");

  static void tak(int x, int y, int z) {
    if (y >= x) return z;
    return tak(tak(x - 1, y, z), tak(y - 1, z, x), tak(z - 1, x, y));
  }

  void warmup() {
    tak(9, 6, 3);
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    tak(18, 12, 6);
  }

  static void main() {
    new TakBenchmark().report();
  }
}

// T a k l
class ListElement {
  final int length;
  final ListElement next;

  const ListElement(int length, ListElement next)
      : this.length = length,
        this.next = next;

  static ListElement makeList(int length) {
    if (length == 0) return null;
    return new ListElement(length, makeList(length - 1));
  }

  static bool isShorter(ListElement x, ListElement y) {
    ListElement xTail = x;
    ListElement yTail = y;
    while (yTail != null) {
      if (xTail == null) return true;
      xTail = xTail.next;
      yTail = yTail.next;
    }
    return false;
  }
}

class Takl {
  static ListElement takl(ListElement x, ListElement y, ListElement z) {
    if (ListElement.isShorter(y, x)) {
      return takl(takl(x.next, y, z), takl(y.next, z, x), takl(z.next, x, y));
    } else {
      return z;
    }
  }
}

class TaklBenchmark extends BenchmarkBase {
  const TaklBenchmark() : super("Takl");

  void warmup() {
    Takl.takl(ListElement.makeList(8), ListElement.makeList(4),
        ListElement.makeList(3));
  }

  void exercise() {
    // This value has been copied from benchpress.js, so that we can compare
    // performance.
    ListElement result = Takl.takl(ListElement.makeList(15),
        ListElement.makeList(10), ListElement.makeList(6));
    if (result.length != 10) {
      int len = result.length;
      Error.error("Wrong result: $len should be: 10");
    }
  }

  static void main() {
    new TaklBenchmark().report();
  }
}

// M a i n

class BenchPress {
  static void mainWithArgs(List<String> args) {
    List<BenchmarkBase> benchmarks = [
      new BubbleSortBenchmark(),
      new FibBenchmark(),
      new LoopBenchmark(),
      new PermuteBenchmark(),
      new QueensBenchmark(),
      new QuickSortBenchmark(),
      new RecurseBenchmark(),
      new SieveBenchmark(),
      new SumBenchmark(),
      new TakBenchmark(),
      new TaklBenchmark(),
      new TowersBenchmark(),
      new TreeSortBenchmark(),
    ];
    if (args.length > 0) {
      String benchName = args[0];
      bool foundBenchmark = false;
      benchmarks.forEach((bench) {
        if (bench.name == benchName) {
          foundBenchmark = true;
          bench.report();
        }
      });
      if (!foundBenchmark) {
        Error.error("Benchmark not found: $benchName");
      }
      return;
    }
    double logMean = 0.0;
    benchmarks.forEach((bench) {
      double benchScore = bench.measure();
      String name = bench.name;
      print("$name: $benchScore");
      logMean += Math.log(benchScore);
    });
    logMean = logMean / benchmarks.length;
    double score = Math.pow(Math.E, logMean);
    print("BenchPress (average): $score");
  }

  // TODO(floitsch): let main accept arguments from the command line.
  static void main() {
    mainWithArgs([]);
  }
}

class BenchmarkBase {
  final String name;

  // Empty constructor.
  const BenchmarkBase(String name) : this.name = name;

  // The benchmark code.
  // This function is not used, if both [warmup] and [exercise] are overwritten.
  void run() {}

  // Runs a short version of the benchmark. By default invokes [run] once.
  void warmup() {
    run();
  }

  // Exercises the benchmark. By default invokes [run] 10 times.
  void exercise() {
    for (int i = 0; i < 10; i++) {
      run();
    }
  }

  // Not measured setup code executed prior to the benchmark runs.
  void setup() {}

  // Not measures teardown code executed after the benchmark runs.
  void teardown() {}

  // Measures the score for this benchmark by executing it repeately until
  // time minimum has been reached.
  static double measureFor(Function f, int timeMinimum) {
    int time = 0;
    int iter = 0;
    DateTime start = new DateTime.now();
    while (time < timeMinimum) {
      f();
      time = (new DateTime.now().difference(start)).inMilliseconds;
      iter++;
    }
    // Force double result by using a double constant.
    return (1000.0 * iter) / time;
  }

  // Measures the score for the benchmark and returns it.
  double measure() {
    setup();
    // Warmup for at least 100ms. Discard result.
    measureFor(() {
      this.warmup();
    }, -100);
    // Run the benchmark for at least 2000ms.
    double result = measureFor(() {
      this.exercise();
    }, -2000);
    teardown();
    return result;
  }

  void report() {
    double score = measure();
    print("name: $score");
  }
}

class Logger {
  static print(object) {
    printobject(object);
  }

  static printobject(obj) {}
}

//
// Dromaeo ObjectString
// Adapted from Mozilla JavaScript performance test suite.
// Microtests of strings (concatenation, methods).

class ObjectString extends BenchmarkBase {
  const ObjectString() : super("Dromaeo.ObjectString");

  static void main() {
    new ObjectString().report();
  }

  static void print(String str) {
    print(str);
  }

  String getRandomString(int characters) {
    var result = "";
    for (var i = 0; i < characters; i++) {
      result +=
          Strings.createFromCodePoints([(25 * Math.random()).toInt() + 97]);
    }
    result += result;
    result += result;
    return result;
  }

  void run() {
    //JS Dromeaeo uses 16384
    final ITERATE1 = 384;
    //JS Dromeaeo uses 80000
    final ITERATE2 = 80;
    //JS Dromeaeo uses 5000
    final ITERATE3 = 50;
    //JS Dromeaeo uses 5000
    final ITERATE4 = 1;
    //JS Dromaeo uses 5000
    final ITERATE5 = 1000;

    var result;
    var text = getRandomString(ITERATE1);

    ConcatStringBenchmark.test(ITERATE2);
    ConcatStringFromCharCodeBenchmark.test(ITERATE2);
    StringSplitBenchmark.test(text);
    StringSplitOnCharBenchmark.test(text);
    text += text;
    CharAtBenchmark.test(text, ITERATE3);
    NumberBenchmark.test(text, ITERATE3);
    CodeUnitAtBenchmark.test(text, ITERATE3);
    IndexOfBenchmark.test(text, ITERATE3);
    LastIndexOfBenchmark.test(text, ITERATE3);
    SliceBenchmark.test(text, ITERATE4);
    SubstrBenchmark.test(text, ITERATE4);
    SubstringBenchmark.test(text, ITERATE4);
    ToLowerCaseBenchmark.test(text, ITERATE5);
    ToUpperCaseBenchmark.test(text, ITERATE5);
    ComparingBenchmark.test(text, ITERATE5);
  }
}

class ConcatStringBenchmark {
  ConcatStringBenchmark() {}

  static String test(var iterations) {
    var str = "";
    for (var i = 0; i < iterations; i++) {
      str += "a";
    }
    return str;
  }
}

class ConcatStringFromCharCodeBenchmark {
  ConcatStringFromCharCodeBenchmark() {}

  static String test(var iterations) {
    var str = "";
    for (var i = 0; i < (iterations / 2); i++) {
      str += Strings.createFromCodePoints([97]);
    }
    return str;
  }
}

class StringSplitBenchmark {
  StringSplitBenchmark() {}

  static List<String> test(String input) {
    return input.split("");
  }
}

class StringSplitOnCharBenchmark {
  StringSplitOnCharBenchmark() {}

  static List<String> test(String input) {
    String multiple = input;
    multiple += multiple;
    multiple += multiple;
    multiple += multiple;
    multiple += multiple;
    return multiple.split("a");
  }
}

class CharAtBenchmark {
  CharAtBenchmark() {}

  static String test(String input, var iterations) {
    var str;
    for (var j = 0; j < iterations; j++) {
      str = input[0];
      str = input[input.length - 1];
      str = input[150]; //set it to 15000
      str = input[120]; //set it to 12000
    }
    return str;
  }
}

class NumberBenchmark {
  NumberBenchmark() {}

  static String test(String input, var iterations) {
    var str;
    for (var j = 0; j < iterations; j++) {
      str = input[0];
      str = input[input.length - 1];
      str = input[150]; //set it to 15000
      str = input[100]; //set it to 10000
      str = input[50]; //set it to 5000
    }
    return str;
  }
}

class CodeUnitAtBenchmark {
  CodeUnitAtBenchmark() {}

  static String test(String input, var iterations) {
    var str;
    for (var j = 0; j < iterations; j++) {
      str = input.codeUnitAt(0);
      str = input.codeUnitAt(input.length - 1);
      str = input.codeUnitAt(150); //set it to 15000
      str = input.codeUnitAt(100); //set it to 10000
      str = input.codeUnitAt(50); //set it to 5000
    }
    return str;
  }
}

class IndexOfBenchmark {
  IndexOfBenchmark() {}

  static String test(String input, var iterations) {
    var str;
    for (var j = 0; j < iterations; j++) {
      str = input.indexOf("a", 0);
      str = input.indexOf("b", 0);
      str = input.indexOf("c", 0);
      str = input.indexOf("d", 0);
    }
    return str;
  }
}

class LastIndexOfBenchmark {
  LastIndexOfBenchmark() {}

  static String test(String input, var iterations) {
    var str;
    for (var j = 0; j < iterations; j++) {
      str = input.lastIndexOf("a", input.length - 1);
      str = input.lastIndexOf("b", input.length - 1);
      str = input.lastIndexOf("c", input.length - 1);
      str = input.lastIndexOf("d", input.length - 1);
    }
    return str;
  }
}

class SliceBenchmark {
  SliceBenchmark() {}

  static String test(String input, var iterations) {
    var str;
    for (var j = 0; j < iterations; j++) {
      str = input.substring(0, input.length - 1);
      str = input.substring(0, 5);
      str = input.substring(input.length - 1, input.length - 1);
      str = input.substring(input.length - 6, input.length - 1);
      str = input.substring(150, 155); //set to 15000 and 15005
      str = input.substring(120, input.length - 1); //set to 12000
    }
    return str;
  }
}

class SubstrBenchmark {
  SubstrBenchmark() {}

  static String test(String input, var iterations) {
    var str;
    for (var j = 0; j < iterations; j++) {
      str = input.substring(0, input.length - 1);
      str = input.substring(0, 4);
      str = input.substring(input.length - 1, input.length - 1);
      str = input.substring(input.length - 6, input.length - 6);
      str = input.substring(150, 154); //set to 15000 and 15005
      str = input.substring(120, 124); //set to 12000
    }
    return str;
  }
}

class SubstringBenchmark {
  SubstringBenchmark() {}

  static String test(String input, var iterations) {
    var str;
    for (var j = 0; j < iterations; j++) {
      str = input.substring(0, input.length - 1);
      str = input.substring(0, 4);
      str = input.substring(input.length - 1, input.length - 1);
      str = input.substring(input.length - 6, input.length - 2);
      str = input.substring(150, 154); //set to 15000 and 15005
      str = input.substring(120, input.length - 2); //set to 12000
    }
    return str;
  }
}

class ToLowerCaseBenchmark {
  ToLowerCaseBenchmark() {}

  static String test(String input, var iterations) {
    var str;
    for (var j = 0; j < (iterations / 1000); j++) {
      str = Ascii.toLowerCase(input);
    }
    return str;
  }
}

class ToUpperCaseBenchmark {
  ToUpperCaseBenchmark() {}

  static String test(String input, var iterations) {
    var str;
    for (var j = 0; j < (iterations / 1000); j++) {
      str = Ascii.toUpperCase(input);
    }
    return str;
  }
}

class ComparingBenchmark {
  ComparingBenchmark() {}

  static bool test(String input, var iterations) {
    var tmp = "a${input}a";
    var tmp2 = "a${input}a";
    var res;
    for (var j = 0; j < (iterations / 1000); j++) {
      res = (tmp.compareTo(tmp2) == 0);
      res = (tmp.compareTo(tmp2) < 0);
      res = (tmp.compareTo(tmp2) > 0);
    }
    return res;
  }
}

// Benchmarks basic message communication between two isolates.

class Benchmark1 {
  static const MESSAGES = 10000;
  static const INIT_MESSAGE = 0;
  static const TERMINATION_MESSAGE = -1;
  static const WARMUP_TIME = 1000;
  static const RUN_TIME = 1000;
  static const RUNS = 5;

  static int run() {
    return _run;
  }

  static void add_result(var opsms) {
    _run++;
    _opsms += opsms;
  }

  static void get_result() {
    return _opsms / _run;
  }

  static void init() {
    _run = 0;
    _opsms = 0.0;
  }

  static void main() {
    init();
    PingPongGame pingPongGame = new PingPongGame();
  }

  static var _run;
  static var _opsms;
}

class PingPongGame {
  PingPongGame()
      : _ping = new ReceivePort(),
        _pingPort = _ping.toSendPort(),
        _pong = null,
        _warmedup = false,
        _iterations = 0 {
    SendPort _pong = spawnFunction(pong);
    play();
  }

  void startRound() {
    _iterations++;
    _pong.send(Benchmark1.INIT_MESSAGE, _pingPort);
  }

  void evaluateRound() {
    int time = (new DateTime.now().difference(_start)).inMilliseconds;
    if (!_warmedup && time < Benchmark1.WARMUP_TIME) {
      startRound();
    } else if (!_warmedup) {
      _warmedup = true;
      _start = new DateTime.now();
      _iterations = 0;
      startRound();
    } else if (_warmedup && time < Benchmark1.RUN_TIME) {
      startRound();
    } else {
      shutdown();
      Benchmark1.add_result((1.0 * _iterations * Benchmark1.MESSAGES) / time);
      if (Benchmark1.run() < Benchmark1.RUNS) {
        new PingPongGame();
      } else {
        print("PingPong: ", Benchmark1.get_result());
      }
    }
  }

  void play() {
    _ping.receive((int message, SendPort replyTo) {
      if (message < Benchmark1.MESSAGES) {
        _pong.send(++message, null);
      } else {
        evaluateRound();
      }
    });
    _start = new DateTime.now();
    startRound();
  }

  void shutdown() {
    _pong.send(Benchmark1.TERMINATION_MESSAGE, null);
    _ping.close();
  }

  DateTime _start;
  SendPort _pong;
  SendPort _pingPort;
  ReceivePort _ping;
  bool _warmedup;
  int _iterations;
}

void pong() {
  port.receive((message, SendPort replyTo) {
    if (message == Benchmark1.INIT_MESSAGE) {
      replyTo.send(message, null);
    } else if (message == Benchmark1.TERMINATION_MESSAGE) {
      port.close();
    } else {
      replyTo.send(message, null);
    }
  });
}

class ManyGenericInstanceofTest {
  static testMain() {
    for (int i = 0; i < 5000; i++) {
      GenericInstanceof.testMain();
    }
  }
}

// ---------------------------------------------------------------------------
// THE REST OF THIS FILE COULD BE AUTOGENERATED
// ---------------------------------------------------------------------------

// ---------------------------------------------------------------------------
// tests/isolate/spawn_test.dart
// ---------------------------------------------------------------------------

spawn_test_main() {
  test("spawn a new isolate", () {
    SendPort port = spawnFunction(entry);
    port.call(42).then(expectAsync1((message) {
      Expect.equals(42, message);
    }));
  });
}

void entry() {
  port.receive((message, SendPort replyTo) {
    Expect.equals(42, message);
    replyTo.send(42, null);
    port.close();
  });
}

// ---------------------------------------------------------------------------
// tests/isolate/isolate_negative_test.dart
// ---------------------------------------------------------------------------

void isolate_negative_entry() {
  port.receive((ignored, replyTo) {
    replyTo.send("foo", null);
  });
}

isolate_negative_test_main() {
  test("ensure isolate code is executed", () {
    SendPort port = spawnFunction(isolate_negative_entry);
    port.call("foo").then(expectAsync1((message) {
      Expect.equals(true, "Expected fail"); // <=-------- Should fail here.
    }));
  });
}

// ---------------------------------------------------------------------------
// tests/isolate/message_test.dart
// ---------------------------------------------------------------------------

// ---------------------------------------------------------------------------
// Message passing test.
// ---------------------------------------------------------------------------

class MessageTest {
  static const List list1 = const ["Hello", "World", "Hello", 0xfffffffffff];
  static const List list2 = const [null, list1, list1, list1, list1];
  static const List list3 = const [list2, 2.0, true, false, 0xfffffffffff];
  static const Map map1 = const {
    "a=1": 1,
    "b=2": 2,
    "c=3": 3,
  };
  static const Map map2 = const {
    "list1": list1,
    "list2": list2,
    "list3": list3,
  };
  static const List list4 = const [map1, map2];
  static const List elms = const [
    list1,
    list2,
    list3,
    list4,
  ];

  static void VerifyMap(Map expected, Map actual) {
    Expect.equals(true, expected is Map);
    Expect.equals(true, actual is Map);
    Expect.equals(expected.length, actual.length);
    testForEachMap(key, value) {
      if (value is List) {
        VerifyList(value, actual[key]);
      } else {
        Expect.equals(value, actual[key]);
      }
    }

    expected.forEach(testForEachMap);
  }

  static void VerifyList(List expected, List actual) {
    for (int i = 0; i < expected.length; i++) {
      if (expected[i] is List) {
        VerifyList(expected[i], actual[i]);
      } else if (expected[i] is Map) {
        VerifyMap(expected[i], actual[i]);
      } else {
        Expect.equals(expected[i], actual[i]);
      }
    }
  }

  static void VerifyObject(int index, var actual) {
    var expected = elms[index];
    Expect.equals(true, expected is List);
    Expect.equals(true, actual is List);
    Expect.equals(expected.length, actual.length);
    VerifyList(expected, actual);
  }
}

pingPong() {
  int count = 0;
  port.receive((var message, SendPort replyTo) {
    if (message == -1) {
      port.close();
      replyTo.send(count, null);
    } else {
      // Check if the received object is correct.
      if (count < MessageTest.elms.length) {
        MessageTest.VerifyObject(count, message);
      }
      // Bounce the received object back so that the sender
      // can make sure that the object matches.
      replyTo.send(message, null);
      count++;
    }
  });
}

message_test_main() {
  test("send objects and receive them back", () {
    SendPort remote = spawnFunction(pingPong);
    // Send objects and receive them back.
    for (int i = 0; i < MessageTest.elms.length; i++) {
      var sentObject = MessageTest.elms[i];
      remote.call(sentObject).then(expectAsync1((var receivedObject) {
        MessageTest.VerifyObject(i, receivedObject);
      }));
    }

    // Send recursive objects and receive them back.
    List local_list1 = ["Hello", "World", "Hello", 0xffffffffff];
    List local_list2 = [null, local_list1, local_list1];
    List local_list3 = [local_list2, 2.0, true, false, 0xffffffffff];
    List sendObject = new List(5);
    sendObject[0] = local_list1;
    sendObject[1] = sendObject;
    sendObject[2] = local_list2;
    sendObject[3] = sendObject;
    sendObject[4] = local_list3;
    remote.call(sendObject).then((var replyObject) {
      Expect.equals(true, sendObject is List);
      Expect.equals(true, replyObject is List);
      Expect.equals(sendObject.length, replyObject.length);
      Expect.equals(true, identical(replyObject[1], replyObject));
      Expect.equals(true, identical(replyObject[3], replyObject));
      Expect.equals(true, identical(replyObject[0], replyObject[2][1]));
      Expect.equals(true, identical(replyObject[0], replyObject[2][2]));
      Expect.equals(true, identical(replyObject[2], replyObject[4][0]));
      Expect.equals(true, identical(replyObject[0][0], replyObject[0][2]));
      // TODO(alexmarkov): Revise this comment.
      // Bigint literals are not canonicalized so do a == check.
      Expect.equals(true, replyObject[0][3] == replyObject[4][4]);
    });

    // Shutdown the MessageServer.
    remote.call(-1).then(expectAsync1((int message) {
      Expect.equals(MessageTest.elms.length + 1, message);
    }));
  });
}

// ---------------------------------------------------------------------------
// tests/isolate/request_reply_test.dart
// ---------------------------------------------------------------------------

void request_reply_entry() {
  port.receive((message, SendPort replyTo) {
    replyTo.send(message + 87);
    port.close();
  });
}

void request_reply_main() {
  test("call", () {
    SendPort port = spawnFunction(request_reply_entry);
    port.call(42).then(expectAsync1((message) {
      Expect.equals(42 + 87, message);
    }));
  });

  test("send", () {
    SendPort port = spawnFunction(request_reply_entry);
    ReceivePort reply = new ReceivePort();
    port.send(99, reply.toSendPort());
    reply.receive(expectAsync2((message, replyTo) {
      Expect.equals(99 + 87, message);
      reply.close();
    }));
  });
}

// ---------------------------------------------------------------------------
// tests/isolate/count_test.dart
// ---------------------------------------------------------------------------

void countMessages() {
  int count = 0;
  port.receive((int message, SendPort replyTo) {
    if (message == -1) {
      Expect.equals(10, count);
      replyTo.send(-1, null);
      port.close();
      return;
    }
    Expect.equals(count, message);
    count++;
    replyTo.send(message * 2, null);
  });
}

void count_main() {
  test("count 10 consecutive messages", () {
    int count = 0;
    SendPort remote = spawnFunction(countMessages);
    ReceivePort local = new ReceivePort();
    SendPort reply = local.toSendPort();

    local.receive(expectAsync2((int message, SendPort replyTo) {
      if (message == -1) {
        Expect.equals(11, count);
        local.close();
        return;
      }

      Expect.equals((count - 1) * 2, message);
      remote.send(count++, reply);
      if (count == 10) {
        remote.send(-1, reply);
      }
    }, 11));
    remote.send(count++, reply);
  });
}

// ---------------------------------------------------------------------------
// tests/isolate/mandel_isolate_test.dart
// ---------------------------------------------------------------------------

const TERMINATION_MESSAGE = -1;
const N = 100;
const ISOLATES = 20;

mandel_main() {
  test("Render Mandelbrot in parallel", () {
    final state = new MandelbrotState();
    state._validated.future.then(expectAsync1((result) {
      expect(result, isTrue);
    }));
    for (int i = 0; i < Math.min(ISOLATES, N); i++) state.startClient(i);
  });
}

class MandelbrotState {
  MandelbrotState() {
    _result = new List<List<int>>(N);
    _lineProcessedBy = new List<LineProcessorClient>(N);
    _sent = 0;
    _missing = N;
    _validated = new Completer<bool>();
  }

  void startClient(int id) {
    assert(_sent < N);
    final client = new LineProcessorClient(this, id);
    client.processLine(_sent++);
  }

  void notifyProcessedLine(LineProcessorClient client, int y, List<int> line) {
    assert(_result[y] == null);
    _result[y] = line;
    _lineProcessedBy[y] = client;

    if (_sent != N) {
      client.processLine(_sent++);
    } else {
      client.shutdown();
    }

    // If all lines have been computed, validate the result.
    if (--_missing == 0) {
      _printResult();
      _validateResult();
    }
  }

  void _validateResult() {
    // TODO(ngeoffray): Implement this.
    _validated.complete(true);
  }

  void _printResult() {
    var output = new StringBuffer();
    for (int i = 0; i < _result.length; i++) {
      List<int> line = _result[i];
      for (int j = 0; j < line.length; j++) {
        if (line[j] < 10) output.write("0");
        output.write(line[j]);
      }
      output.write("\n");
    }
    // print(output);
  }

  List<List<int>> _result;
  List<LineProcessorClient> _lineProcessedBy;
  int _sent;
  int _missing;
  Completer<bool> _validated;
}

class LineProcessorClient {
  LineProcessorClient(MandelbrotState this._state, int this._id) {
    _port = spawnFunction(processLines);
  }

  void processLine(int y) {
    _port.call(y).then((List<int> message) {
      _state.notifyProcessedLine(this, y, message);
    });
  }

  void shutdown() {
    _port.send(TERMINATION_MESSAGE, null);
  }

  MandelbrotState _state;
  int _id;
  SendPort _port;
}

List<int> processLine(int y) {
  double inverseN = 2.0 / N;
  double Civ = y * inverseN - 1.0;
  List<int> result = new List<int>(N);
  for (int x = 0; x < N; x++) {
    double Crv = x * inverseN - 1.5;

    double Zrv = Crv;
    double Ziv = Civ;

    double Trv = Crv * Crv;
    double Tiv = Civ * Civ;

    int i = 49;
    do {
      Ziv = (Zrv * Ziv) + (Zrv * Ziv) + Civ;
      Zrv = Trv - Tiv + Crv;

      Trv = Zrv * Zrv;
      Tiv = Ziv * Ziv;
    } while (((Trv + Tiv) <= 4.0) && (--i > 0));

    result[x] = i;
  }
  return result;
}

void processLines() {
  port.receive((message, SendPort replyTo) {
    if (message == TERMINATION_MESSAGE) {
      assert(replyTo == null);
      port.close();
    } else {
      replyTo.send(processLine(message), null);
    }
  });
}
