void QCopChannel::detach(QCopX11Client *cl)
{
    if (!qcopServerMap)
        return;

    QCopServerMap::Iterator it = qcopServerMap->begin();
    for (; it != qcopServerMap->end(); it++) {
      if (it.value().contains(cl)) {
        it.value().removeAll(cl);
        // If this was the last client in the channel, announce the channel as dead.
        if (it.value().count() == 0) {
	  emit qcopServer->removedChannel(it.key());
        }
      }
    }

    if (!qcopServerRegexpList)
	return;

    QCopServerRegexpList::Iterator it2 = qcopServerRegexpList->begin();
    while(it2 != qcopServerRegexpList->end()) {
	if ((*it2).client == cl)
	    it2 = qcopServerRegexpList->erase(it2);
	else
	    ++it2;
    }
}
void QCopChannel::detach(const QString& ch, QCopX11Client *cl)
{
    if (!qcopServerMap)
        return;

    QCopServerMap::Iterator it = qcopServerMap->find(ch);
    if (it != qcopServerMap->end()) {
        it.value().removeAll(cl);
        if (it.value().isEmpty()) {
          // If this was the last client in the channel, announce the channel as dead
          emit qcopServer->removedChannel(it.key());
          qcopServerMap->erase(it);
        }
    }
    if (qcopServerRegexpList && containsWildcards(ch)) {
        // Remove references to a wildcarded channel.
        QCopServerRegexpList::Iterator it
            = qcopServerRegexpList->begin();
        while(it != qcopServerRegexpList->end()) {
            if ((*it).client == cl && (*it).channel == ch)
                it = qcopServerRegexpList->erase(it);
            else
                ++it;
        }
    }
}
void QCopChannel::detach(QWSClient *cl)
{
    if (!qcopServerMap)
        return;

    QCopServerMap::Iterator it = qcopServerMap->begin();
    for (; it != qcopServerMap->end(); ++it) {
      if (it.value().contains(cl)) {
        it.value().removeAll(cl);
        // If this was the last client in the channel, announce the channel as dead.
        if (it.value().count() == 0) {
          QWSServerSignalBridge* qwsBridge = new QWSServerSignalBridge();
          connect(qwsBridge, SIGNAL(removedChannel(QString)), qwsServer, SIGNAL(removedChannel(QString)));
          qwsBridge->emitRemovedChannel(it.key());
          delete qwsBridge;
        }
      }
    }

    if (!qcopServerRegexpList)
	return;

    QCopServerRegexpList::Iterator it2 = qcopServerRegexpList->begin();
    while(it2 != qcopServerRegexpList->end()) {
	if ((*it2).client == cl)
	    it2 = qcopServerRegexpList->erase(it2);
	else
	    ++it2;
    }
}
void QCopChannel::registerChannel(const QString& ch, QCopX11Client *cl)
{
    if (!qcopServerMap)
        qcopServerMap = new QCopServerMap;

    // do we need a new channel list ?
    QCopServerMap::Iterator it = qcopServerMap->find(ch);
    if (it == qcopServerMap->end())
      it = qcopServerMap->insert(ch, QList<QCopX11Client*>());

    // If the channel name contains wildcard characters, then we also
    // register it on the server regexp matching list.
    if (containsWildcards( ch )) {
	QCopServerRegexp item(ch, cl);
	if (!qcopServerRegexpList)
	    qcopServerRegexpList = new QCopServerRegexpList;
	qcopServerRegexpList->append( item );
    }

    // If this is the first client in the channel, announce the channel as being created.
    if (it.value().count() == 0) {
      emit qcopServer->newChannel(ch);
    }

    it.value().append(cl);
}
void QCopChannel::registerChannel(const QString& ch, QWSClient *cl)
{
    if (!qcopServerMap)
        qcopServerMap = new QCopServerMap;

    // do we need a new channel list ?
    QCopServerMap::Iterator it = qcopServerMap->find(ch);
    if (it == qcopServerMap->end())
      it = qcopServerMap->insert(ch, QList<QWSClient*>());

    // If the channel name contains wildcard characters, then we also
    // register it on the server regexp matching list.
    if (containsWildcards( ch )) {
	QCopServerRegexp item(ch, cl);
	if (!qcopServerRegexpList)
	    qcopServerRegexpList = new QCopServerRegexpList;
	qcopServerRegexpList->append( item );
    }

    // If this is the first client in the channel, announce the channel as being created.
    if (it.value().count() == 0) {
      QWSServerSignalBridge* qwsBridge = new QWSServerSignalBridge();
      connect(qwsBridge, SIGNAL(newChannel(QString)), qwsServer, SIGNAL(newChannel(QString)));
      qwsBridge->emitNewChannel(ch);
      delete qwsBridge;
    }

    it.value().append(cl);
}
void QCopClient::handleDetachMonitor(const QString& ch)
{
    QCopThreadData *td = QCopThreadData::instance();
    QCopServerMap::Iterator it = td->serverMonitorMap.find(ch);
    if (it != td->serverMonitorMap.end()) {
        it.value().removeAll(this);
        if (it.value().isEmpty())
            td->serverMonitorMap.erase(it);
    }
}
void QCopClient::handleRegisterMonitor(const QString& ch)
{
    QCopThreadData *td = QCopThreadData::instance();

    // Add the monitor to the server's list.
    QCopServerMap::Iterator it = td->serverMonitorMap.find(ch);
    if (it == td->serverMonitorMap.end())
        it = td->serverMonitorMap.insert(ch, QList<QCopClient*>());
    it.value().append(this);

    // Inform the client about the current state of the channel.
    if (td->serverMap.contains(ch))
        sendChannelCommand(QCopCmd_MonitorRegistered, ch);
    else
        sendChannelCommand(QCopCmd_MonitorUnregistered, ch);
}
void QCopChannel::detach( const QWSClient *cl )
{
    if ( !qcopServerMap )
	return;

    QCopServerMap::Iterator it = qcopServerMap->begin();
    for ( ; it != qcopServerMap->end(); it++ ) {
      if (it.data().containsRef(cl)) {
	it.data().removeRef( cl );
	// If this was the last client in the channel, announce the channel as dead.
	if (it.data().count() == 0) {
	  QWSServerSignalBridge* qwsBridge = new QWSServerSignalBridge();
	  connect(qwsBridge, SIGNAL(removedChannel(const QString&)), qwsServer, SIGNAL(removedChannel(const QString&)));
	  qwsBridge->emitRemovedChannel(it.key());
	  delete qwsBridge;
	}
      }
    }
}
/*!
  \internal
  Server side: subscribe client \a cl on channel \a ch.
 */
void QCopChannel::registerChannel( const QString &ch, const QWSClient *cl )
{
    if ( !qcopServerMap )
	qcopServerMap = new QCopServerMap;
    
    // do we need a new channel list ? 
    QCopServerMap::Iterator it = qcopServerMap->find( ch );
    if ( it == qcopServerMap->end() )
      it = qcopServerMap->insert( ch, QList<QWSClient>() );
    
    // If this is the first client in the channel, announce the channel as being created.
    if (it.data().count() == 0) {
      QWSServerSignalBridge* qwsBridge = new QWSServerSignalBridge();
      connect(qwsBridge, SIGNAL(newChannel(const QString&)), qwsServer, SIGNAL(newChannel(const QString&)));
      qwsBridge->emitNewChannel(ch);
      delete qwsBridge;
    }

    it.data().append( cl );
}