docs: protected void complete(int endMode, boolean isCompleting) throws InconsistentLocalTranException, RolledbackException,
      IllegalStateException
      {
          if (tc.isEntryEnabled())
          {
              Tr.entry(tc, "complete",
                           (endMode == LocalTransactionCoordinator.EndModeCommit ? "Commit" : "Rollback") +
                           ", isCompleting="+isCompleting + " LTC=" + this);
          }
  
          try
          {
              if (_state != Running)
              {
                  final IllegalStateException ise = new IllegalStateException("Cannot complete LocalTransactionContainment. LocalTransactionCoordinator is completing or completed.");
                  FFDCFilter.processException(ise, "com.ibm.tx.ltc.LocalTranCoordImpl.complete", "715", this);
                  Tr.error(tc, "ERR_LTC_COMPLETE");
                  if (tc.isEntryEnabled()) Tr.exit(tc, "complete", ise);
                  throw ise;
              }
  
              // On WebSphere for z/OS we need to make sure that the unit
              // of work we are about to complete is associated with the
              // current thread of execution.  If we're not executing on
              // the current thread, the work done out of the registered
              // synchronizations will not be done on the right runtime
              // context.  This method should never fail unless we're
              // down an activity session path that we haven't coded for.
              ensureActive();
  
              // Only generate completion performance metrics if the following conditions hold:
              // 1. The performance metrics recorder is available
              // 2. At least one resource has been registered with the LTC (otherwise we would
              //    not have made the original started() call and the metrics would be damaged)
              boolean generateCommitMetrics = false;
              if (startTime != 0)
              {
              	generateCommitMetrics=true;
              	perfCommitRequested();
              }
  
              //
              // Need to fire synchronizations
              // if we are commiting the work.
              //
              // Defect 120540. Add check to see if LTC is completing.
              //
  
              // reset state for new completion
              _outcomeRollback = false;
  
              if ((endMode == EndModeCommit) && !_rollbackOnly)
              {
              	informSynchronizations(isCompleting);
              }
  
              // Defect 122329
              //
              // Change state once synchronizations have been called
              // to allow enlistment during beforeCompletion.
              //
              _state = Completing;
  
              //
              // Defect 115912. Need this check out here
              // so that the flag gets set when there
              // is no work to do.
              //
              if (_rollbackOnly || (endMode == EndModeRollBack))
              {
              	_outcomeRollback = true;
              }
  
              List<String> failures = null;
  
              if (_enlistedResources != null)
              {            
              	for (int i=0; i < _enlistedResources.size(); i++)
              	{
              		OnePhaseXAResource resource = _enlistedResources.get(i);
  
              		try
              		{
              			if (_outcomeRollback)
              			{
              				if (tc.isDebugEnabled()) Tr.debug(tc, "Calling rollback on resource " + resource);
              				resource.rollback(null);
              			}
              			else
              			{
              				if (tc.isDebugEnabled()) Tr.debug(tc, "Calling commit on resource " + resource);
              				resource.commit(null, true);
              			}
              		}
              		catch (XAException xe)
              		{
              			//
              			// Need to build up the failed resource list before throwing
              			//
              			FFDCFilter.processException(xe, "com.ibm.tx.ltc.LocalTranCoordImpl.complete", "593", this);
              			if (failures == null)
              			{
              				failures = new ArrayList<String>();
              			}
              			failures.add(resource.getResourceName());
  
              			Tr.error(tc, "ERR_XA_RESOURCE_COMPLETE", new Object[] {resource.getResourceName(), xe});
              		}
              	}
              }
  
              // Complete native unit of work
              // Provide abstract method to be overridden ?
              final String zosFailure = zosComplete();
              if (zosFailure != null)
              {
              	if (failures == null)
              	{
              		failures = new ArrayList<String>();
              	}
              	failures.add(zosFailure);
  
              }
  
              _state = Completed;
  
              //
              // Need to fire synchronizations even if
              // there is no work to be done.
              //
              informSynchronizations(isCompleting);
  
              //
              // Cleanup all our outstanding objects for
              // garbage collection.
              //
              _cleanupResources  = null;
              _enlistedResources = null;
              _syncs = null;
  
              //
              // Defect 120540. need to check if LTC is completing.
              //
              if (isCompleting)
              {
              	//
              	// Clear the ltc from the Thread context
              	//
              	// Only take off thread if already on
              	if (_current.getLocalTranCoord() == this)
              	{
              		if (tc.isDebugEnabled()) Tr.debug(tc, "Completed LTC is on thread so set current LTC to null");
              		_current.setCoordinator(null);
              	}
              }
              else
              {
              	// Recreate the structure for the native context
              	// provide overriden method here ????
              	zosReCreate();
  
              	//
              	// re-open the LTC for business
              	//
              	_state = Running;
  
              	// if we're not really completing the LTC (mid-AS checkpoint/reset) drive afterCompletion
              	// on the ContainerSync now that LTC can accept new enlistments
              	if (_containerSync != null) 
              	{
              		_containerSync.setCompleting(isCompleting);
  
              		if (_outcomeRollback)
              		{
              			_containerSync.afterCompletion(javax.transaction.Status.STATUS_ROLLEDBACK);
              		}
              		else
              		{
              			_containerSync.afterCompletion(javax.transaction.Status.STATUS_COMMITTED);
              		}
              	}
              }
  
              if (generateCommitMetrics)
              {
              	perfCompleted(0, startTime, !_outcomeRollback);
              }
  
              //
              // Defect 115015
              //
              // Need to throw any exceptions after all Synchronizations
              // have been informed to ensure any dependant cleanup takes
              // place.
              //
              if (failures != null)
              {
              	final String[] out = new String[failures.size()];
              	final InconsistentLocalTranException ilte = new InconsistentLocalTranException("Resource(s) failed to complete.", failures.toArray(out));
              	FFDCFilter.processException(ilte, "com.ibm.tx.ltc.LocalTranCoordImpl.complete", "914", this);
              	if (tc.isEntryEnabled()) Tr.exit(tc, "complete", ilte);
              	throw ilte;
              }
  
              if (_rollbackOnly && (endMode == EndModeCommit))
              {
              	final RolledbackException rbe = new RolledbackException("Resources rolled back due to setRollbackOnly.");
              	Tr.error(tc, "ERR_XA_RESOURCE_ROLLEDBACK");
              	if (tc.isEntryEnabled()) Tr.exit(tc, "complete", rbe);
              	throw rbe;
              }
          }
          finally
          {
              if(_current != null)
              {
                  if (tc.isDebugEnabled()) 
                    Tr.debug(tc, "Drive invokeEventListener processing");
                  _current.invokeEventListener(this, UOWEventListener.POST_END, null);
              }
              else
              {
          	if (tc.isDebugEnabled()) Tr.debug(tc, "current is null");
              }
          }
          
          // deal with uow exception -- subclass to handle in overriden complete method ????
  
          if (tc.isEntryEnabled()) Tr.exit(tc, "complete");
      }