anchor.diff:    HetiSocketBuilder builder = null;
     String get externalIp => _externalAddress;
     String get appIdDesc => "hetim(${appid})";
  +
  +  List<UpnpDeviceInfo> _currentUpnpDeviceInfo = [];
  +
     UpnpPortMapHelper(HetiSocketBuilder builder, String appid) {
       this.appid = appid;
       this.builder = builder;
  
positive.code: }
  class GetPortMapInfoResult {
    List<PortMapInfo> infos = [];
    add(String ip, String internalPort, String externalPort,String description, String type) {
      infos.add(new PortMapInfo()..description=description..externalPort=externalPort..ip=ip..type=type..internalPort=internalPort);
    }
  }
  
  
negative.code:   //
    //
    // ####
    async.Future<StartGetExternalIp> startGetExternalIp({bool reuseRouter: false}) {
      _externalPort = basePort;
      return searchRoutder(reuseRouter: reuseRouter).then((List<UpnpDeviceInfo> deviceInfoList) {
        UpnpDeviceInfo info = deviceInfoList.first;
        UpnpPPPDevice pppDevice = new UpnpPPPDevice(info);
        return pppDevice.requestGetExternalIPAddress().then((UpnpGetExternalIPAddressResponse res) {
          _externalAddress = res.externalIp;
          _controllerUpdateGlobalIp.add(res.externalIp);
          return new StartGetExternalIp(res.externalIp);
        });
      }).catchError((e) {
        throw e;
      });
    }
  
    async.Future<StartPortMapResult> startPortMap({bool reuseRouter: false}) {
      _externalPort = basePort;
      return searchRoutder(reuseRouter: reuseRouter).then((List<UpnpDeviceInfo> deviceInfoList) {
        UpnpDeviceInfo info = deviceInfoList.first;
        UpnpPPPDevice pppDevice = new UpnpPPPDevice(info);
        int maxRetryExternalPort = _externalPort + numOfRetry;
  
        tryAddPortMap() {
          print("############### ${this.localPort} ${this.localAddress}");
          return pppDevice
              .requestAddPortMapping(_externalPort, UpnpPPPDevice.VALUE_PORT_MAPPING_PROTOCOL_TCP, localPort, localAddress, UpnpPPPDevice.VALUE_ENABLE, appIdDesc, 0)
              .then((UpnpAddPortMappingResponse res) {
            if (200 == res.resultCode) {
              _controllerUpdateGlobalPort.add("${_externalPort}");
              return new StartPortMapResult();
            } else if (500 == res.resultCode) {
              _externalPort++;
              if (_externalPort < maxRetryExternalPort) {
                return tryAddPortMap();
              } else {
                throw {"failed": "redirect max"};
              }
            } else {
              throw {"failed": "unexpected error code ${res.resultCode}"};
            }
          });
        }
  
        return tryAddPortMap();
      }).catchError((e) {
        throw e;
      });
    }
  
    async.Future<DeleteAllPortMapResult> deletePortMapFromAppIdDesc({bool reuseRouter: false}) {
      return getPortMapInfo(target: appIdDesc, reuseRouter: reuseRouter).then((GetPortMapInfoResult result) {
        List<int> externalPortList = [];
        for (PortMapInfo info in result.infos) {
          try {
            externalPortList.add(int.parse(info.externalPort));
          } catch (e) {
            ;
          }
        }
  