/** {@inheritDoc} */
  @Override
  public void update(String key, String msg) {
    if (key.startsWith(Definitions.PREFIX_SENSORS_VISIBILITY)) {
      // notify all clients
      log.trace("a sensor has become (in)visible");
      String sensorId = key.replace(VISIBILITY, "");
      String msgToSend = null;
      if ("true".equals(msg)) {
        // for a visible message, we need all the sensors information
        Sensor s = Server.getSensorStorage().getSensorById(sensorId);
        if (s != null) {
          msgToSend =
              ServerProtocolAbstractor.createSensorVisibilityMessage(
                  sensorId, s.description, s.dataType, true);
          broadcastToAllClients(msgToSend);
          // create the visibility conf item for the admin clients:
          String confMsg = createSensorVisiblityConf(s);
          List<ServerClient> admins = null;
          synchronized (m_adminClients) {
            // copy to be thread-safe
            admins = new ArrayList<ServerClient>(m_adminClients.values());
          }
          sendToClients(admins, confMsg);

          // if its a polling sensor, we additionally need the polltime config:
          if (s.isPolling) {
            confMsg = createSensorPollTimeConf(s);
            sendToClients(admins, confMsg);
          }
        } else {
          log.warn("we got info about new sensor which isn't really there! id=" + sensorId);
        }
      } else {
        // sensor became invisble, we only need his id
        msgToSend =
            ServerProtocolAbstractor.createSensorVisibilityMessage(
                sensorId, "NOT_USED", "NOT_USED", false);
        broadcastToAllClients(msgToSend);
        // and unsubscribe all clients that might currently be subscribed:
        List<ServerClient> targets = null;
        synchronized (m_clients) {
          List<ServerClient> clients = m_clients.getClientsForSensor(sensorId);
          if (clients != null) {
            targets = new ArrayList<ServerClient>(clients);
          }
        }
        if (targets != null) {
          for (ServerClient unregMe : targets) {
            m_clients.onClientUnregistersForSensor(unregMe, sensorId);
          }
        }
      }
    }
  }
  /** {@inheritDoc} */
  @Override
  public void onNewClient(Client data, NetworkServiceClient connection) {
    ServerClient sc = new ServerClient(data, connection);
    m_clients.addClient(sc);

    List<Sensor> allSensors = Server.getSensorStorage().getAllSensors();

    for (Sensor sensor : allSensors) {
      String value = m_prefs.getValue(VISIBILITY + sensor.ident);
      if ("true".equals(value)) {
        String msg =
            ServerProtocolAbstractor.createSensorVisibilityMessage(
                sensor.ident, sensor.description, sensor.dataType, true);
        sendToClient(sc, msg);
      }
    }
  }
  @Override
  public void onSensorDataReceived(Sensor s) {
    ArrayList<ServerClient> targets = null;
    synchronized (m_clients) {
      // copy the entries to be reistent to modifications while sending
      List<ServerClient> clients = m_clients.getClientsForSensor(s.ident);
      if (clients != null) {
        targets = new ArrayList<ServerClient>(clients);
      }
    }

    if (targets != null && targets.size() > 0) {
      log.trace(
          "broadcasting new sensor data from " + s.ident + " to " + targets.size() + " clients");
      String msgToSend = ServerProtocolAbstractor.createSensorDataMessage(s.ident, s.data);
      sendToClients(targets, msgToSend);
    } else {
      log.trace("broadcasting new sensor data from " + s.ident + " to 0 clients");
    }
  }