private void stepTimeout() {
    boolean updated = false;
    synchronized (channels) {
      Iterator<ChannelInfo> it = channels.values().iterator();
      while (it.hasNext()) {
        ChannelInfo channel = it.next();
        Iterator<UserInfo> removed = channel.stepTimeout(getTimeoutLimit());

        if (removed != null) {
          updated = true;
          String channelName = channel.getChannelName();
          while (removed.hasNext()) {
            UserInfo user = removed.next();
            ServerLogger.getInstance()
                .channelLeaved(channelName, user.getUserName(), user.getInetSocketAddress());
          }
          if (channel.isEmpty()) {
            it.remove();
            ServerLogger.getInstance().channelRemoved(channelName);
          }
        }
      }

      if (updated) {
        updateChannelsCache();
      }
    }
  }
 public IChannelInfo channelData(
     String channelName, String userName, InetSocketAddress userAddress) {
   // System.out.println("channelName channel:"+channelName+" user:"******"
   // addr:"+userAddress);
   ChannelInfo channel = channelsCache.get(channelName);
   if (channel == null) {
     synchronized (channels) {
       channel = channels.get(channelName);
       if (channel == null) {
         channel = new ChannelInfo(channelName);
         channels.put(channelName, channel);
         updateChannelsCache();
         ServerLogger.getInstance().channelCreated(channelName);
       }
     }
   }
   boolean updated = channel.userData(userName, userAddress);
   if (updated) {
     ServerLogger.getInstance().channelJoined(channelName, userName, userAddress);
   }
   return channel;
 }