  private void removeClientFromCache(ChannelPipeline pipeline) {
    final RegionClient client = pipeline.get(RegionClient.class);
    final SocketAddress remote = pipeline.getChannel().getRemoteAddress();
    if (remote == null) {
      if (client == rootregion) {
        rootregion = null;
        String hostport = null;
        synchronized(this) {
          final Iterator<Map.Entry<String, RegionClient>> it =
            ip2client.entrySet().iterator();
          while (it.hasNext()) {
            final Map.Entry<String, RegionClient> e = it.next();
            if (e.getValue() == client) {
              hostport = e.getKey();
              it.remove();
              break;
            }
          }
        }
        LOG.warn("Couldn't connect to the -ROOT- region @ " + hostport);
      }
      return;
    }
    pipeline = null;  
    String hostport = null;
    if (remote instanceof InetSocketAddress) {
      final InetSocketAddress sock = (InetSocketAddress) remote;
      final InetAddress addr = sock.getAddress();
      if (addr == null) {
        LOG.error("Unresolved IP for " + remote
                  + ".  This shouldn't happen.");
        return;
      } else {
        hostport = addr.getHostAddress() + ':' + sock.getPort();
      }
    } else {
        LOG.error("Found a non-InetSocketAddress remote: " + remote
                  + ".  This shouldn't happen.");
        return;
    }
    RegionClient old;
    if (client != null) {
      final ArrayList<RegionInfo> regions = client2regions.remove(client);
      if (regions != null) {
        for (final RegionInfo region : regions) {
          final byte[] table = region.table();
          final byte[] stop_key = region.stopKey();
          final Map.Entry<byte[], RegionInfo> entry =
            (stop_key.length == 0
             ? regions_cache.floorEntry(createRegionSearchKey(table, stop_key))
             : regions_cache.lowerEntry(createRegionSearchKey(table, stop_key)));
          if (entry != null && entry.getValue() == region) {
            regions_cache.remove(entry.getKey());
            LOG.debug("Removed from regions cache: {}", region);
          }
          final RegionClient oldclient = region2client.remove(region);
          if (client == oldclient) {
            LOG.debug("Association removed: {} -> {}", region, client);
          } else if (oldclient != null) {  
            LOG.warn("When handling disconnection of " + client
                     + " and removing " + region + " from region2client"
                     + ", it was found that " + oldclient + " was in fact"
                     + " serving this region");
          }
        }
      }
    }
    synchronized (ip2client) {
      old = ip2client.remove(hostport);
    }
    LOG.debug("Removed from IP cache: {} -> {}", hostport, client);
    if (old == null) {
      LOG.warn("When expiring " + client + " from the client cache (host:port="
               + hostport + "), it was found that there was no entry"
               + " corresponding to " + remote + ".  This shouldn't happen.");
    }
    if (client == rootregion) {
      LOG.info("Lost connection with the -ROOT- region");
      rootregion = null;
    }
  }

  private void removeClientFromCache(ChannelPipeline pipeline) {
    final RegionClient client = pipeline.get(RegionClient.class);
    final SocketAddress remote = pipeline.getChannel().getRemoteAddress();
    if (remote == null) {
      if (client == rootregion) {
        rootregion = null;
        String hostport = null;
        synchronized (ip2client) {
          final Iterator<Map.Entry<String, RegionClient>> it =
            ip2client.entrySet().iterator();
          while (it.hasNext()) {
            final Map.Entry<String, RegionClient> e = it.next();
            if (e.getValue() == client) {
              hostport = e.getKey();
              it.remove();
              break;
            }
          }
        }
        LOG.warn("Couldn't connect to the -ROOT- region @ " + hostport);
      }
      return;
    }
    pipeline = null;  
    String hostport = null;
    if (remote instanceof InetSocketAddress) {
      final InetSocketAddress sock = (InetSocketAddress) remote;
      final InetAddress addr = sock.getAddress();
      if (addr == null) {
        LOG.error("Unresolved IP for " + remote
                  + ".  This shouldn't happen.");
        return;
      } else {
        hostport = addr.getHostAddress() + ':' + sock.getPort();
      }
    } else {
        LOG.error("Found a non-InetSocketAddress remote: " + remote
                  + ".  This shouldn't happen.");
        return;
    }
    RegionClient old;
    if (client != null) {
      final ArrayList<RegionInfo> regions = client2regions.remove(client);
      if (regions != null) {
        for (final RegionInfo region : regions) {
          final byte[] table = region.table();
          final byte[] stop_key = region.stopKey();
          final Map.Entry<byte[], RegionInfo> entry =
            (stop_key.length == 0
             ? regions_cache.floorEntry(createRegionSearchKey(table, stop_key))
             : regions_cache.lowerEntry(createRegionSearchKey(table, stop_key)));
          if (entry != null && entry.getValue() == region) {
            regions_cache.remove(entry.getKey());
            LOG.debug("Removed from regions cache: {}", region);
          }
          final RegionClient oldclient = region2client.remove(region);
          if (client == oldclient) {
            LOG.debug("Association removed: {} -> {}", region, client);
          } else if (oldclient != null) {  
            LOG.warn("When handling disconnection of " + client
                     + " and removing " + region + " from region2client"
                     + ", it was found that " + oldclient + " was in fact"
                     + " serving this region");
          }
        }
      }
    }
    synchronized (ip2client) {
      old = ip2client.remove(hostport);
    }
    LOG.debug("Removed from IP cache: {} -> {}", hostport, client);
    if (old == null) {
      LOG.warn("When expiring " + client + " from the client cache (host:port="
               + hostport + "), it was found that there was no entry"
               + " corresponding to " + remote + ".  This shouldn't happen.");
    }
    if (client == rootregion) {
      LOG.info("Lost connection with the -ROOT- region");
      rootregion = null;
    }
  }
