protected void removeCallMonitor(TsapiCallMonitor obs, int cause,
			Object privateData) {
		CallbackAndType cbAndType = null;
		synchronized (this.callbackAndTypeVector) {
			for (int i = 0; i < this.callbackAndTypeVector.size(); i++) {
				cbAndType = (CallbackAndType) this.callbackAndTypeVector
						.elementAt(i);
				if (cbAndType.callback == obs) {
					if (cbAndType.devWithType == null) {
						synchronized (this.monitorThreads) {
							if (!this.monitorThreads
									.contains(cbAndType.callback)) {
								this.monitorThreads
										.addElement(cbAndType.callback);
								cbAndType.callback.addReference();
							}
						}
					} else {
						boolean found = false;
						DeviceObs devObs = null;
						synchronized (this.deviceObsVector) {
							for (int j = 0; j < this.deviceObsVector.size(); j++) {
								devObs = (DeviceObs) this.deviceObsVector
										.elementAt(j);
								if (devObs.callback == cbAndType.callback) {
									found = true;
									break;
								}
							}
							if (!found) {
								devObs = new DeviceObs(cbAndType.callback);
								devObs.devWithTypeVector
										.addElement(cbAndType.devWithType);
								this.deviceObsVector.addElement(devObs);
								cbAndType.callback.addReference();
							}
						}
					}
					this.callbackAndTypeVector.removeElement(cbAndType);
				}
			}
		}

		synchronized (this.monitorThreads) {
			if (this.monitorThreads.removeElement(obs)) {
				obs.deleteReference(this, false, cause, privateData);
				if (this.monitorThreads.isEmpty()) {
					if (this.monitorCrossRefID != 0) {
						this.provider.deleteMonitor(this.monitorCrossRefID);
						if (this.provider.getCapabilities().getMonitorStop() != 0) {
							try {
								this.provider.tsapi.monitorStop(
										this.monitorCrossRefID, null, null);
							} catch (TsapiUnableToSendException tue) {
								throw tue;
							} catch (Exception e) {
								log.error(e.getMessage(), e);
							}

						}

						this.monitorCrossRefID = 0;

						if (!checkForMonitors()) {
							setNeedSnapshot(true);
						}
					}
				}
			} else {
				synchronized (this.deviceObsVector) {
					for (int i = 0; i < this.deviceObsVector.size(); i++) {
						if (((DeviceObs) this.deviceObsVector.elementAt(i)).callback == obs) {
							this.deviceObsVector.removeElementAt(i);
							obs.deleteReference(this, false, cause, privateData);
							return;
						}
					}

				}

				if (this.staleObsVector.removeElement(obs)) {
					obs.deleteReference(this, false, cause, privateData);
					return;
				}
			}
		}
	}