public void conference(TSCall otherCall, CSTAPrivate reqPriv)
			throws TsapiPrivilegeViolationException,
			TsapiInvalidArgumentException, TsapiInvalidStateException,
			TsapiResourceUnavailableException, TsapiMethodNotSupportedException {
		if (this.provider.getCapabilities().getConferenceCall() == 0) {
			throw new TsapiMethodNotSupportedException(4, 0,
					"unsupported by driver");
		}

		boolean thisCallUpdate = updateObject();
		boolean otherCallUpdate = otherCall.updateObject();

		if ((thisCallUpdate) && (this.state != 33)) {
			throw new TsapiInvalidStateException(3, 0,
					TsapiCreateObject.getTsapiObject(this, false), 1,
					this.state, "call is not active");
		}

		if ((!this.confEnable) || (!otherCall.confEnable)) {
			throw new TsapiInvalidStateException(3, 0,
					TsapiCreateObject.getTsapiObject(this, false), 1,
					this.state, "conferencing disabled");
		}

		TSConnection activeTermConn = this.confController;
		TSConnection heldTermConn = otherCall.confController;
		if (activeTermConn == null) {
			if (heldTermConn == null) {
				TSConnection conn = null;
				TSConnection termConn = null;
				boolean found = false;
				synchronized (this.connections) {
					for (int i = 0; i < this.connections.size(); i++) {
						conn = (TSConnection) this.connections.elementAt(i);
						Vector<?> termConns = conn.getTermConns();
						if (termConns != null) {
							Vector<?> tcs = new Vector<Object>(termConns);
							for (int j = 0; j < tcs.size(); j++) {
								termConn = (TSConnection) tcs.elementAt(j);
								if ((termConn.getCallControlTermConnState() == 98)
										|| (termConn
												.getCallControlTermConnState() == 103)) {
									activeTermConn = termConn;

									heldTermConn = otherCall
											.findHeldTermConnection(activeTermConn
													.getTSDevice());
									if (heldTermConn != null) {
										found = true;
										break;
									}
								}
							}
							if (found)
								break;
						}
					}
				}
				if (activeTermConn == null) {
					throw new TsapiInvalidStateException(3, 0,
							TsapiCreateObject.getTsapiObject(this, false), 1,
							this.state, "no active terminal connection found");
				}

				if (heldTermConn == null) {
					throw new TsapiInvalidStateException(3, 0,
							TsapiCreateObject.getTsapiObject(this, false), 1,
							this.state, "no held terminal connection found");
				}

			} else {
				if ((otherCallUpdate)
						&& (heldTermConn.getCallControlTermConnState() != 99)
						&& (heldTermConn.getCallControlTermConnState() != 103)) {
					throw new TsapiInvalidStateException(3, 0,
							TsapiCreateObject.getTsapiObject(this, false), 1,
							this.state, "terminal connection not held");
				}

				activeTermConn = findActiveTermConnection(heldTermConn
						.getTSDevice());
				if (activeTermConn == null) {
					throw new TsapiInvalidStateException(3, 0,
							TsapiCreateObject.getTsapiObject(this, false), 1,
							this.state, "no active terminal connection found");
				}

			}

		} else if (heldTermConn == null) {
			if ((thisCallUpdate)
					&& (activeTermConn.getCallControlTermConnState() != 98)
					&& (activeTermConn.getCallControlTermConnState() != 103)) {
				throw new TsapiInvalidStateException(3, 0,
						TsapiCreateObject.getTsapiObject(this, false), 1,
						this.state,
						"Terminal connection not active. It's state is "
								+ activeTermConn.getCallControlTermConnState());
			}

			heldTermConn = otherCall.findHeldTermConnection(activeTermConn
					.getTSDevice());
			if (heldTermConn == null) {
				throw new TsapiInvalidStateException(3, 0,
						TsapiCreateObject.getTsapiObject(this, false), 1,
						this.state, "no held terminal connection found");
			}

		} else if ((thisCallUpdate) && (otherCallUpdate)) {
			if ((activeTermConn.getCallControlTermConnState() != 98)
					&& (activeTermConn.getCallControlTermConnState() != 103)) {
				throw new TsapiInvalidStateException(
						3,
						0,
						TsapiCreateObject.getTsapiObject(this, false),
						1,
						this.state,
						"the state of the active terminal connection is not TALKING or UNKNOWN; its state is "
								+ activeTermConn.getCallControlTermConnState());
			}

			if ((heldTermConn.getCallControlTermConnState() != 99)
					&& (heldTermConn.getCallControlTermConnState() != 103)) {
				throw new TsapiInvalidStateException(
						3,
						0,
						TsapiCreateObject.getTsapiObject(this, false),
						1,
						this.state,
						"the state of the held terminal connection is not HELD or UNKNOWN; its state is "
								+ heldTermConn.getCallControlTermConnState());
			}

			if (!activeTermConn.getTSDevice().getTermConns()
					.contains(heldTermConn)) {
				throw new TsapiInvalidStateException(3, 0,
						TsapiCreateObject.getTsapiObject(this, false), 1,
						this.state,
						"the held terminal connection is not associated with the device ("
								+ activeTermConn.getTSDevice()
								+ ") of the active terminal connection");
			}

		}

		ConfHandler handler = new ConfXferConfHandler(this, otherCall, 12);
		try {
			this.provider.tsapi.conferenceCall(heldTermConn.getConnID(),
					activeTermConn.getConnID(), reqPriv, handler);
		} catch (TsapiInvalidStateException e) {
			throw e;
		} catch (TsapiInvalidArgumentException e) {
			throw e;
		} catch (TsapiPrivilegeViolationException e) {
			throw e;
		} catch (TsapiResourceUnavailableException e) {
			throw e;
		} catch (TsapiPlatformException e) {
			throw e;
		} catch (Exception e) {
			if ((e instanceof ITsapiException)) {
				throw new TsapiPlatformException(
						((ITsapiException) e).getErrorType(),
						((ITsapiException) e).getErrorCode(),
						"conferenceCall failure");
			}
			throw new TsapiPlatformException(4, 0, "conferenceCall failure");
		}
	}