/** starts work on a transaction branch */
  public void start(Xid xid, int flags) throws XAException {
    if (_xid != null) {
      if (log.isLoggable(Level.FINER)) log.finer("connection pool start XA: rejoin " + this);

      return;
    }

    if (flags == TMJOIN && _xid == null) {
      // TMJOIN means the resource manager is managing more than one
      // connection.  The delegates tie the PoolItems managed by
      // the same resource manager together.

      _xid = xid;

      UserTransactionImpl trans = _cm.getTransaction();

      if (trans != null) {
        ManagedPoolItem xaHead = trans.findJoin(this);

        if (xaHead != null) {
          _xaNext = xaHead._xaNext;
          _xaHead = xaHead;
          xaHead._xaNext = this;
        }
      }
    }

    // local transaction optimization
    if (!_isXATransaction && flags != TMJOIN && _localTransaction != null) {
      try {
        if (log.isLoggable(Level.FINER))
          log.finer("begin-local-XA: " + xid + " " + _localTransaction);

        _localTransaction.begin();
      } catch (ResourceException e) {
        throw new XAExceptionWrapper(e);
      }

      _xid = xid;

      return;
    }

    if (_xaResource != null) {
      if (log.isLoggable(Level.FINER)) log.finer("start-XA: " + xid + " " + _xaResource);

      _xaResource.start(xid, flags);
      _isXATransaction = true;
    } else {
      if (log.isLoggable(Level.FINER))
        log.finer("start-XA with non XA resource: " + xid + " " + _xaResource);
    }

    _xid = xid;
  }
  /** Restores the delegation for the entire chain. */
  private void clearXid() {
    _xid = null;

    UserPoolItem shareHead = _shareHead;
    _shareHead = null;

    ManagedPoolItem xaPtr = _xaNext;
    _xaHead = null;
    _xaNext = null;

    UserPoolItem assignedUserItem = null;
    for (UserPoolItem ptr = shareHead; ptr != null; ptr = ptr.getShareNext()) {
      if (ptr.getOwnPoolItem() == this) {
        assignedUserItem = ptr;
        break;
      }
    }

    for (UserPoolItem ptr = shareHead; ptr != null; ptr = ptr.getShareNext()) {
      if (assignedUserItem == null && ptr.getOwnPoolItem() == null) {
        ptr.associatePoolItem(this);
        assignedUserItem = ptr;
      }

      try {
        ptr.reassociatePoolItem();
      } catch (Throwable e) {
        log.log(Level.WARNING, e.toString(), e);
      }
    }

    while (xaPtr != null) {
      ManagedPoolItem next = xaPtr._xaNext;
      xaPtr._xaNext = null;
      xaPtr._xaHead = null;

      xaPtr.clearXid();

      xaPtr = next;
    }

    if (assignedUserItem != null) {
      // _shareHead = assignedUserItem;
      // _shareHead.setShareNext(null);
    } else if (_hasConnectionError) {
      destroy();
    } else {
      toIdle();
    }
  }