private synchronized void deleteReferenceInternalForListener(
      TSDevice device, int cause, Object privateData) {
    String tsEventLog = null;
    this.reference -= 1L;
    tsEventLog = "OBSERVATIONENDEDEVENT for " + device;

    AddressEventParams addressEventParams = new AddressEventParams();
    addressEventParams.setCause(cause);
    addressEventParams.setEventId(100);
    Address address = createAddress(device);
    addressEventParams.setSource(address);
    addCoreAddressEvents(new AddressEventImpl(addressEventParams, address), tsEventLog);
    if (privateData != null) {
      tsEventLog = "PRIVATEEVENT for " + device;
      addPrivateEvents(
          new PrivateDataEventImpl(600, cause, null, address, privateData), tsEventLog);
    }

    if (this.reference <= 0L) {
      this.provider.removeAddressMonitorThread(this);
    }
  }
  private void createEventsForListener(Vector<TSEvent> _eventList, boolean snapshot) {
    if (_eventList == null) return;
    int cause;
    if (snapshot) {
      cause = 110;
    } else {
      cause = 100;
    }

    TSEvent tsEvent = null;
    Object tsTarget = null;
    TSDevice target = null;
    TSAgent targetAgent = null;
    Object privateData = null;
    Object previousPrivateData = null;
    Address address = null;
    Agent agent = null;
    Object source = null;
    for (int i = 0; i < _eventList.size(); i++) {
      tsEvent = (TSEvent) _eventList.elementAt(i);
      tsTarget = tsEvent.getEventTarget();
      if ((tsTarget instanceof TSDevice)) {
        target = (TSDevice) tsTarget;
        address = createAddress(target);
        source = address;
      } else if ((tsTarget instanceof TSAgent)) {
        targetAgent = (TSAgent) tsTarget;
        agent = createAgent(targetAgent);
        source = agent;
        target = targetAgent.getTSACDDevice();
        if (target == null) target = tsEvent.getSkillDevice();
        address = createAddress(target);
      }
      privateData = tsEvent.getPrivateData();
      if (privateData != null) {
        if ((previousPrivateData != null) && (!privateData.equals(previousPrivateData))) {
          _eventList.add(new TSEvent(9999, tsEvent.getEventTarget(), privateData, this.provider));
          previousPrivateData = privateData;
        }
      } else {
        previousPrivateData = null;
      }
      AddressEventParams addressEventParams = new AddressEventParams();
      addressEventParams.setCause(cause);
      addressEventParams.setPrivateData(privateData);
      String tsEventLog;
      switch (tsEvent.getEventType()) {
        case 37:
          tsEventLog = "ADDRESSDONOTDISTURBEVENT for " + target;
          addressEventParams.setEventId(350);
          addressEventParams.setDoNotDisturbState(target.dndState);
          addressEventParams.setSource(source);
          addCallControlAddressEvents(
              new CallControlAddressEventImpl(addressEventParams, address), tsEventLog);
          break;
        case 38:
          tsEventLog = "ADDRESSMESSAGEWAITINGEVENT for " + target;
          addressEventParams.setSource(source);
          addressEventParams.setEventId(352);
          addressEventParams.setMwBits(target.msgWaitingBits);
          if (this.provider.isLucent()) {
            addCallControlAddressEvents(
                new LucentCallControlAddressMsgWaitingEventImpl(addressEventParams, address),
                tsEventLog);
          } else {
            addCallControlAddressEvents(
                new CallControlAddressEventImpl(addressEventParams, address), tsEventLog);
          }
          break;
        case 39:
          tsEventLog = "ADDRESSFORWARDEVENT for " + target;
          addressEventParams.setSource(source);
          addressEventParams.setEventId(351);
          addressEventParams.setCallControlForwarding(target.createForwarding());
          addCallControlAddressEvents(
              new CallControlAddressEventImpl(addressEventParams, address), tsEventLog);
          break;
        case 40:
          tsEventLog = "ADDRESSLOGGEDONEVENT for " + targetAgent;
          addressEventParams.setEventId(302);
          addressEventParams.setSource(source);
          addCallCenterAddressEvents(
              new ACDAddressEventImpl(addressEventParams, address, agent, privateData), tsEventLog);
          break;
        case 41:
          tsEventLog = "ADDRESSLOGGEDOFFEVENT for " + targetAgent;
          addressEventParams.setEventId(301);
          addressEventParams.setSource(source);
          addCallCenterAddressEvents(
              new ACDAddressEventImpl(addressEventParams, address, agent, privateData), tsEventLog);
          break;
        case 42:
          tsEventLog = "ADDRESSREADYEVENT for " + targetAgent;
          addressEventParams.setEventId(304);
          addressEventParams.setSource(source);
          addCallCenterAddressEvents(
              new ACDAddressEventImpl(addressEventParams, address, agent, privateData), tsEventLog);
          break;
        case 43:
          tsEventLog = "ADDRESSNOTREADYEVENT for " + targetAgent;
          addressEventParams.setEventId(303);
          addressEventParams.setSource(source);
          addCallCenterAddressEvents(
              new ACDAddressEventImpl(addressEventParams, address, agent, privateData), tsEventLog);
          break;
        case 44:
          tsEventLog = "ADDRESSWORKREADYEVENT for " + targetAgent;
          addressEventParams.setEventId(307);
          addressEventParams.setSource(source);
          addCallCenterAddressEvents(
              new ACDAddressEventImpl(addressEventParams, address, agent, privateData), tsEventLog);
          break;
        case 45:
          tsEventLog = "ADDRESSWORKNOTREADYEVENT for " + targetAgent;
          addressEventParams.setEventId(306);
          addressEventParams.setSource(source);
          addCallCenterAddressEvents(
              new ACDAddressEventImpl(addressEventParams, address, agent, privateData), tsEventLog);
          break;
        case 46:
          tsEventLog = "ADDRESSBUSYEVENT for " + targetAgent;
          addressEventParams.setEventId(300);
          addressEventParams.setSource(source);
          addCallCenterAddressEvents(
              new ACDAddressEventImpl(addressEventParams, address, agent, privateData), tsEventLog);
          break;
        case 9999:
          tsEventLog = "PRIVATEEVENT for " + target;
          addPrivateEvents(
              new PrivateDataEventImpl(600, cause, null, source, privateData), tsEventLog);
      }
    }

    if (this.listenerEventList.size() == 0) {
      log.debug("no events to send to " + this.addressListener);
      return;
    }
    JtapiEventThreadManager.execute(this);
  }