| Index: tests/isolate/mint_maker_test.dart
 | 
| diff --git a/tests/isolate/mint_maker_test.dart b/tests/isolate/mint_maker_test.dart
 | 
| index 90ad0584cbabcaff22dc24a929770ef8977e183b..457a42a62767e7c162d04024c18c057d8cdd9336 100644
 | 
| --- a/tests/isolate/mint_maker_test.dart
 | 
| +++ b/tests/isolate/mint_maker_test.dart
 | 
| @@ -2,117 +2,84 @@
 | 
|  // 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.
 | 
|  
 | 
| -// Things that should be "auto-generated" are between AUTO START and
 | 
| -// AUTO END (or just AUTO if it's a single line).
 | 
| -
 | 
|  library MintMakerTest;
 | 
|  import 'dart:isolate';
 | 
|  import '../../pkg/unittest/lib/unittest.dart';
 | 
|  
 | 
|  class Mint {
 | 
| -  Mint() : registry_ = new Map<SendPort, Purse>() {
 | 
| -    // AUTO START
 | 
| +  Map<SendPort, Purse> _registry;
 | 
| +  SendPort port;
 | 
| +
 | 
| +  Mint() : _registry = new Map<SendPort, Purse>() {
 | 
|      ReceivePort mintPort = new ReceivePort();
 | 
| -    port = mintPort.toSendPort();
 | 
| +    port = mintPort.sendPort;
 | 
|      serveMint(mintPort);
 | 
| -    // AUTO END
 | 
|    }
 | 
|  
 | 
| -  // AUTO START
 | 
|    void serveMint(ReceivePort port) {
 | 
| -    port.receive((var message, SendPort replyTo) {
 | 
| -      int balance = message;
 | 
| +    port.listen((message) {
 | 
| +      int balance = message[0];
 | 
|        Purse purse = createPurse(balance);
 | 
| -      replyTo.send([ purse.port ], null);
 | 
| +      message[1].send(purse.port);
 | 
|      });
 | 
|    }
 | 
| -  // AUTO END
 | 
|  
 | 
|    Purse createPurse(int balance) {
 | 
|      Purse purse = new Purse(this, balance);
 | 
| -    registry_[purse.port] = purse;
 | 
| +    _registry[purse.port] = purse;
 | 
|      return purse;
 | 
|    }
 | 
|  
 | 
|    Purse lookupPurse(SendPort port) {
 | 
| -    return registry_[port];
 | 
| +    return _registry[port];
 | 
|    }
 | 
| -
 | 
| -  Map<SendPort, Purse> registry_;
 | 
| -  // AUTO
 | 
| -  SendPort port;
 | 
|  }
 | 
|  
 | 
|  
 | 
| -// AUTO START
 | 
|  class MintWrapper {
 | 
| -  MintWrapper(SendPort this.mint_) {}
 | 
| +  SendPort _mint;
 | 
| +  MintWrapper(SendPort this._mint) {}
 | 
|  
 | 
|    void createPurse(int balance, handlePurse(PurseWrapper purse)) {
 | 
| -    mint_.call(balance).then((var message) {
 | 
| -      SendPort purse = message[0];
 | 
| +    ReceivePort reply = new ReceivePort();
 | 
| +    reply.first.then((SendPort purse) {
 | 
|        handlePurse(new PurseWrapper(purse));
 | 
|      });
 | 
| +    _mint.send([balance, reply.sendPort]);
 | 
|    }
 | 
|  
 | 
| -  SendPort mint_;
 | 
| -}
 | 
| -// AUTO END
 | 
| -
 | 
| -
 | 
| -/*
 | 
| -One way this could look without the autogenerated code:
 | 
| -
 | 
| -class Mint {
 | 
| -  Mint() : registry_ = new Map<SendPort, Purse>() {
 | 
| -  }
 | 
| -
 | 
| -  wrap Purse createPurse(int balance) {
 | 
| -    Purse purse = new Purse(this, balance);
 | 
| -    registry_[purse.port] = purse;
 | 
| -    return purse;
 | 
| -  }
 | 
| -
 | 
| -  Purse lookupPurse(SendPort port) {
 | 
| -    return registry_[port];
 | 
| -  }
 | 
| -
 | 
| -  Map<SendPort, Purse> registry_;
 | 
|  }
 | 
|  
 | 
| -The other end of the port would use Wrapper<Mint> as the wrapper, or
 | 
| -Future<Mint> as a future for the wrapper.
 | 
| -*/
 | 
| -
 | 
| -
 | 
|  class Purse {
 | 
| -  Purse(Mint this.mint, int this.balance) {
 | 
| -    // AUTO START
 | 
| +  Mint mint;
 | 
| +  int balance;
 | 
| +  SendPort port;
 | 
| +
 | 
| +  Purse(this.mint, this.balance) {
 | 
|      ReceivePort recipient = new ReceivePort();
 | 
| -    port = recipient.toSendPort();
 | 
| +    port = recipient.sendPort;
 | 
|      servePurse(recipient);
 | 
| -    // AUTO END
 | 
|    }
 | 
|  
 | 
| -  // AUTO START
 | 
|    void servePurse(ReceivePort recipient) {
 | 
| -    recipient.receive((var message, SendPort replyTo) {
 | 
| +    recipient.listen((message) {
 | 
|        String command = message[0];
 | 
|        if (command == "balance") {
 | 
| -        replyTo.send(queryBalance(), null);
 | 
| +        SendPort replyTo = message.last;
 | 
| +        replyTo.send(queryBalance());
 | 
|        } else if (command == "deposit") {
 | 
|          Purse source = mint.lookupPurse(message[2]);
 | 
|          deposit(message[1], source);
 | 
|        } else if (command == "sprout") {
 | 
| +        SendPort replyTo = message.last;
 | 
|          Purse result = sproutPurse();
 | 
| -        replyTo.send([ result.port ], null);
 | 
| +        replyTo.send(result.port);
 | 
|        } else {
 | 
|          // TODO: Send an exception back.
 | 
| -        replyTo.send("Exception: Command not understood", null);
 | 
| +        throw UnsupportedError("Unsupported commend: $command");
 | 
|        }
 | 
|      });
 | 
|    }
 | 
| -  // AUTO END
 | 
|  
 | 
|    int queryBalance() { return balance; }
 | 
|  
 | 
| @@ -124,64 +91,60 @@ class Purse {
 | 
|      balance += amount;
 | 
|      source.balance -= amount;
 | 
|    }
 | 
| -
 | 
| -  Mint mint;
 | 
| -  int balance;
 | 
| -  // AUTO
 | 
| -  SendPort port;
 | 
|  }
 | 
|  
 | 
|  
 | 
| -// AUTO START
 | 
|  class PurseWrapper {
 | 
| -  PurseWrapper(SendPort this.purse_) {}
 | 
| +  SendPort _purse;
 | 
| +
 | 
| +  PurseWrapper(this._purse) {}
 | 
| +
 | 
| +  void _sendReceive(message, replyHandler(reply)) {
 | 
| +    ReceivePort reply = new ReceivePort();
 | 
| +    _purse.send([message, reply.sendPort]);
 | 
| +    reply.first.then(replyHandler);
 | 
| +  }
 | 
|  
 | 
|    void queryBalance(handleBalance(int balance)) {
 | 
| -    purse_.call([ "balance" ]).then((var message) {
 | 
| -      int balance = message;
 | 
| -      handleBalance(balance);
 | 
| -    });
 | 
| +    _sendReceive("balance", handleBalance);
 | 
|    }
 | 
|  
 | 
|    void sproutPurse(handleSprouted(PurseWrapper sprouted)) {
 | 
| -    purse_.call([ "sprout" ]).then((var message) {
 | 
| -      SendPort sprouted = message[0];
 | 
| +    _sendReceive("sprout", (SendPort sprouted) {
 | 
|        handleSprouted(new PurseWrapper(sprouted));
 | 
|      });
 | 
|    }
 | 
|  
 | 
|    void deposit(PurseWrapper source, int amount) {
 | 
| -    purse_.send([ "deposit", amount, source.purse_ ], null);
 | 
| +    _purse.send([ "deposit", amount, source._purse ]);
 | 
|    }
 | 
| -
 | 
| -
 | 
| -  SendPort purse_;
 | 
|  }
 | 
| -// AUTO END
 | 
| -
 | 
|  
 | 
| -// AUTO STATUS UNCLEAR!
 | 
| -
 | 
| -mintMakerWrapper() {
 | 
| -  port.receive((var message, SendPort replyTo) {
 | 
| +mintMakerWrapper(SendPort replyPort) {
 | 
| +  ReceivePort receiver = new ReceivePort();
 | 
| +  replyPort.send(receiver.sendPort);
 | 
| +  receiver.listen((SendPort replyTo) {
 | 
|      Mint mint = new Mint();
 | 
| -    replyTo.send([ mint.port ], null);
 | 
| +    replyTo.send(mint.port);
 | 
|    });
 | 
|  }
 | 
|  
 | 
|  class MintMakerWrapper {
 | 
| -  MintMakerWrapper() {
 | 
| -    port_ = spawnFunction(mintMakerWrapper);
 | 
| +  final SendPort _port;
 | 
| +
 | 
| +  static Future<MintMakerWrapper> create() {
 | 
| +    ReceivePort reply = new ReceivePort();
 | 
| +    return Isolate.spawn(mintMakerWrapper, reply.sendPort).then((_) =>
 | 
| +        reply.first.then((port) => new MintMakerWrapper._(port)));
 | 
|    }
 | 
|  
 | 
| +  MintMakerWrapper._(this._port);
 | 
| +
 | 
|    void makeMint(handleMint(MintWrapper mint)) {
 | 
| -    port_.call(null).then((var message) {
 | 
| -      SendPort mint = message[0];
 | 
| -      handleMint(new MintWrapper(mint));
 | 
| -    });
 | 
| +    ReceivePort reply = new ReceivePort();
 | 
| +    reply.first.then((SendPort mint) { handleMint(new MintWrapper(mint)); });
 | 
| +    _port.send(reply.sendPort);
 | 
|    }
 | 
| -
 | 
| -  SendPort port_;
 | 
|  }
 | 
|  
 | 
|  _checkBalance(PurseWrapper wrapper, expected) {
 | 
| @@ -192,70 +155,24 @@ _checkBalance(PurseWrapper wrapper, expected) {
 | 
|  
 | 
|  main() {
 | 
|    test("creating purse, deposit, and query balance", () {
 | 
| -    MintMakerWrapper mintMaker = new MintMakerWrapper();
 | 
| -    mintMaker.makeMint(expectAsync1((MintWrapper mint) {
 | 
| -      mint.createPurse(100, expectAsync1((PurseWrapper purse) {
 | 
| -        _checkBalance(purse, 100);
 | 
| -        purse.sproutPurse(expectAsync1((PurseWrapper sprouted) {
 | 
| -          _checkBalance(sprouted, 0);
 | 
| +    MintMakerWrapper.create().then(expectAsync1((mintMaker) {
 | 
| +      mintMaker.makeMint(expectAsync1((MintWrapper mint) {
 | 
| +        mint.createPurse(100, expectAsync1((PurseWrapper purse) {
 | 
|            _checkBalance(purse, 100);
 | 
| -
 | 
| -          sprouted.deposit(purse, 5);
 | 
| -          _checkBalance(sprouted, 0 + 5);
 | 
| -          _checkBalance(purse, 100 - 5);
 | 
| -
 | 
| -          sprouted.deposit(purse, 42);
 | 
| -          _checkBalance(sprouted, 0 + 5 + 42);
 | 
| -          _checkBalance(purse, 100 - 5 - 42);
 | 
| +          purse.sproutPurse(expectAsync1((PurseWrapper sprouted) {
 | 
| +            _checkBalance(sprouted, 0);
 | 
| +            _checkBalance(purse, 100);
 | 
| +
 | 
| +            sprouted.deposit(purse, 5);
 | 
| +            _checkBalance(sprouted, 0 + 5);
 | 
| +            _checkBalance(purse, 100 - 5);
 | 
| +
 | 
| +            sprouted.deposit(purse, 42);
 | 
| +            _checkBalance(sprouted, 0 + 5 + 42);
 | 
| +            _checkBalance(purse, 100 - 5 - 42);
 | 
| +          }));
 | 
|          }));
 | 
|        }));
 | 
|      }));
 | 
|    });
 | 
| -
 | 
| -  /* This is an attempt to show how the above code could look like if we had
 | 
| -   * better language support for asynchronous messages (deferred/asynccall).
 | 
| -   * The static helper methods like createPurse and queryBalance would also
 | 
| -   * have to be marked async.
 | 
| -
 | 
| -  void run(port) {
 | 
| -    MintMakerWrapper mintMaker = spawnMintMaker();
 | 
| -    deferred {
 | 
| -      MintWrapper mint = asynccall mintMaker.createMint();
 | 
| -      PurseWrapper purse = asynccall mint.createPurse(100);
 | 
| -      expect(asynccall purse.queryBalance(), 100);
 | 
| -
 | 
| -      PurseWrapper sprouted = asynccall purse.sproutPurse();
 | 
| -      expect(asynccall sprouted.queryBalance(), 0);
 | 
| -
 | 
| -      asynccall sprouted.deposit(purse, 5);
 | 
| -      expect(asynccall sprouted.queryBalance(), 0 + 5);
 | 
| -      expect(asynccall purse.queryBalance(), 100 - 5);
 | 
| -
 | 
| -      asynccall sprouted.deposit(purse, 42);
 | 
| -      expect(asynccall sprouted.queryBalance(), 0 + 5 + 42);
 | 
| -      expect(asynccall purse.queryBalance(), 100 - 5 - 42);
 | 
| -    }
 | 
| -  }
 | 
| -  */
 | 
| -
 | 
| -  /* And a version using futures and wrappers.
 | 
| -
 | 
| -  void run(port) {
 | 
| -    Wrapper<MintMaker> mintMaker = spawnMintMaker();
 | 
| -    Future<Mint> mint = mintMaker...createMint();
 | 
| -    Future<Purse> purse = mint...createPurse(100);
 | 
| -    expect(purse.queryBalance(), 100);
 | 
| -
 | 
| -    Future<Purse> sprouted = purse...sproutPurse();
 | 
| -    expect(0, sprouted.queryBalance());
 | 
| -
 | 
| -    sprouted...deposit(purse, 5);
 | 
| -    expect(sprouted.queryBalance(), 0 + 5);
 | 
| -    expect(purse.queryBalance(), 100 - 5);
 | 
| -
 | 
| -    sprouted...deposit(purse, 42);
 | 
| -    expect(sprouted.queryBalance(), 0 + 5 + 42);
 | 
| -    expect(purse.queryBalance(), 100 - 5 - 42);
 | 
| -  }
 | 
| -  */
 | 
|  }
 | 
| 
 |