/*
 *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 *  Copyright 2000-2007 Sun Microsystems, Inc. All rights reserved. 
 *
 *  The contents of this file are subject to the terms of either the GNU
 *  General Public License Version 2 only ("GPL") or the Common Development
 *  and Distribution License ("CDDL") (collectively, the "License").  You may
 *  not use this file except in compliance with the License.  You can obtain
 *  a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
 *  or mq/legal/LICENSE.txt.  See the License for the specific language
 *  governing permissions and limitations under the License.
 * 
 *  When distributing the software, include this License Header Notice in each
 *  file and include the License file at mq/legal/LICENSE.txt.  Sun designates
 *  this particular file as subject to the "Classpath" exception as provided by
 *  Sun in the GPL Version 2 section of the License file that accompanied this
 *  code.  If applicable, add the following below the License Header, with the
 *  fields enclosed by brackets [] replaced by your own identifying information:
 *  "Portions Copyrighted [year] [name of copyright owner]"
 * 
 *  Contributor(s):
 * 
 *  If you wish your version of this file to be governed by only the CDDL or
 *  only the GPL Version 2, indicate your decision by adding "[Contributor]
 *  elects to include this software in this distribution under the [CDDL or GPL
 *  Version 2] license."  If you don't indicate a single choice of license, a
 *  recipient has the option to distribute your version of this file under
 *  either the CDDL, the GPL Version 2 or  to extend the choice of license to
 *  its licensees as provided above.  However, if you add GPL Version 2 code
 *  and therefore, elected the GPL Version 2 license, then the option applies
 *  only if the new code is made subject to such option by the copyright holder. 
 *
 *  ResourceAdapter.java
 *
 *  @(#)ResourceAdapter.java	1.62 07/12/07
 */

package com.sun.messaging.jms.ra;

import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.jms.JMSException;
import javax.resource.NotSupportedException;
import javax.resource.ResourceException;
import javax.resource.spi.BootstrapContext;
import javax.resource.spi.ResourceAdapterInternalException;
import javax.resource.spi.endpoint.MessageEndpointFactory;
import javax.resource.spi.work.Work;
import javax.resource.spi.work.WorkManager;
import javax.transaction.xa.XAResource;

import com.sun.messaging.ConnectionConfiguration;
import com.sun.messaging.jmq.Version;
import com.sun.messaging.jmq.jmsservice.JMSService;
import com.sun.messaging.jmq.util.service.PortMapperClientHandler;
import com.sun.messaging.jms.blc.LifecycleManagedBroker;

/**
 * <p>This is JMSRA, the native JMS resource adapter for Glassfish Message
 * Queue.
 * <p>It can be used with or without MQ broker lifecycle support. 
 * This is determined by the value of the <tt>manageBrokerLifecycle</tt>
 * JavaBean property.
 * <p>If the property <tt>manageBrokerLifecycle</tt> is set to <tt>true</tt>
 * (default), then: 
 * <ul>
 * <li>this resource adapter will manage the starting and stopping
 * of a MQ broker. The brokerType property should be set to <tt>DIRECT</tt>/
 * <tt>EMBEDDED</tt>, <tt>LOCAL</tt> or <tt>REMOTE</tt> as required. 
 * If <tt>REMOTE</tt> is specified then it is assumed that the broker is already
 * running. <br>
 <li>it is legal to
 * set any of the properties needed to configure the broker lifecycle, even in
 * <tt>REMOTE</tt> mode (this is to support old versions of app server)<br>
 * </ul>
 * <p>If the property <tt>manageBrokerLifecycle</tt> is set to <tt>false</tt> then:
 * <ul>
 * <li>this resource adapter will not manage the starting and stopping of a MQ
 * broker and will expect a broker to be already running.<br>
 * <li>an attempt to
 * set any of the properties needed to configure the broker lifecycle will cause
 * an Exception.
 * </ul>
 */
public class ResourceAdapter implements javax.resource.spi.ResourceAdapter, javax.jms.ExceptionListener,
		java.io.Serializable, com.sun.messaging.jms.notification.EventListener {

	/**
	 * Whether this resource adapter should manage the broker lifecycle. See the
	 * class comment for more information.
	 */
	boolean manageBrokerLifecycle = true;

	/* Unique ID acquired from the broker that this RA connects to */
	// This ID is used to identify the 'Namespace' that this RA is generating
	// connections from.
	// The MQ Broker will enforce JMS Semantics of ClientID within 'Namespace'
	// but will allow sharing of the same ClientID in other 'Namespaces'.
	private String raUID = null;

	/* passed by the Java EE server; used by RA to acquire WorkManager etc. */
	private transient BootstrapContext b_context = null;

	/* WorkManager used to execute message delivery. */
	protected transient WorkManager workMgr = null;

	/* Indicates that RA was successfully started */
	private transient boolean started;
	private transient boolean stopping;

	/* hashmaps */
	private transient HashMap<Integer, MessageEndpointFactory> epFactories = null;
	private transient HashMap<Integer, EndpointConsumer> epConsumers = null;
	private transient HashMap<Integer, Integer> epFactoryToConsumer = null;

	/* IDs */
	private transient int _factoryID = 0;
	private transient int _consumerID = 0;

	/* the ConnectionFactory for this RA */
	private transient com.sun.messaging.XAConnectionFactory xacf = null;

	/* the Connection held by this RA */
	protected transient com.sun.messaging.jmq.jmsclient.XAConnectionImpl xac = null;

	/* the message listener method */
	private transient Method onMessage = null;

	/* flag to control logging during long reconnect attempts */
	private transient boolean logRCFailures = true;

	/* Loggers */
	private static transient final String _className = "com.sun.messaging.jms.ra.ResourceAdapter";
	protected static transient final String _lgrNameBase = "javax.resourceadapter.mqjmsra";
	protected static transient final String _lgrNameLifecycle = "javax.resourceadapter.mqjmsra.lifecycle";
	protected static transient final String _lgrNameInboundMessage = "javax.resourceadapter.mqjmsra.inbound.message";
	protected static transient final Logger _loggerB = Logger.getLogger(_lgrNameBase);
	protected static transient final Logger _loggerL = Logger.getLogger(_lgrNameLifecycle);
	protected static transient final Logger _loggerIM = Logger.getLogger(_lgrNameInboundMessage);
	protected static transient final String _lgrMIDPrefix = "MQJMSRA_RA";
	protected static transient final String _lgrMID_EET = _lgrMIDPrefix + "1001: ";
	protected static transient final String _lgrMID_INF = _lgrMIDPrefix + "1101: ";
	protected static transient final String _lgrMID_WRN = _lgrMIDPrefix + "2001: ";
	protected static transient final String _lgrMID_ERR = _lgrMIDPrefix + "3001: ";
	protected static transient final String _lgrMID_EXC = _lgrMIDPrefix + "4001: ";

	/* Non-Managed Connection Manager */
	protected static transient final com.sun.messaging.jms.ra.ConnectionManager _cm = new com.sun.messaging.jms.ra.ConnectionManager();

	/* Version Info */
	protected static transient final Version _version = new Version();

	/**
	 * Specifies whether the XAResource implementations provided by this RA
	 * should return isSameRM()=true if the resources are capable of being
	 * joined.
	 * 
	 * This field is initialised from a system property in start()
	 * 
	 */
	private static boolean isSameRMAllowed = true;

	/**
	 * Specifies whether we should revert to the original behaviour rather than
	 * apply the workarounds implemented in RFE 6882044 in which various calls
	 * to XAResource.start() and XAResource.end() were not sent to the broker.
	 */
	private static boolean isRevert6882044 = false;

	// Configurable attributes of the MQ RA //

	/** The UserName to be used for the MQ RA Connection */
	protected String userName = "guest";

	/** The Password to be used for the MQ RA Connection */
	protected String password = "guest";

	/* RA Failover controls */
	private boolean reconnectEnabled = false;
	private int reconnectInterval = 5000;
	private int reconnectAttempts = 6;
	private String addressListBehavior = "PRIORITY";
	private int addressListIterations = 1;
	private int maxLoopDelay = 120000;

	/* Indicate whether the RA is being used in the application client container */
	private boolean inAppClientContainer = false;

	/* Indicate whether the RA is being used in a clustered container */
	private boolean inClusteredContainer = false;

	/**
	 * Pass this value to setBrokerType() to specify that the broker type is
	 * REMOTE.<br/>
	 * This means that this instance will not manage a broker. Calling start()
	 * and stop() will have no effect.
	 */
	public static final String BROKER_TYPE_REMOTE = LifecycleManagedBroker.BROKER_TYPE_REMOTE;
	
	/**
	 * Pass this value to setBrokerType() to specify that the broker type is
	 * LOCAL.<br/>
	 * This means that when start() is called a broker will be started in a
	 * separate JVM, and a subsequent call to stop() will shut it down
	 */
	public static final String BROKER_TYPE_LOCAL = LifecycleManagedBroker.BROKER_TYPE_LOCAL;
	
	/**
	 * Pass this value to setBrokerType() to specify that the broker type is
	 * EMBEDDED.<br/>
	 * This means that when start() is called a broker will be started in the
	 * same JVM.<br/>
	 * Clients running in this JVM will connect to it using TCP connections.<br/>
	 * <b>Note, however, that currently if this value is specified then DIRECT
	 * will be used instead</b><br/>
	 */
	public static final String BROKER_TYPE_EMBEDDED = LifecycleManagedBroker.BROKER_TYPE_EMBEDDED;
	
	/**
	 * Pass this value to setBrokerType() to specify that the broker type is
	 * DIRECT.<br/>
	 * This means that when start() is called a broker will be started in the
	 * same JVM.<br/>
	 * Clients running in this JVM will connect to it using direct (non-TCP)
	 * connections.DB. <br/>
	 */
	public static final String BROKER_TYPE_DIRECT = LifecycleManagedBroker.BROKER_TYPE_DIRECT;
	// If DIRECT is passed in by app server then some sort of direct mode is
	// required
	// _useAPIDirectDefault() will then be called to determine which
	// implementation will be used, APIDIRECT or RADIRECT
	// note that the app server does not pass in APIDIRECT or RADIRECT directly
	protected static final String BROKER_TYPE_SOMEDIRECT = LifecycleManagedBroker.BROKER_TYPE_DIRECT;

	/**
	 * brokerType used internally to refer to the new direct mode implementation using standard JMS API
	 * <p>Note that the application server does not use this value directly 
	 */
	protected static final String BROKER_TYPE_APIDIRECT= "APIDIRECT";
	
	/**
	 * brokerType used internally to refer to the old direct mode implementation 
	 * <p>Note that the application server does not use this value directly
	 */
	protected static final String BROKER_TYPE_RADIRECT = "RADIRECT";

	/**
	 * This is the default value returned by _isDirectDefaultWhenStandalone() if the system
	 * property imq.jmsra.direct is not set See the comment on
	 * _isDirectDefaultWhenStandalone() for more information
	 */
	private static final String DIRECT_MODE_DEFAULT_STANDALONE = "true";
	
	/**
	 * This is the default value returned by _isDirectDefaultWhenClustered() if the system
	 * property imq.jmsra.direct.clustered is not set See the comment on
	 * _isDirectDefaultWhenClustered() for more information
	 */
	private static final String DIRECT_MODE_DEFAULT_CLUSTERED = "false";	

	/**
	 * This is the default value returned by _useAPIDirectImplementation if the
	 * system property imq.jmsra.apidirect is not set See the comment on
	 * _useAPIDirectImplementation() for more information
	 */
	private static final String APIDIRECT_MODE_DEFAULT = "false";

	/*
	 * * The Group Name assigned to this Resource Adapter.* Supports deployment
	 * scenarios where multiple instances of a group* are acting as a single
	 * logical unit for JMS semantics.* All ResourceAdapter instances in the
	 * group must have the same Group Name.
	 */
	private String groupName = null;

	/*
	 * The object that manages the lifecycle managed broker.
	 * 
	 * <br>This is created lazily if the resource adapter is configured to
	 * perform broker lifecycle management (that is, if
	 * <tt>setManageBrokerLifecycle(false)</tt> has not been called).<br>
	 * <br>
	 * Note if this property is set to <tt>true</tt> then a <tt>LifecycleManagedBroker</tt>
	 * is always created and configured, even if <tt>brokerType</tt> is set to <tt>REMOTE</tt>.<br>
	 * This is to support backwards compatibility when the caller may
	 * start setting broker lifecycle javabean properties before setting brokerType.
	 */
	private transient LifecycleManagedBroker lmb;

	public LifecycleManagedBroker getLifecycleManagedBroker() {
		if (lmb == null) {
			lmb = new LifecycleManagedBroker();
		}
		return lmb;
	}

	/*
	 * Indicate main port for broker when its lifecycle is controlled by the RA
	 * (also used by the RA itself)
	 */
	private int brokerPort = 7676;

	/*
	 * Indicate type for broker lifecycle control (also used by the RA itself)
	 */
	private String brokerType = ResourceAdapter.BROKER_TYPE_REMOTE;

	/* The ConnectionURL (used by both the RA and the managed broker) */
	private String connectionURL = "";

	/* Must declare public empty constructor */
	public ResourceAdapter() {
		_loggerL.entering(_className, "constructor()");
		started = false;
	}

	// ResourceAdapter interface methods //
	//

	/**
	 * <p>Starts this instance of the Resource Adapter. 
	 * <br>
	 * <p>If this resource adapter is configured to perform broker
	 * lifecycle management (i.e.<tt>setManageBrokerLifecycle(false)</tt> has not been called)
	 * and the configured broker type is not <tt>REMOTE</tt>, then this also starts the managed broker.
	 */
	public synchronized void start(BootstrapContext ctx) throws ResourceAdapterInternalException {

		_loggerL.entering(_className, "start()", ctx);

		isSameRMAllowed = Boolean.valueOf(System.getProperty("imq.jmsra.isSameRMAllowed", "true"));

		isRevert6882044 = Boolean.valueOf(System.getProperty("imq.jmsra.isRevert6882044", "false"));

		stopping = false;
		if (started) {
			_loggerL.warning(_lgrMID_WRN + "start:Previously started:Ignoring");
		} else {
			_loggerL.info(_lgrMID_INF + "SJSMQ JMS Resource Adapter starting: " + getPublicBrokerType());
			this.b_context = ctx;

			if (b_context != null) {
				workMgr = b_context.getWorkManager();
			}

			// Try to set inAppClientContainer correctly
			_adjustInAppClientContainer();

			this.xacf = new com.sun.messaging.XAConnectionFactory();

			if (!inAppClientContainer) {
				AccessController.doPrivileged(new PrivilegedAction<Object>() {
					public Object run() {
						System.setProperty("imq.DaemonThreads", "true");
						return null;
					}
				});
			}

			// if we have been configured to start a managed broker, start it
			if (isManageBrokerLifecycle() && !this._isRemote()) {
				getLifecycleManagedBroker().start();
			}
			try {
				// Configure RA ConnectionFactory
				configureFactory();
				// Create Connection if not RADIRECT
				if (!_isRADirect()) {
					xac = (com.sun.messaging.jmq.jmsclient.XAConnectionImpl) xacf.createXAConnection();
					_loggerL.fine(_lgrMID_INF + "start:cID=" + xac._getConnectionID());
					// Init the connection; set ExceptionListener etc.
					init();
				}
			} catch (JMSException jmse) {
				// We are about to fail the start
				// If we have just started a local broker then stop it
				if (getLifecycleManagedBroker().isStarted() && getLifecycleManagedBroker().isLocal()) {
					getLifecycleManagedBroker().stop();
				}

				ResourceAdapterInternalException raie = new ResourceAdapterInternalException(_lgrMID_EXC
						+ "start:Aborting:JMSException on createConnection=" + jmse.getMessage());
				raie.initCause(jmse);
				_loggerL.severe(raie.getMessage());
				jmse.printStackTrace();
				_loggerL.throwing(_className, "start()", raie);
				throw raie;
			}

			/* init hash maps */
			epFactories = new HashMap<Integer, MessageEndpointFactory>(10);
			epConsumers = new HashMap<Integer, EndpointConsumer>(10);
			epFactoryToConsumer = new HashMap<Integer, Integer>(10);

			_setOnMessageMethod();
			started = true;
			_loggerL.config(_lgrMID_INF + toString());
			_loggerL.config(_lgrMID_INF + "start:SJSMQ JMSRA Connection Factory Config="
					+ xacf.getCurrentConfiguration());
			_loggerL.info(_lgrMID_INF + "SJSMQ JMSRA Started:" + getPublicBrokerType());
		}
		_loggerL.exiting(_className, "start()");
	}

	/**
	 * <p>Stops this instance of the Resource Adapter. 
	 * <br>
	 * <p>If this resource adapter instance is configured to perform broker
	 * lifecycle management (i.e.<tt>setManageBrokerLifecycle(false)</tt> has not been called)
	 * and the configured broker type is not <tt>REMOTE</tt>, then this also stops the managed broker.
	 */
	public synchronized void stop() {

		_loggerL.entering(_className, "stop()");
		stopping = true;
		if (!started) {
			_loggerL.warning(_lgrMID_WRN + "stop:Previously stopped:Ignoring");
			// Thread.dumpStack();
		} else {
			_loggerL.info(_lgrMID_INF + "SJSMQ JMSRA stopping...");
			// remove all epConsumers
			removeAllConsumers();

			if (xac != null) {

				// close the RA connection.
				try {
					if (_loggerL.isLoggable(Level.FINER)) {
						_loggerL.finer(_lgrMID_INF + "stop:close:cID=" + xac._getConnectionID());
					}
					xac.close();
				} catch (JMSException jmse) {
					_loggerL.logp(Level.WARNING, _className, "stop()", _lgrMID_WRN + "Exception on close:Ignoring:",
							jmse);
					// jmse.printStackTrace();
				}
			}
			if (_cm != null) {
				_cm.destroyConnections();
			}

			// if we have been configured to start a managed broker, stop it
			if (isManageBrokerLifecycle() && !this._isRemote()) {
				getLifecycleManagedBroker().stop();
			}
			started = false;
		}
		_loggerL.info(_lgrMID_INF + "SJSMQ JMSRA stopped.");
		_loggerL.exiting(_className, "stop()");
	}

	/**
	 * Activate a message endpoint. Called by the Application Server when a
	 * message-driven bean is deployed.
	 * 
	 * {@inheritDoc}
	 */
	public void endpointActivation(MessageEndpointFactory endpointFactory, javax.resource.spi.ActivationSpec spec)
			throws NotSupportedException {
		Object params[] = new Object[2];
		params[0] = endpointFactory;
		params[1] = spec;

		_loggerIM.entering(_className, "endpointActivation()", params);
		if (!started) {
			_loggerIM.logp(Level.SEVERE, _className, "endpointActivation()", _lgrMID_EXC
					+ "MQJMSRA not started:Aborting:", params);
			NotSupportedException nse = new NotSupportedException(
					"MQJMSRA-endpointActivation:Error:RA not started:aborting");
			_loggerIM.throwing(_className, "endpointActivation()", nse);
			throw nse;
		}
		EndpointConsumer ec;

		if ((System.getProperty("imq.jmsra.endpoint.concurrent", "false")).equals("true")) {
			ec = new ConcurrentEndpointConsumer(this, endpointFactory, spec, this._isRADirect());
		} else {
			ec = new EndpointConsumer(this, endpointFactory, spec, this._isRADirect());
		}
		try {
			ec.startMessageConsumer();
			// if (this._isDirect()) {
			// ec.startDirectConsumer();
			// } else {
			// ec.createMessageConsumer(endpointFactory, spec);
			// }
			if (_loggerIM.isLoggable(Level.FINER)) {
				_loggerIM.finer(_lgrMID_INF + "endpointActivation:createMessageConsumer:DONE:" + "fID="
						+ ec.getFactoryID() + " cID=" + ec.getConsumerID());
			}
		} catch (Exception ex) {
			_loggerIM.logp(Level.SEVERE, _className, "endpointActivation()", _lgrMID_EXC + ":Failed due to:"
					+ ex.getMessage(), params);
			NotSupportedException nse = new NotSupportedException(
					"MQJMSRA-endpointActivation:Exception on createMessageConsumer:");
			nse.initCause(ex);
			_loggerIM.throwing(_className, "endpointActivation()", nse);
			throw nse;
		}
		_loggerIM.exiting(_className, "endpointActivation()");
	}

	/**
	 * Deactivates a message endpoint Called by the Application Server when a
	 * message-driven bean is undeployed.
	 * 
	 * {@inheritDoc}
	 */
	public void endpointDeactivation(MessageEndpointFactory endpointFactory, javax.resource.spi.ActivationSpec spec) {
		Object params[] = new Object[2];
		params[0] = endpointFactory;
		params[1] = spec;

		_loggerIM.entering(_className, "endpointDeactivation()", params);
		if (!started) {
			_loggerIM.logp(Level.SEVERE, _className, "endpointDeactivation()", _lgrMID_EXC
					+ "MQJMSRA not started:Aborting:", params);
		} else {
			// Can check spec against what the ec contains and error if not
			// correct kind or match
			int factoryID = matchMessageFactory(endpointFactory);
			if (factoryID != -1) {
				int consumerID = _getConsumerIDbyFactoryID(factoryID);
				EndpointConsumer ec = _getEndpointConsumer(consumerID);
				// System.out.println("MQJMSRA-endpointDeactivation:setting deactivated");
				ec.setDeactivated();

				try {
					// System.out.println("MQJMSRA-endpointDeactivation:stopping MessageConsumerfID="+factoryID+" cID="+consumerID+" spec=\n"+spec.toString());
					if (_loggerIM.isLoggable(Level.FINER)) {
						_loggerIM.finer(_lgrMID_INF + "endpointDeactivation:stopMessageConsumer:fID=" + factoryID
								+ " cID=" + consumerID);
					}
					ec.stopMessageConsumer();
					// System.out.println("MQJMSRA-endpointDeactivation:stopped MessageConsumer");
				} catch (Exception ex) {
					// No exception for this method, print
					// System.err.println("MQJMSRA-endpointDeactivation:Error:stopMessageConsumer exception:ignoring");
					_loggerIM.logp(Level.WARNING, _className, "endpointDeactivation()", _lgrMID_WRN
							+ "Exception on stopMessageConsumer:Ignoring:", ex);
					ex.printStackTrace();
				}
				// System.out.println("MQJMSRA-endpointDeactivation:removing from maps-fID="+factoryID);
				removeFromMaps(factoryID);
			} else {
				_loggerIM
						.log(Level.WARNING, _lgrMID_WRN + "endpointDeactivation:Ignoring:Not found:" + spec.toString());
			}
		}
		_loggerIM.exiting(_className, "endpointDeactivation()");
	}

	/**
	 * Returns the XAResource array that correspond to the ActivationSpec
	 * instances parameter. Called by the Application Server when it needs to
	 * determine transaction status for these message endpoints from the
	 * Resource Adapter.
	 * 
	 * {@inheritDoc}
	 */
	public javax.transaction.xa.XAResource[] getXAResources(javax.resource.spi.ActivationSpec[] specs)
			throws ResourceException {
		_loggerL.entering(_className, "getXAResources()");
		XAResource[] xar = new XAResource[0];
		_loggerL.exiting(_className, "getXAResources()");
		return xar;
	}

	// javax.jms.ExceptionListener interface method
	public void onException(JMSException exception) {
		_loggerL.entering(_className, "onException()", exception);
		_loggerL.warning(_lgrMID_WRN + "onException:Connection Failed:" + exception.getMessage());
		logRCFailures = true;
		int loopDelay = reconnectInterval;
		int loopCount = 0;

		while (started && !stopping) {
			// wait till initial interval expires
			try {
				Thread.sleep(loopDelay);
			} catch (Exception e) {
			}
			try {
				loopCount += 1;
				_loggerL.warning(_lgrMID_WRN + "onException:Reconnecting...Loop Attempt# " + loopCount + ":Delayed "
						+ loopDelay + " milliseconds.");
				xac = (com.sun.messaging.jmq.jmsclient.XAConnectionImpl) xacf.createXAConnection();
				// Init the connection; set ExceptionListener etc.
				init();
				_loggerL.warning(_lgrMID_WRN + "onException:Reconnect successfull on loop# " + loopCount);
				break;
			} catch (JMSException jmse) {
				if (logRCFailures) {
					_loggerL.severe(_lgrMID_WRN + "onException:Reconnect unsuccessfull on loop# " + loopCount + ":"
							+ jmse.getMessage());
					jmse.printStackTrace();
				} else {
					_loggerL.severe(_lgrMID_WRN + "onException:Reconnect unsuccessfull on loop# " + loopCount);
				}
				logRCFailures = false;
				if (loopDelay < maxLoopDelay) {
					loopDelay *= 3;
					if (loopDelay > maxLoopDelay)
						loopDelay = maxLoopDelay;
				}
			}
		}
		_loggerL.exiting(_className, "onException()");
	}

	// com.sun.messaging.jms.notification.EventListener interface method
	public void onEvent(com.sun.messaging.jms.notification.Event evnt) {
		_loggerL.entering(_className, "onEvent()", evnt);
		_loggerL.info(_lgrMID_INF + "onEvent:Connection Event:" + (evnt == null ? "null" : evnt.toString()));
	}

	/**
	 * Sets the UserName for this ResourceAdapter instance
	 * 
	 * @param userName
	 *            The UserName
	 */
	public synchronized void setUserName(String userName) {
		_loggerL.entering(_className, "setUserName()", userName);
		this.userName = userName;
	}

	/**
	 * Return the UserName for this ResourceAdapter instance
	 * 
	 * @return The UserName
	 */
	public String getUserName() {
		_loggerL.entering(_className, "getUserName()", userName);
		return userName;
	}

	/**
	 * Sets the Password for this ResourceAdapter instance
	 * 
	 * @param password
	 *            The Password
	 */
	public synchronized void setPassword(String password) {
		_loggerL.entering(_className, "setPassword()");
		this.password = password;
	}

	/**
	 * Return the Password for this ResourceAdapter instance
	 * 
	 * @return The Password
	 */
	public String getPassword() {
		_loggerL.entering(_className, "getPassword()");
		return password;
	}

	/**
	 * Sets the Reconnect behavior for this Resource Adapter
	 * 
	 * @param reconnectEnabled
	 *            if true, enables reconnect behavior
	 */
	public synchronized void setReconnectEnabled(boolean reconnectEnabled) {
		_loggerL.entering(_className, "setReconnectEnabled()", Boolean.toString(reconnectEnabled));
		this.reconnectEnabled = reconnectEnabled;
	}

	/**
	 * Returns the Reconnect behavior for this Resource Adapter
	 * 
	 * @return the Reconnect behavior for this Resource Adapter
	 */
	public boolean getReconnectEnabled() {
		_loggerL.entering(_className, "getReconnectEnabled()", Boolean.toString(reconnectEnabled));
		return reconnectEnabled;
	}

	/**
	 * Sets the Reconnect interval for this Resource Adapter
	 * 
	 * @param reconnectInterval
	 *            The reconnect interval in milliseconds when reconnect is
	 *            enabled
	 */
	public synchronized void setReconnectInterval(int reconnectInterval) {
		_loggerL.entering(_className, "setReconnectInterval()", Integer.toString(reconnectInterval));
		this.reconnectInterval = reconnectInterval;
	}

	/**
	 * Returns the Reconnect interval for this Resource Adapter
	 * 
	 * @return the Reconnect interval for this Resource Adapter
	 */
	public int getReconnectInterval() {
		_loggerL.entering(_className, "getReconnectInterval()", Integer.toString(reconnectInterval));
		return reconnectInterval;
	}

	/**
	 * Sets the reconnectAttempts for this Resource Adapter
	 * 
	 * @param reconnectAttempts
	 *            The number of reconnect attempts when reconnect is enabled
	 */
	public synchronized void setReconnectAttempts(int reconnectAttempts) {
		_loggerL.entering(_className, "setReconnectAttempts()", Integer.toString(reconnectAttempts));
		this.reconnectAttempts = reconnectAttempts;
	}

	/**
	 * Returns the Reconnect attempts for this Resource Adapter
	 * 
	 * @return the reconnectAttempts for this Resource Adapter
	 */
	public int getReconnectAttempts() {
		_loggerL.entering(_className, "getReconnectAttempts()", Integer.toString(reconnectAttempts));
		return reconnectAttempts;
	}

	/**
	 * Sets the addressListBehavior for this Resource Adapter
	 * 
	 * @param addressListBehavior
	 *            The behavior of connectionURL or addressList on connection
	 *            establishment
	 */
	public synchronized void setAddressListBehavior(String addressListBehavior) {
		_loggerL.entering(_className, "setAddressListBehavior()", addressListBehavior);
		if ("RANDOM".equalsIgnoreCase(addressListBehavior)) {
			this.addressListBehavior = "RANDOM";
			;
		} else {
			this.addressListBehavior = "PRIORITY";
		}
	}

	/**
	 * Returns the addressListBehavior for this Resource Adapter
	 * 
	 * @return the addressListBehavior for this Resource Adapter
	 */
	public String getAddressListBehavior() {
		_loggerL.entering(_className, "getAddressListBehavior()", addressListBehavior);
		return addressListBehavior;
	}

	/**
	 * Sets the addressListIterations for this Resource Adapter
	 * 
	 * @param addressListIterations
	 *            The number of iterations on addressList to be attempted on
	 *            connection establishment
	 */
	public synchronized void setAddressListIterations(int addressListIterations) {
		_loggerL.entering(_className, "setAddressListIterations()", Integer.toString(addressListIterations));
		if (addressListIterations < 1) {
			_loggerL.warning(_lgrMID_WRN + "setAddressListIterations:Invalid value:"
					+ Integer.toString(addressListIterations) + ":Setting to 1");
			this.addressListIterations = 1;
		} else {
			this.addressListIterations = addressListIterations;
		}
	}

	/**
	 * Returns the addressListIterations for this Resource Adapter
	 * 
	 * @return the addressListIterations for this Resource Adapter
	 */
	public int getAddressListIterations() {
		_loggerL.entering(_className, "getAddressListIterations()", Integer.toString(addressListIterations));
		return addressListIterations;
	}

	/**
	 * Sets the Resource Adapter for use in the Application Client Container
	 * 
	 * @param inAppClientContainer
	 *            if true, indicates that it is in the ACC
	 */
	public synchronized void setInAppClientContainer(boolean inAppClientContainer) {
		_loggerL.entering(_className, "setInAppClientContainer()", Boolean.toString(inAppClientContainer));
		this.inAppClientContainer = inAppClientContainer;
		_adjustInAppClientContainer();
	}

	/**
	 * Return whether the Resource Adapter is being used in the App Client Cont.
	 * 
	 * @return true if being used in the App Client Cont.
	 */
	public boolean getInAppClientContainer() {
		_loggerL.entering(_className, "getInAppClientContainer()", Boolean.toString(inAppClientContainer));
		return inAppClientContainer;
	}

	/**
	 * Sets the RA for use in a Clustered Java EE Container
	 * 
	 * @param inClusteredContainer
	 *            if true, indicates that it is in a Clustered Java EE Containe.
	 */
	public synchronized void setInClusteredContainer(boolean inClusteredContainer) {
		_loggerL.entering(_className, "setInClusteredContainer()", Boolean.toString(inClusteredContainer));
		this.inClusteredContainer = inClusteredContainer;
	}

	/**
	 * Return whether this RA is being used in a Clustered Java EE Container.
	 * 
	 * @return true if being used in a Clustered Java EE Container.
	 */
	public boolean getInClusteredContainer() {
		_loggerL.entering(_className, "getInClusteredContainer()", Boolean.toString(inClusteredContainer));
		return inClusteredContainer;
	}

	/**
	 * Sets the groupName for this ResourceAdapter
	 * 
	 * @param groupName
	 *            The Group Name
	 */
	public synchronized void setGroupName(String groupName) {
		_loggerL.entering(_className, "setGroupName()", groupName);
		this.groupName = groupName;
	}

	/**
	 * Returns the groupName for this ResourceAdapter
	 * 
	 * @return The groupName
	 */
	public String getGroupName() {
		_loggerL.entering(_className, "getGroupName()", groupName);
		return groupName;
	}
	
	
	/**
	 * Specifies how this resource adapter will connect to the MQ broker. Possible values of brokerType are: 
	 * <ul>
	 * <li><tt>LOCAL</tt> ({@link #BROKER_TYPE_LOCAL BROKER_TYPE_LOCAL}) - A normal TCP connection will be used<br/>
	 * <li><tt>EMBEDDED</tt> ({@link #BROKER_TYPE_EMBEDDED BROKER_TYPE_EMBEDDED}) -- A broker will be started in the same JVM. Identical to <tt>DIRECT</tt>.
	 * <li><tt>DIRECT</tt> ({@link #BROKER_TYPE_DIRECT BROKER_TYPE_DIRECT}) - A broker will be started in the same JVM. Identical to <tt>EMBEDDED</tt>
	 * <li><tt>REMOTE</tt> ({@link #BROKER_TYPE_REMOTE BROKER_TYPE_REMOTE}) - No broker will be started. 
	 * Calling <tt>start()</tt> and <tt>stop()<tt> will have no effect.
	 * </ul>
	 * @param brokerType One of <tt>LOCAL</tt>,<tt>EMBEDDED</tt>,<tt>DIRECT</tt> or <tt>REMOTE</tt>.
	 */

	/**
	 * Sets the brokerType for this ResourceAdapter
	 * 
	 * <br>
	 * If this broker is being used to perform broker lifecycle management then
	 * this is also passed to the underlying <tt>LifecycleManagedBroker</tt>.
	 * 
	 * @param brokerType
	 *            The type of the broker that this RA associates with
	 */
	public synchronized void setBrokerType(String brokerType) {
		_loggerL.entering(_className, "setBrokerType()", brokerType);

		if (started) {
			_loggerL.warning(_lgrMID_WRN + "setBrokerType:RA already started:Disallowing change from:"
					+ this.brokerType + ":to:" + brokerType);
			return;
		}

		if ((BROKER_TYPE_SOMEDIRECT.equals(brokerType)) || (BROKER_TYPE_EMBEDDED.equals(brokerType))) {
			// either direct or embedded
			if (getInClusteredContainer()){
				// clustered
				if (ResourceAdapter._isDirectDefaultWhenClustered()) {
					// force to direct (RADirect)
					this.brokerType = BROKER_TYPE_SOMEDIRECT;
				} else {
					// force to embedded (TCP)
					this.brokerType = BROKER_TYPE_EMBEDDED;
				}
			} else {
				// standalone
				if (ResourceAdapter._isDirectDefaultWhenStandalone()) {
					// force to direct (RADirect)
					this.brokerType = BROKER_TYPE_SOMEDIRECT;
				} else {
					// force to embedded (TCP)
					this.brokerType = BROKER_TYPE_EMBEDDED;
				}
			}
			
			if (BROKER_TYPE_SOMEDIRECT.equals(this.brokerType)) {
				// direct mode was specified or forced
				if (ResourceAdapter._useAPIDirectImplementation()) {
					// use new DIRECT mode implementation
					_loggerL.fine(_lgrMID_INF + " Using new API DIRECT mode");
					this.brokerType = BROKER_TYPE_APIDIRECT;
				} else {
					// Using old DIRECT mode implementation
					_loggerL.fine(_lgrMID_INF + " Using old JMSRA DIRECT mode");
					this.brokerType = BROKER_TYPE_RADIRECT;
				}
			}
		} else {
			if ((BROKER_TYPE_LOCAL.equals(brokerType)) || (BROKER_TYPE_REMOTE.equals(brokerType))) {
				// either local or remote
				this.brokerType = brokerType;
			} else {
				_loggerL.warning(_lgrMID_WRN + "setBrokerType:Invalid value:" + brokerType
						+ ":remaining at brokerType=" + this.brokerType);
			}
		}

		if (isManageBrokerLifecycle()) {
			getLifecycleManagedBroker().setBrokerType(brokerType);
		}
	}

	/**
	 * Returns the brokerType for this ResourceAdapter
	 * 
	 * @return The brokerType
	 */
	public String getBrokerType() {
		_loggerL.entering(_className, "getBrokerType()", brokerType);
		return brokerType;
	}

	/**
	 * Return the public string corresponding to the specified broker type
	 * 
	 * Returns one of DIRECT, EMBEDDED, REMOTE or LOCAL Note that if the broker
	 * type is RADIRECT or APIDIRECT, DIRECT is returned
	 * 
	 * @return
	 */
	private String getPublicBrokerType() {
		String result;
		if (_isAnyDirect()) {
			result = BROKER_TYPE_SOMEDIRECT;
		} else {
			result = getBrokerType();
		}
		return result;
	}

	/**
	 * Sets the brokerInstanceName for this ResourceAdapter.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param brokerInstanceName
	 *            The Instance Name that the broker must use
	 */
	public synchronized void setBrokerInstanceName(String brokerInstanceName) {
		checkManaged();
		_loggerL.entering(_className, "setBrokerInstanceName()", brokerInstanceName);
		getLifecycleManagedBroker().setBrokerInstanceName(brokerInstanceName);
	}

	/**
	 * Returns the brokerInstanceName for this ResourceAdapter.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return The brokerInstanceName
	 */
	public String getBrokerInstanceName() {
		checkManaged();
		String result = getLifecycleManagedBroker().getBrokerInstanceName();
		_loggerL.entering(_className, "getBrokerInstanceName()", result);
		return result;
	}

	/**
	 * Sets the brokerBindAddress for both this ResourceAdapter instance and for
	 * any managed broker.
	 * <br>
	 * <p>Also used to construct (when a managed broker is being used) the value returned by <tt>_getEffectiveConnectionURL</tt>.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param brokerBindAddress
	 *            The network address that the broker must bind to
	 */
	public synchronized void setBrokerBindAddress(String brokerBindAddress) {
		checkManaged();
		_loggerL.entering(_className, "setBrokerBindAddress()", brokerBindAddress);
		getLifecycleManagedBroker().setBrokerBindAddress(brokerBindAddress);
	}

	/**
	 * Returns the brokerBindAddress for both this ResourceAdapter instance and
	 * for any managed broker.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return The brokerBindAddress
	 */
	public String getBrokerBindAddress() {
		checkManaged();
		String brokerBindAddress = getLifecycleManagedBroker().getBrokerBindAddress();
		_loggerL.entering(_className, "getBrokerBindAddress()", brokerBindAddress);
		return brokerBindAddress;

	}

	/**
	 * Sets the port used by a managed broker
	 * <br>
	 * <p>Also used to construct (when a managed broker is being used) the value returned by <tt>_getEffectiveConnectionURL</tt>.
     *
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param brokerPort The port used by a managed broker
	 */
	public synchronized void setBrokerPort(int brokerPort) {
		checkManaged();
		_loggerL.entering(_className, "setBrokerPort()", new Integer(brokerPort));
		if (started) {
			_loggerL.warning(_lgrMID_WRN + "setBrokerPort:RA already started:Disallowing change from:"
					+ this.brokerPort + ":to:" + brokerPort);
			return;
		}
		this.brokerPort = brokerPort;
		
		if (isManageBrokerLifecycle()) {
			getLifecycleManagedBroker().setBrokerPort(brokerPort);
		}
	}

	/**
	 * <p>Returns the port used by a managed broker
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle management.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return  The port used by a managed broker
	 */
	public int getBrokerPort() {
		checkManaged();
		_loggerL.entering(_className, "getBrokerPort()", new Integer(brokerPort));
		return brokerPort;
	}

	/**
	 * Sets the ConnectionURL used by this ResourceAdapter instance
	 * 
	 * <br>
	 * If this broker is being used to perform broker lifecycle management then
	 * this is also passed to the underlying <tt>LifecycleManagedBroker</tt>.
	 * 
	 * @param connectionURL
	 *            The ConnectionURL
	 */
	public synchronized void setConnectionURL(String connectionURL) {
		// XXX: work around this Logger API stripping the String after the 1st
		// 'space'
		String tConnectionURL = connectionURL;
		_loggerL.entering(_className, "setConnectionURL()", tConnectionURL);
		this.connectionURL = connectionURL;
		if (isManageBrokerLifecycle()) {
			getLifecycleManagedBroker().setConnectionURL(connectionURL);
		}
	}

	/**
	 * Return the ConnectionURL for both this ResourceAdapter instance and for
	 * any managed broker
	 * 
	 * @return The ConnectionURL
	 */
	public String getConnectionURL() {
		_loggerL.entering(_className, "getConnectionURL()", connectionURL);
//		if ("".equals(connectionURL)) {
//			_loggerL.fine(_lgrMID_INF + "getConnectionURL:returning default of 'localhost' for empty connectionURL");
//			// Nigel: Not sure when this is needed
//			return "localhost";
//		} else {
			return connectionURL;
//		}
	}

	/**
	 * Sets the brokerHomeDir for this ResourceAdapter.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param brokerHomeDir
	 *            The Broker Home Directory
	 */
	public synchronized void setBrokerHomeDir(String brokerHomeDir) {
		checkManaged();
		_loggerL.entering(_className, "setBrokerHomeDir()", brokerHomeDir);
		getLifecycleManagedBroker().setBrokerHomeDir(brokerHomeDir);
	}

	/**
	 * Returns the brokerHomeDir for this ResourceAdapter.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return The brokerHomeDir
	 */
	public String getBrokerHomeDir() {
		checkManaged();
		String result = getLifecycleManagedBroker().getBrokerHomeDir();
		_loggerL.entering(_className, "getBrokerHomeDir()", result);
		return result;
	}

	/**
	 * Sets the brokerVarDir for this ResourceAdapter.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param brokerVarDir
	 *            The Broker VarDir Directory
	 */
	public synchronized void setBrokerVarDir(String brokerVarDir) {
		checkManaged();
		_loggerL.entering(_className, "setBrokerVarDir()", brokerVarDir);
		getLifecycleManagedBroker().setBrokerVarDir(brokerVarDir);
	}

	/**
	 * Returns the brokerVarDir for this ResourceAdapter.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return The brokerVarDir
	 */
	public String getBrokerVarDir() {
		checkManaged();
		String result = getLifecycleManagedBroker().getBrokerVarDir();
		_loggerL.entering(_className, "getBrokerVarDir()", result);
		return result;
	}

	/**
	 * Sets the brokerLibDir for this ResourceAdapter.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param brokerLibDir
	 *            The Broker LibDir Directory
	 */
	public synchronized void setBrokerLibDir(String brokerLibDir) {
		checkManaged();
		_loggerL.entering(_className, "setBrokerLibDir()", brokerLibDir);
		getLifecycleManagedBroker().setBrokerLibDir(brokerLibDir);
	}

	/**
	 * Returns the brokerLibDir for this ResourceAdapter.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return The brokerLibDir
	 */
	public String getBrokerLibDir() {
		checkManaged();
		String result = getLifecycleManagedBroker().getBrokerLibDir();
		_loggerL.entering(_className, "getBrokerLibDir()", result);
		return result;
	}

	/**
	 * Sets the brokerJavaDir for this ResourceAdapter.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param brokerJavaDir
	 *            The Broker JavaDir Directory
	 */
	public synchronized void setBrokerJavaDir(String brokerJavaDir) {
		checkManaged();
		_loggerL.entering(_className, "setBrokerJavaDir()", brokerJavaDir);
		getLifecycleManagedBroker().setBrokerJavaDir(brokerJavaDir);
	}

	/**
	 * Returns the brokerJavaDir for this ResourceAdapter.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return The brokerJavaDir
	 */
	public String getBrokerJavaDir() {
		checkManaged();
		String result = getLifecycleManagedBroker().getBrokerJavaDir();
		_loggerL.entering(_className, "getBrokerJavaDir()", result);
		return result;
	}

	/**
	 * Sets the brokerArgs for this ResourceAdapter.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param brokerArgs
	 *            The extra cmd line args to be used for the broker that this RA
	 *            controls
	 */
	public synchronized void setBrokerArgs(String brokerArgs) {
		checkManaged();
		_loggerL.entering(_className, "setBrokerArgs()", brokerArgs);
		getLifecycleManagedBroker().setBrokerArgs(brokerArgs);
	}

	/**
	 * Returns the brokerArgs for this ResourceAdapter.
	 * 
	 * <p><i>Note:</i> This method is only needed when the resource adapter is
	 * performing broker lifecycle management (that is, when
	 * <tt>setManageBrokerLifecycle(false)</tt> has not been called).<br>
	 * <br>
	 * If this method is called after <tt>setManageBrokerLifecycle(false)</tt>
	 * has been called then an <tt>IllegalOperationException</tt> will be
	 * thrown.<br>
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return The brokerArgs
	 */
	public String getBrokerArgs() {
		checkManaged();
		String result = getLifecycleManagedBroker().getBrokerArgs();
		_loggerL.entering(_className, "getBrokerArgs()", result);
		return result;
	}

	/**
	 * Sets the masterBroker for this ResourceAdapter.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param masterBroker
	 *            The masterBroker that the Resource Adapter must use
	 */
	public synchronized void setMasterBroker(String masterBroker) {
		checkManaged();
		_loggerL.entering(_className, "setMasterBroker()", masterBroker);
		getLifecycleManagedBroker().setMasterBroker(masterBroker);
	}

	/**
	 * Returns the masterBroker for this ResourceAdapter.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return The masterBroker
	 */
	public String getMasterBroker() {
		checkManaged();
		String result = getLifecycleManagedBroker().getMasterBroker();
		_loggerL.entering(_className, "getMasterBroker()", result);
		return result;
	}

	/**
	 * Specify the maximum time allowed for a local broker to start.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param brokerStartTimeout
	 *            the maximum time allowed for a local broker to start
	 */
	public void setBrokerStartTimeout(int brokerStartTimeout) {
		checkManaged();
		_loggerL.entering(_className, "setBrokerStartTimeout()", brokerStartTimeout);
		getLifecycleManagedBroker().setBrokerStartTimeout(brokerStartTimeout);
	}

	/**
	 * Return the maximum time allowed for a local broker to start.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * 
	 * @return the maximum time allowed for a local broker to start
	 */
	public int getBrokerStartTimeout() {
		checkManaged();
		int result = getLifecycleManagedBroker().getBrokerStartTimeout();
		_loggerL.entering(_className, "getBrokerStartTimeout()", result);
		return result;
	}

	/**
	 * Sets the admin Username for both this ResourceAdapter instance and for
	 * any managed broker.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param adminUsername
	 *            The adminUsername
	 */
	public synchronized void setAdminUsername(String adminUsername) {
		checkManaged();
		_loggerL.entering(_className, "setAdminUsername()", adminUsername);
		getLifecycleManagedBroker().setAdminUsername(adminUsername);
	}

	/**
	 * Return the adminUsername for both this ResourceAdapter instance and for
	 * any managed broker.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return The adminUsername
	 */
	public String getAdminUsername() {
		checkManaged();
		String adminUsername = getLifecycleManagedBroker().getAdminUsername();
		_loggerL.entering(_className, "getAdminUsername()", adminUsername);
		return adminUsername;
	}

	/**
	 * Sets the admin Password for both this ResourceAdapter instance and for
	 * any managed broker.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param adminPassword
	 *            The adminPassword
	 */
	public synchronized void setAdminPassword(String adminPassword) {
		checkManaged();
		_loggerL.entering(_className, "setAdminPassword()", adminPassword);
		getLifecycleManagedBroker().setAdminPassword(adminPassword);
	}

	/**
	 * Return the adminPassword for both this ResourceAdapter instance and for
	 * any managed broker.
	 * 
	 * <p><i>Note:</i> This method is only needed when the resource adapter is
	 * performing broker lifecycle management (that is, when
	 * <tt>setManageBrokerLifecycle(false)</tt> has not been called).<br>
	 * <br>
	 * 
	 * @return The adminPassword
	 */
	public String getAdminPassword() {
		String adminPassword = getLifecycleManagedBroker().getAdminPassword();
		_loggerL.entering(_className, "getAdminUsername()", adminPassword);
		return adminPassword;
	}

	/**
	 * Sets the admin Password File for this ResourceAdapter instance.<br>
	 * <br>
	 * <i>Note:</i> This method is deprecated. The method <tt>setBrokerProps()</tt>
	 * should be used instead to pass password properties to the managed broker<br>
	 * <br>
	 * <i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param adminPassFile
	 *            The adminPassFile
	 */
	@Deprecated
	public synchronized void setAdminPassFile(String adminPassFile) {
		checkManaged();
		_loggerL.entering(_className, "setAdminPassFile()", adminPassFile);
		getLifecycleManagedBroker().setAdminPassFile(adminPassFile);
	}

	/**
	 * Return the admin Password File for the lifecycle managed broker.<br/>
	 * <br/>
	 * This method is deprecated because the corresponding setter method is deprecated.<br/>
	 * <br/> 
	 * <i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return The adminPassFile
	 */
	@Deprecated
	public String getAdminPassFile() {
		checkManaged();

		String result = getLifecycleManagedBroker().getAdminPassFile();
		_loggerL.entering(_className, "getAdminPassFile()", result);
		return result;
	}
	
	/**
	 * Return the JMXConnectorEnv for the broker that this RA is configured to
	 * connect to.
	 * 
	 * This is a HashMap whose key is "jmx.remote.credentials" and whose
	 * corresponding value is a string array containing admin username and admin
	 * password
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return The JMXConnectorEnv
	 */
	public synchronized HashMap getJMXConnectorEnv() {
		checkManaged();
		HashMap result = getLifecycleManagedBroker().getJMXConnectorEnv();
		_loggerL.entering(_className, "getJMXConnectorEnv()", result);
		return result;
	}

	/**
	 * Return the JMXServiceURLList for the brokers that this RA is configured
	 * to connect to. This is a String that can be used to acquire JMX
	 * connections to all brokers specified on connectionURL.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return The JMXServiceURLList
	 */
	public synchronized String getJMXServiceURLList() {
		checkManaged();
		_loggerL.entering(_className, "getJMXServiceURLList()", "For addressList = " + getConnectionURL());
		String jmxServiceURLList = getLifecycleManagedBroker().getJMXServiceURLList();
		_loggerL.exiting(_className, "getJMXServiceURLList()", jmxServiceURLList);
		return jmxServiceURLList;
	}

	/**
	 * Return the JMXServiceURL for the broker that this RA is configured to
	 * connect to This is a String that can be used to acquire JMX connections
	 * 
	 * Returns null if the broker is REMOTE
	 * 
	 * @return The JMXServiceURL
	 */
	public synchronized String getJMXServiceURL() {
		checkManaged();
		_loggerL.entering(_className, "getJMXServiceURL()");
		return getLifecycleManagedBroker().getJMXServiceURL();
	}

	/**
	 * Sets useJNDIRmiServiceURL for this ResourceAdapter instance.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param useJNDIRmiServiceURL
	 *            The boolean value of useJNDIRmiServiceURL
	 */
	public synchronized void setUseJNDIRmiServiceURL(boolean useJNDIRmiServiceURL) {
		checkManaged();
		_loggerL.entering(_className, "setUseJNDIRmiServiceURL()", new Boolean(useJNDIRmiServiceURL));
		getLifecycleManagedBroker().setUseJNDIRmiServiceURL(useJNDIRmiServiceURL);
	}

	/**
	 * Return useJNDIRmiServiceURL of this ResourceAdapter instance
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return The useJNDIRmiServiceURL
	 */
	public boolean getUseJNDIRmiServiceURL() {
		checkManaged();
		boolean result = getLifecycleManagedBroker().getUseJNDIRmiServiceURL();
		_loggerL.entering(_className, "getUseJNDIRmiServiceURL()", new Boolean(result));
		return result;
	}

	/**
	 * Sets the startRmiRegistry for this ResourceAdapter.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param startRmiRegistry
	 *            The RMI Registry Port
	 */
	public synchronized void setStartRmiRegistry(boolean startRmiRegistry) {
		checkManaged();
		_loggerL.entering(_className, "setStartRmiRegistry()", new Boolean(startRmiRegistry));
		getLifecycleManagedBroker().setStartRmiRegistry(startRmiRegistry);
	}

	/**
	 * Returns the startRmiRegistry for this ResourceAdapter.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return startRmiRegistry
	 */
	public boolean getStartRmiRegistry() {
		checkManaged();
		boolean result = getLifecycleManagedBroker().getStartRmiRegistry();
		_loggerL.entering(_className, "getStartRmiRegistry()", new Boolean(result));
		return result;
	}

	/**
	 * Sets the rmiRegistryPort for this ResourceAdapter.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param rmiRegistryPort
	 *            The RMI Registry Port
	 */
	public synchronized void setRmiRegistryPort(int rmiRegistryPort) {
		checkManaged();
		_loggerL.entering(_className, "setRmiRegistryPort()", new Integer(rmiRegistryPort));
		getLifecycleManagedBroker().setRmiRegistryPort(rmiRegistryPort);
	}

	/**
	 * Returns the rmiRegistryPort for this ResourceAdapter
	 * 
	 * @return The rmiRegistryPort
	 */
	public int getRmiRegistryPort() {
		checkManaged();
		int result = getLifecycleManagedBroker().getRmiRegistryPort();
		_loggerL.entering(_className, "getRmiRegistryPort()", new Integer(result));
		return result;
	}

	/**
	 * Sets useSSLJMXConnector for this ResourceAdapter instance.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param useSSLJMXConnector
	 *            The boolean value of useSSLJMXConnector
	 */
	public synchronized void setUseSSLJMXConnector(boolean useSSLJMXConnector) {
		checkManaged();
		_loggerL.entering(_className, "setUseSSLJMXConnector()", new Boolean(useSSLJMXConnector));
		getLifecycleManagedBroker().setUseSSLJMXConnector(useSSLJMXConnector);
	}

	/**
	 * Return useSSLJMXConnector of this ResourceAdapter instance.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle management.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return The useSSLJMXConnector
	 */
	public boolean getUseSSLJMXConnector() {
		checkManaged();
		boolean result = getLifecycleManagedBroker().getUseSSLJMXConnector();
		_loggerL.entering(_className, "getUseSSLJMXConnector()", new Boolean(result));
		return result;
	}

	/**
	 * Sets brokerEnableHA for this ResourceAdapter instance.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle management.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param brokerEnableHA
	 *            The boolean value of brokerEnableHA
	 */
	public synchronized void setBrokerEnableHA(boolean brokerEnableHA) {
		checkManaged();
		_loggerL.entering(_className, "setBrokerEnableHA()", new Boolean(brokerEnableHA));
		getLifecycleManagedBroker().setBrokerEnableHA(brokerEnableHA);
	}
	

	

	/**
	 * Return brokerEnableHA of this ResourceAdapter instance.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle management.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return The brokerEnableHA
	 */
	public boolean getBrokerEnableHA() {
		checkManaged();
		boolean result = getLifecycleManagedBroker().getBrokerEnableHA();
		_loggerL.entering(_className, "getBrokerEnableHA()", new Boolean(result));
		return result;
	}
	
	
	/**
	 * Set the value that, if set, is used to set the broker property imq.cluster.nowaitForMasterBrokerTimeoutInSeconds 
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle lmanagement.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param i
	 */
	public void setNowaitForMasterBrokerTimeoutInSeconds(int i) {
		checkManaged();
		_loggerL.entering(_className, "setNowaitForMasterBrokerTimeoutInSeconds()", i);
		getLifecycleManagedBroker().setNowaitForMasterBrokerTimeoutInSeconds(i);
	}
	
	/**
	 * Return the value that, if set, is used to set the broker property imq.cluster.nowaitForMasterBrokerTimeoutInSeconds.
	 * A value of -1 means the value is unset
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle management.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return
	 */
	public int getNowaitForMasterBrokerTimeoutInSeconds(){
		checkManaged();
		int result = getLifecycleManagedBroker().getNowaitForMasterBrokerTimeoutInSeconds();
		_loggerL.entering(_className, "getNowaitForMasterBrokerTimeoutInSeconds()", result);
		return result;
	}

	/**
	 * Sets the clusterId for this ResourceAdapter.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle management.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param clusterId
	 *            The cluster Id that the Resource Adapter must use
	 */
	public synchronized void setClusterId(String clusterId) {
		checkManaged();
		_loggerL.entering(_className, "setClusterId()", clusterId);
		getLifecycleManagedBroker().setClusterId(clusterId);
	}

	/**
	 * Returns the clusterId for this ResourceAdapter.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle management.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return The clusterId
	 */
	public String getClusterId() {
		checkManaged();
		String result = getLifecycleManagedBroker().getClusterId();
		_loggerL.entering(_className, "getClusterId()", result);
		return result;
	}

	/**
	 * Sets the brokerId for this ResourceAdapter.
	 * 
	 * @param brokerId
	 *            The brokerId that the Resource Adapter must use
	 */
	public synchronized void setBrokerId(String brokerId) {
		checkManaged();
		_loggerL.entering(_className, "setBrokerId()", brokerId);
		getLifecycleManagedBroker().setBrokerId(brokerId);
	}

	/**
	 * Returns the brokerId for this ResourceAdapter.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle management.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return The brokerId
	 */
	public String getBrokerId() {
		checkManaged();
		String result = getLifecycleManagedBroker().getBrokerId();
		_loggerL.entering(_className, "getBrokerId()", result);
		return result;
	}

	/**
	 * Sets the dbType for this ResourceAdapter.<br/>
	 * <br/>
	 * This method is deprecated: callers should instead use <tt>setBrokerProps()</tt>
	 * to set the appropriate broker property directly.<br/>
	 * <br/>
	 * <i>Note:</i> This method is needed only for broker lifecycle management.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param dbType
	 *            The type of the broker that this RA associates with
	 */
	@Deprecated
	public synchronized void setDBType(String dbType) {
		checkManaged();
		_loggerL.entering(_className, "setDBType()", dbType);
		getLifecycleManagedBroker().setDBType(dbType);
	}

	/**
	 * Returns the dbType for this ResourceAdapter.<br/>
	 * <br/>
	 * This method is deprecated because the corresponding setter method is deprecated.<br/>
	 * <br/>
	 * <i>Note:</i> This method is needed only for broker lifecycle management.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return The dbType
	 */
	@Deprecated
	public String getDBType() {
		checkManaged();
		String result = getLifecycleManagedBroker().getDBType();
		_loggerL.entering(_className, "getDBType()", result);
		return result;
	}
	
	/**
	 * Sets the brokerProps for this ResourceAdapter.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle management.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param brokerProps
	 *            The brokerProps that the Resource Adapter must use
	 */
	public synchronized void setBrokerProps(Properties brokerProps) {
		checkManaged();
		// don't log properties as it may include passwords TODO strip passwords out from logging
		_loggerL.entering(_className, "setBrokerProps()");
//		_loggerL.entering(_className, "setBrokerProps()", brokerProps);
		getLifecycleManagedBroker().setBrokerProps(brokerProps);
	}

	/**
	 * Returns the brokerProps for this ResourceAdapter.
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle management.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return The brokerProps
	 */
	public Properties getBrokerProps() {
		checkManaged();
		// don't log properties as it may include passwords TODO strip passwords out from logging
		_loggerL.entering(_className, "getBrokerProps()");
		Properties result = getLifecycleManagedBroker().getBrokerProps();
//		_loggerL.entering(_className, "getBrokerProps()", result);
		return result;
	}	

	/**
	 * Sets the dbProps for this ResourceAdapter.<br/>
	 * <br/>
	 * This method is deprecated: callers should instead use <tt>setBrokerProps()</tt>
	 * to set the appropriate broker property directly.<br/>
	 * <br/>	 
	 * <i>Note:</i> This method is needed only for broker lifecycle management.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param dbProps
	 *            The dbProps that the Resource Adapter must use
	 */
	@Deprecated
	public synchronized void setDBProps(Properties dbProps) {
		checkManaged();
		_loggerL.entering(_className, "setDBProps()", dbProps);
		getLifecycleManagedBroker().setDBProps(dbProps);
	}

	/**
	 * Returns the dbProps for this ResourceAdapter.<br/>
	 * <br/>
	 * This method is deprecated because the corresponding setter method is deprecated.<br/>
	 * <br/>
	 * <i>Note:</i> This method is needed only for broker lifecycle management.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return The dbProps
	 */
	@Deprecated
	public Properties getDBProps() {
		checkManaged();
		Properties result = getLifecycleManagedBroker().getDBProps();
		_loggerL.entering(_className, "getDBProps()", result);
		return result;
	}

	/**
	 * Sets the dsProps for this ResourceAdapter.<br/>
	 * <br/>
	 * This method is deprecated: callers should instead use <tt>setBrokerProps()</tt>
	 * to set the appropriate broker property directly.<br/>
	 * <br/>
	 * <i>Note:</i> This method is needed only for broker lifecycle management.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param dsProps
	 *            The dsProps that the Resource Adapter must use
	 */
	@Deprecated
	public synchronized void setDSProps(Properties dsProps) {
		checkManaged();
		_loggerL.entering(_className, "setDSProps()", dsProps);
		getLifecycleManagedBroker().setDSProps(dsProps);
	}

	/**
	 * Returns the dsProps for this ResourceAdapter.<br/>
	 * <br/>
	 * This method is deprecated because the corresponding setter method is deprecated.<br/>
	 * <br/>
	 * <i>Note:</i> This method is needed only for broker lifecycle management.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @return The dsProps
	 */
	@Deprecated
	public Properties getDSProps() {
		checkManaged();
		Properties result = getLifecycleManagedBroker().getDSProps();
		_loggerL.entering(_className, "getDSProps()", result);
		return result;
	}

	/**
	 * <p>
	 * Return whether a the lifecycle managed broker should start a PortMapper
	 * thread listening on the configured PortMapper port.
	 * </p>
	 * <p>
	 * This should be set to false if this is an embedded broker and a proxy
	 * port mapper will be listening on this port instead.
	 * </p>
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle management.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param whether
	 *            a the lifecycle managed broker should start a PortMapper
	 *            thread listening on the configured PortMapper port.
	 */
	public boolean isDoBind() {
		checkManaged();
		return getLifecycleManagedBroker().isDoBind();
	}

	/**
	 * <p>
	 * Specifies whether a the lifecycle managed broker should start a
	 * PortMapper thread listening on the configured PortMapper port.
	 * </p>
	 * <p>
	 * Set to false if this is an embedded broker and a proxy port mapper will
	 * be listening on this port instead.
	 * </p>
	 * <p>
	 * This has no affect on a local or remote broker.
	 * </p>
	 * 
	 * <p><i>Note:</i> This method is needed only for broker lifecycle management.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called.<br>
	 * 
	 * @param whether
	 *            a the lifecycle managed broker should start a PortMapper
	 *            thread listening on the configured PortMapper port.
	 */
	public void setDoBind(boolean doBind) {
		checkManaged();
		getLifecycleManagedBroker().setDoBind(doBind);
	}

	/**
	 * <p>
	 * If an external proxy port mapper is being used to listen for connections
	 * to the port mapper, then after accepting the connection it should forward
	 * the new client socket to the PortMapperClientHandler returned by this
	 * method.
	 * </p>
	 * 
	 * <p>
	 * This method should not be called except in this case.
	 * </p>
	 * 
	 * <p>
	 * This method should only be called after the in-process broker has been
	 * started. If it is called before the broker has been started, or if the
	 * broker type is LOCAL or REMOTE, then a
	 * <tt>java.lang.IllegalStateException</tt> will be thrown.
	 * </p>
	 *
	 * <p><i>Note:</i> This method is needed only for broker lifecycle management.
	 * Will throw an <tt>IllegalOperationException</tt> if
	 * <tt>setManageBrokerLifecycle(false)</tt> has previously been called).<br>
	 * 
	 * @return
	 */
	public PortMapperClientHandler getPortMapperClientHandler() {
		checkManaged();
		return getLifecycleManagedBroker().getPortMapperClientHandler();
	}

	/**
	 * Returns the effective connection URL used by this resource adapter instance
	 * to connect to the broker. 
	 * <ul>
	 * <li>If the (effective) brokerType is APIDIRECT then the connection URL that is returned is <tt>mq://localhost/direct</tt>.
	 * 
	 * <li>If this resource adapter instance is performing broker lifecycle management and the brokerType is LOCAL, EMBEDDED
	 * or RADirect then the connection URL that is returned consists of the configured <tt>connectionURL</tt> (if set),
	 * prepended with a URL composed of <tt>localhost</tt> (or the configured <tt>brokerBindAddress</tt>, if set) and the 
	 * configured <tt>brokerPort</tt>. (ND: Not sure whether RADirect case is strictly needed).
	 * 
	 * <li>In all other cases the connection URL that is returned is the configured <tt>connectionURL</tt>.
	 * </ul>
	 */
	protected String _getEffectiveConnectionURL() {
		_loggerL.entering(_className, "_getEffectiveConnectionURL()");
		String eConnectionURL = null;
		
		if (_isAPIDirect()){
			eConnectionURL = "mq://localhost/direct";
		} else if (isManageBrokerLifecycle() && 
				(_isLocal() || _isEmbedded() || _isRADirect())) {
			// local or embedded or radirect
			// adjustment for managed brokers use 
			eConnectionURL = ((getBrokerBindAddress() != null) ? getBrokerBindAddress() : "localhost") + ":"
					+ Integer.toString(getBrokerPort());
			if ((getConnectionURL() != null) && (!("".equals(getConnectionURL())))) {
				eConnectionURL = eConnectionURL + "," + getConnectionURL();
			}
		} else {
			eConnectionURL = getConnectionURL();
		}
		_loggerL.exiting(_className, "_getEffectiveConnectionURL()", eConnectionURL);
		return eConnectionURL;
	}

	/**
	 * Returns the XAConnectionFactory for this ResourceAdapter
	 */
	protected com.sun.messaging.XAConnectionFactory _getXACF() {
		return xacf;
	}

	/**
	 * Returns the raUID for this ResourceAdapter
	 */
	protected String _getRAUID() {
		return raUID;
	}

	/**
	 * Returns the method that is called in the MessageListener to deliver
	 * messages to the endpoint consumer
	 */
	protected Method _getOnMessageMethod() {
		if (onMessage == null) {
			_setOnMessageMethod();
		}
		return onMessage;
	}

	// Private & Protected Methods //
	//
	/* configure the xacf */
	private void configureFactory() throws JMSException {
		String lcConnectionURL = null;

		if (!BROKER_TYPE_REMOTE.equals(brokerType)) {
			xacf.setProperty(ConnectionConfiguration.imqAddressList, _getEffectiveConnectionURL());
			xacf.setProperty(ConnectionConfiguration.imqAddressListBehavior, "PRIORITY");
		} else {
			xacf.setProperty(ConnectionConfiguration.imqAddressList, getConnectionURL());
			xacf.setProperty(ConnectionConfiguration.imqAddressListBehavior, addressListBehavior);
		}
		xacf.setProperty(ConnectionConfiguration.imqDefaultUsername, userName);
		xacf.setProperty(ConnectionConfiguration.imqDefaultPassword, password);
		xacf.setProperty(ConnectionConfiguration.imqAddressListIterations, Integer.toString(addressListIterations));

		// Force reconnectEnabled to false for XAR succes
		xacf.setProperty(ConnectionConfiguration.imqReconnectEnabled, Boolean.toString(false)); // reconnectEnabled

		xacf.setProperty(ConnectionConfiguration.imqReconnectInterval, Integer.toString(reconnectInterval));
		xacf.setProperty(ConnectionConfiguration.imqReconnectAttempts, Integer.toString(reconnectAttempts));

	}

	/* init the connection */
	private void init() throws JMSException {
		if (xac != null) {
			// Needs to be done once only, even across a reconnect
			if (inClusteredContainer && (raUID == null)) {
				raUID = Long.toString(xac.generateUID());
			}
			xac.setExceptionListener(this);
			((com.sun.messaging.jms.Connection) xac).setEventListener(this);
		}
		if (_loggerL.isLoggable(Level.FINER)) {
			_loggerL.finer(_lgrMID_INF + "init:" + "DONE:" + "raUID=" + raUID);
		}
	}

	/* Keys for factory in epFactories hashmap */
	private int createFactoryID() {
		return ++_factoryID;
	}

	/* Keys for consumer in epConsumers hashmap */
	private int createConsumerID() {
		return ++_consumerID;
	}

	/**
	 * Adds a MessageEndpointFactory to the epFactories hashmap
	 * 
	 * @param endpointFactory
	 *            The MessageEndpointFactory to be added
	 * @return The ID assigned to the MessageEndpoitnFactory added
	 */
	protected int addMessageFactory(MessageEndpointFactory endpointFactory) {
		int factoryID = createFactoryID();
		synchronized (epFactories) {
			epFactories.put(new Integer(factoryID), endpointFactory);
		}
		return factoryID;
	}

	/**
	 * Removes a MessageEndpointFactory by ID from the epFactories hashmap
	 * 
	 * @param factoryID
	 *            The ID of the MessageEndpointFactory to be removed
	 */
	protected void removeMessageFactory(int factoryID) {
		synchronized (epFactories) {
			epFactories.remove(new Integer(factoryID));
		}
	}

	/**
	 * Returns the MessageEndpointFactory corresponding to ID from the hashmap
	 * 
	 * @param factoryID
	 *            The ID of the MessageEndpointFactory to be returned
	 * 
	 * @return MessageEndpointFactory
	 */
	protected MessageEndpointFactory _getMessageFactory(int factoryID) {
		synchronized (epFactories) {
			MessageEndpointFactory epFactory = (MessageEndpointFactory) epFactories.get(new Integer(factoryID));
			return epFactory;
		}
	}

	/**
	 * Searches for a MessageEndpointFactory in the epFactories hashmap
	 * 
	 * @param endpointFactory
	 *            The MessageEndpointFactory to find
	 * @return The ID of the MessageEndpoitnFactory in the epFactories hashmap
	 */
	private int matchMessageFactory(MessageEndpointFactory endpointFactory) {
		int key = -1;

		if (endpointFactory != null) {
			synchronized (epFactories) {

				Collection factories = epFactories.entrySet();
				if (factories != null) {
					Iterator iter = factories.iterator();
					while (iter.hasNext()) {
						/* Get the map's entries */
						Map.Entry map = (Map.Entry) iter.next();

						/*
						 * If the endpointFactory matches an entry in the map,
						 * we have a match. Get the key for that match.
						 */
						if (endpointFactory.equals(map.getValue())) {
							Integer iKey = (Integer) map.getKey();
							key = iKey.intValue();
							break;
						}
					}
				}
			}
		}
		return key;
	}

	/**
	 * Adds a link between factoryID for MessageEndpointFactory and consumerID
	 * (endpointConsumer) in the hashmaps
	 */
	protected void addFactorytoConsumerLink(int factoryID, int consumerID) {
		synchronized (epFactoryToConsumer) {
			epFactoryToConsumer.put(new Integer(factoryID), new Integer(consumerID));
		}
	}

	/**
	 * Removes Link between factoryID (MessageEndpointFactory) and consumerID
	 * (EndpointConsumer) in the epFactoryToConsumer hashmap
	 * 
	 * @param factoryID
	 *            MessageEndpointFactory ID for which linked consumerID
	 *            (EndpointConsumer) is to be removed
	 */
	private void removeFactorytoConsumerLink(int factoryID) {
		synchronized (epFactoryToConsumer) {
			epFactoryToConsumer.remove(new Integer(factoryID));
		}
	}

	/**
	 * Returns the ID for the EndpointConsumer that is linked by the ID for the
	 * MessageEndpointFactory
	 * 
	 * @param factoryID
	 *            The ID for the MessageEndpointFactory
	 * 
	 * @return consumerID for the EndpointConsumer linked by this factoryID
	 */
	private int _getConsumerIDbyFactoryID(int factoryID) {
		return ((Integer) epFactoryToConsumer.get(new Integer(factoryID))).intValue();
	}

	/**
	 * Adds an EndpointConsumer in the hashmap
	 * 
	 * @param endpointConsumer
	 *            The EndpointConsumer to be added
	 * @return The ID assigned to the EndpointConsumer added
	 */
	protected int addEndpointConsumer(EndpointConsumer endpointConsumer) {
		int consumerID = createConsumerID();
		synchronized (epConsumers) {
			epConsumers.put(new Integer(consumerID), endpointConsumer);
		}
		return consumerID;
	}

	/**
	 * Removes EndpointConsumer from the hashmap given consumerID
	 * 
	 * @param consumerID
	 *            for the EndpointConsumer to remove
	 */
	private void removeEndpointConsumer(int consumerID) {
		synchronized (epConsumers) {
			epConsumers.remove(new Integer(consumerID));
		}
	}

	/**
	 * Returns the EndpointConsumer for a given consumerID
	 * 
	 * @param consumerID
	 *            The ID for which the EndpointConsumer is desired
	 * 
	 * @return EndpointConsumer for consumerID
	 */
	private EndpointConsumer _getEndpointConsumer(int consumerID) {
		EndpointConsumer endpointConsumer = (EndpointConsumer) epConsumers.get(new Integer(consumerID));
		return endpointConsumer;
	}

	/**
	 * Removes references MessageEndpointFactory and linked EndpointConsumer
	 * from hashmaps
	 */
	private void removeFromMaps(int factoryID) {
		int consumerID = _getConsumerIDbyFactoryID(factoryID);
		removeEndpointConsumer(consumerID);
		removeMessageFactory(factoryID);
		removeFactorytoConsumerLink(factoryID);
	}

	/**
	 * Removes all the consumers from epConsumers after first closing them.
	 */
	private void removeAllConsumers() {
		synchronized (epFactories) {

			Collection factories = epFactories.entrySet();

			if (factories != null) {

				Iterator iter = factories.iterator();
				while (iter.hasNext()) {
					Map.Entry entry = (Map.Entry) iter.next();
					int factoryID = ((Integer) entry.getKey()).intValue();
					int consumerID = _getConsumerIDbyFactoryID(factoryID);
					EndpointConsumer ec = _getEndpointConsumer(consumerID);

					try {
						ec.stopMessageConsumer();
					} catch (Exception ex) {
						// No exception for this method, print
						// XXX:log:tharakan
						System.err.println("MQJMSRA:RA::Error:stopMessageConsumer exception:ignoring");
						// ex.printStackTrace();
					}
					// removeFromMaps(factoryID);
				}
				clearMaps();
			}
		}
	}

	private void clearMaps() {

		/* clear hash maps */
		epFactories.clear();
		epConsumers.clear();
		epFactoryToConsumer.clear();
	}

	/**
	 * Sets the Method that is called in the MessageListener
	 * 
	 */
	private void _setOnMessageMethod() {
		Method onMessageMethod = null;
		try {
			Class msgListenerClass = javax.jms.MessageListener.class;
			Class[] paramTypes = { javax.jms.Message.class };
			onMessageMethod = msgListenerClass.getMethod("onMessage", paramTypes);

		} catch (NoSuchMethodException ex) {

			ex.printStackTrace();
		}
		onMessage = onMessageMethod;
	}

	/**
	 * Adjust the value of inAppClientContainer to reflect the actual
	 * capability.
	 * <p>
	 * 
	 * For test purposes, we can set imq.jms.ra.inACC to force the setting one
	 * way or another.
	 */
	private void _adjustInAppClientContainer() {
		// System.out.println("MQJMSRA:RA:AIACC()");
		String inACC_SysProp = System.getProperty("imq.jmsra.inACC");
		if (inACC_SysProp != null) {
			System.err.println("MQJMSRA:RA:AIACC:SystemProp imq.jmsra.inACC is NOT null!!");
			if ("true".equals(inACC_SysProp)) {
				System.err.println("MQJMSRA:RA:AIACC:setting inACC true");
				this.inAppClientContainer = true;
			} else {
				System.err.println("MQJMSRA:RA:AIACC:setting inACC false");
				this.inAppClientContainer = false;
			}
		} else {
			// System.out.println("MQJMSRA:RA:AIACC:SystemProp com.sun.messaging.jms.ra.inACC IS NULL!! Try WorkMgr");
			// Try to set inACC correctly depending on workMgr availability
			if (workMgr != null) {
				// System.out.println("MQJMSRA:RA:AIACC:WorkMgr is NOT null!!");
				// Try to do work
				try {
					workMgr.doWork(new Work() {
						public void run() {
							// System.out.println("MQJMSRA:RA:AIACC:Working...!");
							return;
						}

						public void release() {
							// System.out.println("MQJMSRA:RA:AIACC:Released...!");
							return;
						}
					});
					// System.out.println("MQJMSRA:RA:AIACC:leaving inACC as set since WorkMgr available and successful. inACC="+this.inAppClientContainer);
					//
					// Leave inAppClientContainer setting as set -- i.e. don't
					// change it if WorkMgr is successful
					// e.g. If Test wants it to be true - don't set it to false
					// if the workMgr is successful
					//
				} catch (Exception we) {
					// System.out.println("MQJMSRA:RA:AIACC:setting inACC true as WorkMgr available but unsuccessful");
					// Force it to be in the AppClient Container if unable to
					// use WorkMgr
					this.inAppClientContainer = true;
				}
			} else {
				// System.out.println("MQJMSRA:RA:AIACC:setting inACC true as WorkMgr unavailable");
				// Force it to be in the AppClient Container if WorkMgr is NULL
				this.inAppClientContainer = true;
			}
		}
		// System.out.println("MQJMSRA:RA:AIACC:exiting with inACC set to " +
		// this.inAppClientContainer);
	}

	/**
	 * This method is used to determine how a brokerType of DIRECT or EMBEDDED
	 * will be interpreted in the case when the broker is standalone
	 * (i.e. if inClusteredContainer=false).
	 * 
	 * If this method returns true then DIRECT mode will
	 * always be used (when the broker is standalone), 
	 * even if EMBEDDED was specified.
	 * 
	 * If it returns false then
	 * EMBEDDED mode will always be used (when the broker is standalone), 
	 * even if DIRECT was specified
	 * 
	 * The return value is obtained from the system property imq.jmsra.direct.
	 * If this property is not set then the return value is obtained from
	 * the constant ResourceAdapter.DIRECT_MODE_DEFAULT_STANDALONE. 
	 * 
	 * This means that users who specify DIRECT or EMBEDDED mode will actually
	 * get DIRECT mode (when the broker is standalone)
	 * unless they explicitly set imq.jmsra.direct to false
	 * 
	 * Note that this flag has no effect when the broker is clustered
	 * (i.e. if inClusteredContainer=true)
	 * 
	 * Note that if DIRECT mode is chosen, the function
	 * _useAPIDirectImplementation() is then called to determine whether the
	 * APIDIRECT or RADIRECT implementation is used
	 * 
	 * @return true if DIRECT or EMBEDDED mode should (when the broker is standalone) be overridden to DIRECT,
	 *         false if DIRECT or EMBEDDED mode should (when the broker is standalone) be overridden to EMBEDDED
	 * 
	 */
	private static boolean _isDirectDefaultWhenStandalone() {
		return Boolean.valueOf(System.getProperty("imq.jmsra.direct", ResourceAdapter.DIRECT_MODE_DEFAULT_STANDALONE));
	}
	
	/**
	 * This method is used to determine how a brokerType of DIRECT or EMBEDDED
	 * will be interpreted in the case when the broker is clustered
	 * (i.e. if inClusteredContainer=true).
	 * 
	 * If this method returns true then DIRECT mode will
	 * always be used (when the broker is clustered), 
	 * even if EMBEDDED was specified.
	 * 
	 * If it returns false then
	 * EMBEDDED mode will always be used (when the broker is clustered), 
	 * even if DIRECT was specified
	 * 
	 * The return value is obtained from the system property imq.jmsra.direct.clustered
	 * If this property is not set then the return value is obtained from
	 * the constant ResourceAdapter.DIRECT_MODE_DEFAULT_CLUSTERED. 
	 * 
	 * This means that users who specify DIRECT or EMBEDDED mode will actually
	 * get DIRECT mode (when the broker is clustered)
	 * unless they explicitly set imq.jmsra.direct to false
	 * 
	 * Note that this flag has no effect when the broker is standalone
	 * (i.e. if inClusteredContainer=false)
	 * 
	 * Note that if DIRECT mode is chosen, the function
	 * _useAPIDirectImplementation() is then called to determine whether the
	 * APIDIRECT or RADIRECT implementation is used
	 * 
	 * @return true if DIRECT or EMBEDDED mode should (when the broker is clustered) be overridden to DIRECT,
	 *         false if DIRECT or EMBEDDED mode should (when the broker is clustered) be overridden to EMBEDDED
	 * 
	 */
	private static boolean _isDirectDefaultWhenClustered() {
		return Boolean.valueOf(System.getProperty("imq.jmsra.direct.clustered", ResourceAdapter.DIRECT_MODE_DEFAULT_CLUSTERED));
	}	

	/**
	 * This method is used to determine which implementation will be used when
	 * DIRECT mode is chosen
	 * 
	 * If this method returns true then APIDIRECT mode will be used This is the
	 * new (4.4) direct mode implementation using standard JMS API If it returns
	 * false then RADIRECT mode will be used This is the old direct mode
	 * implementation implemented in the RA
	 * 
	 * The return value is obtained from the system property imq.jmsra.apidirect
	 * If this property is not set then the return value is obtained from
	 * ResourceAdapter.APIDIRECT_MODE_DEFAULT 
	 * 
	 * @return true if APIDIRECT mode should be used when DIRECT mode is chosen,
	 *         false if RADIRECT mode should be used when DIRECT mode is chosen
	 * 
	 */
	protected static boolean _useAPIDirectImplementation() {
		return Boolean.valueOf(System.getProperty("imq.jmsra.apidirect", ResourceAdapter.APIDIRECT_MODE_DEFAULT));
	}

	// Info Methods
	public String toString() {
		return ("SJSMQ JMSRA ResourceAdapter configuration=\n" + "\traUID                    =" + raUID + "\n"
				+ "\tGroupName                =" + groupName + "\n" + "\tbrokerType               =" + brokerType
				+ "\tbrokerPort               =" + brokerPort + "\n" + "\tConnectionURL            =" + connectionURL
				+ "\n" + "\tRADIRECT Mode allowed    =" + this._isRADirectAllowed() + "\n"
				+ "\tAPIDIRECT Mode allowed   =" + this._isAPIDirectAllowed() + "\n" + "\tDIRECT Mode default      ="
				+ _isDirectDefaultWhenStandalone() + "\n" + "\tUse APIDIRECT impl       =" + _useAPIDirectImplementation() + "\n"
				+ "\tUserName                 =" + userName + "\n" + "\tPassword                 ="
				+ ("guest".equals(this.password) ? "<default>" : "<modified>") + "\n" + "\tReconnectEnabled         ="
				+ reconnectEnabled + "\n" + "\tReconnectInterval        =" + reconnectInterval + "\n"
				+ "\tReconnectAttempts        =" + reconnectAttempts + "\n" + "\tAddressListBehavior      ="
				+ addressListBehavior + "\n" + "\tAddressListIterations    =" + addressListIterations + "\n"
				+ "\tInAppClientContainer     =" + inAppClientContainer + "\n" + "\tInClusteredContainer     ="
				+ inClusteredContainer + "\n" + getLifecycleManagedBroker().toString());
	}

	protected static com.sun.messaging.jms.ra.ConnectionManager _getConnectionManager() {
		return _cm;
	}

	/**
	 * If the effective broker type is RADIRECT, return the JMSService instance
	 * that a RADirect client can use to communicate with the in-VM broker.<br/>
	 * <br/>
	 * For all other types of broker null is returned<br/>
	 * <br>
	 * For internal resource adapter use only<br>
	 * 
	 * @return the JMSService instance or null
	 */
	public JMSService _getJMSService() {
		JMSService result = null;
		if (getLifecycleManagedBroker() != null) {
			result = getLifecycleManagedBroker()._getJMSService();
		}
		return result;
	}

	protected static final JMSService _getRAJMSService() {
		return LifecycleManagedBroker._getRAJMSService();
	}

	public boolean _isAnyDirect() {
		return (ResourceAdapter.BROKER_TYPE_RADIRECT.equals(brokerType) | ResourceAdapter.BROKER_TYPE_APIDIRECT
				.equals(brokerType));
	}

	public boolean _isRADirect() {
		return (ResourceAdapter.BROKER_TYPE_RADIRECT.equals(brokerType));
	}

	public boolean _isAPIDirect() {
		return (ResourceAdapter.BROKER_TYPE_APIDIRECT.equals(brokerType));
	}

	public boolean _isEmbedded() {
		return (ResourceAdapter.BROKER_TYPE_EMBEDDED.equals(brokerType));
	}
	
	public boolean _isLocal() {
		return (ResourceAdapter.BROKER_TYPE_LOCAL.equals(brokerType));
	}

	public boolean _isRemote() {
		return (ResourceAdapter.BROKER_TYPE_REMOTE.equals(brokerType));
	}

	public boolean _isRADirectAllowed() {
		return (this._isRADirect() && (!this.inAppClientContainer));
	}

	public boolean _isAPIDirectAllowed() {
		return (this._isAPIDirect() && (!this.inAppClientContainer));
	}

	public boolean _isAnyDirectAllowed() {
		return (this._isAnyDirect() && (!this.inAppClientContainer));
	}

	public void setDoInitOnlyOnStart(boolean start) {

		if (start) {
			// shouldn't happen
			throw new RuntimeException("setDoInitOnlyOnStart(true) is not supported any more");
		}
	}

	/**
	 * Returns whether the XAResource implementations provided by this RA should
	 * return isSameRM()=true if the resources are capable of being joined.
	 * 
	 * @return
	 */
	public static boolean isSameRMAllowed() {
		return isSameRMAllowed;
	}

	/**
	 * Return whether we should revert to the original behaviour rather than
	 * apply the workarounds implemented in RFE 6882044 in which various calls
	 * to XAResource.start() and XAResource.end() were not sent to the broker.
	 * 
	 * @return
	 */
	public static boolean isRevert6882044() {
		return isRevert6882044;
	}

	/**
	 * Check whether this resource adapter is configured to perform broker
	 * lifecycle management. This is the case by default, or can be configured
	 * by calling <tt>setManageBrokerLifecycle(true)</tt>. If
	 * <tt>setManageBrokerLifecycle(false)</tt> has been called then an
	 * <tt>IllegalStateException</tt> will be thrown.
	 */
	private void checkManaged() {
		if (!isManageBrokerLifecycle()) {
			throw new IllegalStateException(
					"com.sun.messaging.jms.raResourceAdapter: cannot perform broker lifecycle operations if manageBrokerLifecycle=true");
		}

	}

	/**
	 * Return whether this resource adapter should manage the broker lifecycle.
	 * See the class comment for more information.
	 * 
	 * @return
	 */
	public boolean isManageBrokerLifecycle() {
		return manageBrokerLifecycle;
	}

	/**
	 * Set whether this resource adapter should manage the broker lifecycle. See
	 * the class comment for more information.
	 * 
	 * @param manageBrokerLifecycle
	 */
	public void setManageBrokerLifecycle(boolean manageBrokerLifecycle) {
		this.manageBrokerLifecycle = manageBrokerLifecycle;
	}



}
