anchor.diff:        var data = common("disconnect");
         com.pm.sendAll(data);
       });
  +    
  +    b.client.register((IRC.ModeEvent e) {
  +      var data = common("mode");
  +      if (e.channel != null) {
  +        data['channel'] = e.channel.name;
  +      }
  +      data['mode'] = e.mode;
  +      data['user'] = e.user;
  +      com.pm.sendAll(data);
  +    });
  +    
  +    b.client.register((IRC.WhoisEvent event) {
  +      var data = common("whois");
  +      data['member_in'] = event.member_in;
  +      data['op_in'] = event.op_in;
  +      data['voice_in'] = event.voice_in;
  +      data['username'] = event.username;
  +      data['server_operator'] = event.server_operator;
  +      data['realname'] = event.realname;
  +      data['nickname'] = event.nickname;
  +      com.pm.sendAll(data);
  +    });
     }
   
     Map common(String event) {
  
positive.code:           bot.config.clear();
            bot.config.addAll(config);
            break;
          default:
            throw new Exception("$plugin sent an invalid command: $command");
        }
  
negative.code:           var data = request.data["data"];
            pm.get(plugin, command, data).then((response) {
              request.reply(response);
            });
            break;
          case "channel":
            var net = request.data['network'];
            var chan = request.data['channel'];
            var channel = bot._clients[net].client.channel(chan);
            request.reply({
              "name": channel.name,
              "ops": channel.ops,
              "voices": channel.voices,
              "members": channel.members,
              "topic": channel.topic
            });
            break;
          default:
  