anchor.diff:  testLoopbackMulticast() {
     test(bindAddress, multicastAddress, enabled) {
       asyncStart();
  -    Future.wait([RawDatagramSocket.bind(bindAddress, 0),
  -                 RawDatagramSocket.bind(bindAddress, 0)]).then((values) {
  -      var senderTimer;
  -      var sender = values[0];
  -      var receiver = values[1];
  -
  -      sender.joinMulticast(multicastAddress);
  -      receiver.joinMulticast(multicastAddress);
  -      // On Windows at least the receiver needs to have multicast
  -      // loop enabled whereas on Linux at least the sender needs to.
  -      receiver.multicastLoopback = enabled;
  -      sender.multicastLoopback = enabled;
  -
  -      receiver.listen((event) {
  -        if (event == RawSocketEvent.READ) {
  -          Expect.isTrue(enabled);
  -          sender.close();
  -          receiver.close();
  -          senderTimer.cancel();
  -          asyncEnd();
  +    Future.wait([
  +        RawDatagramSocket.bind(bindAddress, 0, reuseAddress: false),
  +        RawDatagramSocket.bind(bindAddress, 0, reuseAddress: false)])
  +      .then((values) {
  +        var senderTimer;
  +        var sender = values[0];
  +        var receiver = values[1];
  +
  +        sender.joinMulticast(multicastAddress);
  +        receiver.joinMulticast(multicastAddress);
  +        // On Windows at least the receiver needs to have multicast
  +        // loop enabled whereas on Linux at least the sender needs to.
  +        receiver.multicastLoopback = enabled;
  +        sender.multicastLoopback = enabled;
  +
  +        receiver.listen((event) {
  +          if (event == RawSocketEvent.READ) {
  +            if (!enabled) {
  +              var data = receiver.receive();
  +              print(data.port);
  +              print(data.address);
  +            }
  +            Expect.isTrue(enabled);
  +            sender.close();
  +            receiver.close();
  +            senderTimer.cancel();
  +            asyncEnd();
  +          }
  +        });
  +
  +        int sendCount = 0;
  +        send(_) {
  +          int bytes =
  +              sender.send(new Uint8List(1), multicastAddress, receiver.port);
  +          Expect.isTrue(bytes == 0 || bytes == 1);
  +          sendCount++;
  +          if (!enabled && sendCount == 50) {
  +            sender.close();
  +            receiver.close();
  +            senderTimer.cancel();
  +            asyncEnd();
  +          }
           }
  +        senderTimer = new Timer.periodic(new Duration(milliseconds: 10), send);
         });
  -
  -      int sendCount = 0;
  -      send(_) {
  -        int bytes =
  -            sender.send(new Uint8List(1), multicastAddress, receiver.port);
  -        Expect.isTrue(bytes == 0 || bytes == 1);
  -        sendCount++;
  -        if (!enabled && sendCount == 50) {
  -          sender.close();
  -          receiver.close();
  -          senderTimer.cancel();
  -          asyncEnd();
  -        }
  -      }
  -      senderTimer = new Timer.periodic(new Duration(milliseconds: 10), send);
  -    });
     }
   
     test(InternetAddress.ANY_IP_V4, new InternetAddress("228.0.0.4"), true);
  
positive.code:   var ackSeq = 0;
    Timer ackTimer;
  
    Future.wait([RawDatagramSocket.bind(bindAddress, 0),
                 RawDatagramSocket.bind(bindAddress, 0)]).then((values) {
    var sender = values[0];
    var receiver = values[1];
    if (bindAddress.isMulticast) {
      sender.multicastLoopback = true;
      receiver.multicastLoopback = true;
      sender.joinMulticast(bindAddress);
      receiver.joinMulticast(bindAddress);
    }
  
    Uint8List createDataPackage(int seq) {
      var data = new Uint8List(1000);
      (new ByteData.view(data.buffer, 0, 4)).setUint32(0, seq);
      return data;
    }
  
    Uint8List createAckPackage(int seq) {
      var data = new Uint8List(4);
      new ByteData.view(data.buffer, 0, 4).setUint32(0, seq);
      return data;
    }
  
    int packageSeq(Datagram datagram) =>
        new ByteData.view((datagram.data as Uint8List).buffer).getUint32(0);
  
    void sendData(int seq) {
      // Send a datagram acknowledging the received sequence.
      int bytes = sender.send(createDataPackage(seq), bindAddress, receiver.port);
      Expect.isTrue(bytes == 0 || bytes == 1000);
    }
  
    void sendAck(address, port) {
      // Send a datagram acknowledging the received sequence.
      int bytes = receiver.send(createAckPackage(receivedSeq), address, port);
      Expect.isTrue(bytes == 0 || bytes == 4);
      // Start a "long" timer for more data.
      if (ackTimer != null) ackTimer.cancel();
      ackTimer = new Timer.periodic(
          new Duration(milliseconds: 100), (_) => sendAck(address, port));
    }
  
    sender.listen((event) {
      switch (event) {
        case RawSocketEvent.READ:
          var datagram = sender.receive();
          if (datagram != null) {
            Expect.equals(datagram.port, receiver.port);
            if (!bindAddress.isMulticast) {
              Expect.equals(receiver.address, datagram.address);
            }
            ackSeq = packageSeq(datagram);
            if (ackSeq < total) {
              sender.writeEventsEnabled = true;
            } else {
              sender.close();
              receiver.close();
              ackTimer.cancel();
              asyncEnd();
            }
          }
          break;
        case RawSocketEvent.WRITE:
          // Send the next package.
          sendData(ackSeq + 1);
          break;
        case RawSocketEvent.CLOSED:
          break;
        default:
          throw "Unexpected event $event";
      }
    });
  
    receiver.writeEventsEnabled = false;
    receiver.listen((event) {
      switch (event) {
        case RawSocketEvent.READ:
          var datagram = receiver.receive();
          if (datagram != null) {
            Expect.equals(datagram.port, sender.port);
            if (!bindAddress.isMulticast) {
              Expect.equals(receiver.address, datagram.address);
            }
            var seq = packageSeq(datagram);
            if (seq == receivedSeq + 1) {
              receivedSeq = seq;
              sendAck(bindAddress, sender.port);
            }
          }
          break;
        case RawSocketEvent.WRITE:
          throw "Unexpected WRITE";
          break;
        case RawSocketEvent.CLOSED:
          break;
        default:
          throw "Unexpected event $event";
      }
    });
    });
  }
  
  
  
negative.code: testBroadcast() {
    test(bindAddress, broadcastAddress, enabled) {
      asyncStart();
      Future.wait([
          RawDatagramSocket.bind(bindAddress, 0, reuseAddress: false),
          RawDatagramSocket.bind(bindAddress, 0, reuseAddress: false)])
        .then((values) {
          var broadcastTimer;
          var sender = values[0];
          var receiver = values[1];
          // On Windows at least the receiver needs to have broadcast
          // enabled whereas on Linux at least the sender needs to.
          receiver.broadcastEnabled = enabled;
          sender.broadcastEnabled = enabled;
          receiver.listen((event) {
            if (event == RawSocketEvent.READ) {
              Expect.isTrue(enabled);
              sender.close();
              receiver.close();
              broadcastTimer.cancel();
              asyncEnd();
            }
          });
  
          int sendCount = 0;
          send(_) {
            int bytes =
                sender.send(new Uint8List(1), broadcastAddress, receiver.port);
            Expect.isTrue(bytes == 0 || bytes == 1);
            sendCount++;
            if (!enabled && sendCount == 50) {
              sender.close();
              receiver.close();
              broadcastTimer.cancel();
              asyncEnd();
            }
          }
          broadcastTimer = new Timer.periodic(new Duration(milliseconds: 10), send);
        });
    }
  
    var broadcast = new InternetAddress("255.255.255.255");
  