anchor.diff:    KId _nodeId = null;
     KId get nodeId => _nodeId;
     List<SendInfo> queryInfo = [];
  -
  -  KNode(HetiSocketBuilder socketBuilder, {int kBucketSize: 8, List<int> nodeIdAsList: null}) {
  +  KNodeAI _ai = null;
  +  KNode(HetiSocketBuilder socketBuilder, {int kBucketSize: 8, List<int> nodeIdAsList: null,KNodeAI ai:null}) {
       if (nodeIdAsList == null) {
         _nodeId = KId.createIDAtRandom();
       } else {
  
positive.code:     return new Future(() {
        if (_udpSocket == null) {
          return null;
        }
        return _udpSocket.close();
      });
    }
  }
  
  
negative.code:             buffers["${info.remoteAddress}:${info.remotePort}"] = new EasyParser(new ArrayBuilder());
            }
            EasyParser parser = buffers["${info.remoteAddress}:${info.remotePort}"];
            
            //
            //
            KrpcMessage.decode(parser, this).then((KrpcMessage message) {
              if (message is KrpcResponse) {
                SendInfo rm = removeQueryNameFromTransactionId(UTF8.decode(message.rawMessageMap["t"]));
                _onReceiveResponse(info, message);
                rm._c.complete(message);
              } else if (message is KrpcQuery) {
                _onReceiveQuery(info, message);
              } else {
                _onReceiveUnknown(info, message);
              }
            }).catchError((e) {
              parser.last();
            });
            //
            
            _ai.start(this);
          });
        });
      });
    }
  
    _onReceiveQuery(HetiReceiveUdpInfo info, KrpcMessage message) {}
    _onReceiveResponse(HetiReceiveUdpInfo info, KrpcMessage message) {}
  
    _onReceiveUnknown(HetiReceiveUdpInfo info, KrpcMessage message) {}
  
    String getQueryNameFromTransactionId(String transactionId) {
      for (SendInfo si in queryInfo) {
        if (si._id == transactionId) {
          return si._act;
        }
      }
      return "";
    }
    SendInfo removeQueryNameFromTransactionId(String transactionId) {
      SendInfo re = null;
      for (SendInfo si in queryInfo) {
        if (si._id == transactionId) {
          re = si;
          break;
        }
      }
      queryInfo.remove(re);
      return re;
    }
    static int id = 0;
    Future sendPing(String ip, int port) {
      Completer c;
      new Future(() {
        KrpcPingQuery query = new KrpcPingQuery(UTF8.encode("p_${id}"), _nodeId.id);
        queryInfo.add(new SendInfo("p_${id}", "ping", c));
        return _udpSocket.send(query.messageAsBencode, ip, port);
      }).catchError(c.completeError);
      return c.future;
  