/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2009 BULL S.A.S
 * Contact: jonas-team@ow2.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */
package org.ow2.jonas.lib.management.extensions.manager;

import java.io.Serializable;
import java.util.List;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;

import org.ow2.jonas.lib.management.extensions.cluster.ClusterManagement;
import org.ow2.jonas.lib.management.extensions.clusterdaemon.ClusterdaemonManagement;
import org.ow2.jonas.lib.management.extensions.domain.DomainManagement;
import org.ow2.jonas.lib.management.extensions.server.ServerManagement;
import org.ow2.jonas.lib.management.extensions.server.ServerMonitoring;
import org.ow2.jonas.management.extensions.base.api.J2EEMBeanAttributeInfo;
import org.ow2.jonas.management.extensions.base.api.ManagementException;
import org.ow2.jonas.management.extensions.cluster.api.ICluster;
import org.ow2.jonas.management.extensions.clusterdaemon.api.IClusterdaemon;
import org.ow2.jonas.management.extensions.domain.api.IDomain;
import org.ow2.jonas.management.extensions.server.api.IServer;
import org.ow2.jonas.management.extensions.server.api.IServerManagement;

/**
 * Implements singleton for all management operations in JOnAS.
 * @author danesa
 * @author Oualaa Hani
 * @author Thomas KOUASSI
 */
public final class ManagementEntryPoint implements IDomain, IServer, IServerManagement, IClusterdaemon, ICluster, Serializable {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    /**
     * The ManagementEntryPoint singleton for management tools.
     */
    private static ManagementEntryPoint unique = null;

    /**
     * The IDomain Interface for DomainManagement implementation.
     */
    private static IDomain domainManagement = null;

    /**
     * The IServer Interface for Server Monitoring implementation.
     */
    private static IServer serverMonitor = null;

    /**
     * The IServerManagement Interface for Server Management implementation.
     */
    private static IServerManagement serverManagement = null;

    /**
     * The IClusterdaemon Interface for cluster daemon Management
     * implementation.
     */
    private static IClusterdaemon clusterdaemonManagement = null;

    /**
     * The ICluster Interface for cluster Management implementation.
     */
    private static ICluster clusterManagement = null;

    /**
     * @return ManagementEntryPoint singleton.
     */
    public static synchronized ManagementEntryPoint getInstance() {
        if (unique == null) {
            unique = new ManagementEntryPoint();
        }
        return unique;
    }

    /**
     * Constructor.
     */
    private ManagementEntryPoint() {
        domainManagement = new DomainManagement();
        serverMonitor = new ServerMonitoring();
        serverManagement = new ServerManagement();
        clusterdaemonManagement = new ClusterdaemonManagement();
        clusterManagement = new ClusterManagement();
    }

    // --------------------------------------------------
    // Domain management operations.
    // --------------------------------------------------

    /**
     * @return the current domain name.
     */
    public String getDomainName() {
        return domainManagement.getDomainName();
    }

    /**
     * @return the current server name.
     */
    public String getServerName() {
        return domainManagement.getServerName();
    }

    /**
     * @return the current server's host.
     */
    public String getServerHost() {
        return domainManagement.getServerHost();
    }

    /**
     * @return the current server's port if the web service activated.
     */
    public String getServerPort() {
        return domainManagement.getServerPort();
    }

    /**
     * Return True if the managed server is a master.
     * @param serverName managed server name
     * @return the "master" attribute of the corresponding J2EEDomain MBean
     */
    public boolean isMaster(final String serverName) {
        // Exception "ManagementException" if serverName doesn't exist
        return domainManagement.isMaster(serverName);
    }

    /**
     * Return True if the current server is a master.
     * @return the "master" attribute of the current J2EEDomain MBean
     */
    public boolean isMaster() {
        return domainManagement.isMaster();
    }

    /**
     * Return the server names that are belonging to the domain.
     * @return the server names that are belonging to the domain
     */
    public String[] getServerNames() {
        return domainManagement.getServerNames();
    }

    /**
     * @return the names of clusters in the domain.
     */
    public String[] getClustersNames() {
        return domainManagement.getClustersNames();
    }

    /**
     * @return the names of clusterDaemons in the domain.
     */
    public String[] getClusterDaemonNames() {
        return domainManagement.getClusterDaemonNames();
    }

    /**
     * Return the clusters in the domain. A cluster in the domain has associated
     * a cluster MBean having in its ObjectName a key property 'type' with
     * values in {LogicalCluster, TomcatCluster, JkCluster, EjbHa}
     * @return the OBJECT_NAMES of the Cluster MBeans.
     */
    public String[] getClusters() {
        return domainManagement.getClusters();
    }

    /**
     * Return the clusterDaemons in the domain. A clusterDaemon in the domain
     * has associated a cluster daemon MBean having in its ObjectName a key
     * property 'type' with value equal to 'ClusterDaemon'.
     * @return the OBJECT_NAMES of the Cluster Daemon MBeans.
     */
    public String[] getclusterDaemons() {
        return domainManagement.getclusterDaemons();
    }

    /**
     * Add a new server in the domain.
     * @param serverName the server's name.
     * @param connector the server's connector it can be JRMP, IRMI or IIOP.
     * @param userName the user of the new server.
     * @param password the password of the new server.
     * @param clusterDaemon the name of clusterDaemon if this server will take
     *        part of clusterDaemon.
     */
    public void addServer(final String serverName, final String serverURL, final String userName, final String password,
            final String clusterdaemon) {
        domainManagement.addServer(serverName, serverURL, userName, password, clusterdaemon);
    }

    /**
     * Remove a list of servers from the domain.
     * @param serversToRemove the list of servers to remove.
     */
    public void removeServers(final String[] serversToRemove) {
        domainManagement.removeServers(serversToRemove);
    }

    /**
     * Add a new cluster in the domain.
     * @param clusterName the new cluster's name.
     */
    public void addCluster(final String clusterName) {
        domainManagement.addCluster(clusterName);
    }

    /**
     * Return the state of a server in the domain.
     * @param serverName the server's name
     * @return the state of a server in the domain
     */
    public String getServerState(final String serverName) {
        return domainManagement.getServerState(serverName);
    }

    /**
     * Start the server.
     * @param serverName the name of the server to start
     */
    public void startServer(final String serverName) {
        startServer(serverName, false);
    }

    /**
     * Start the server.
     * @param serverName the name of the server to start
     * @param standby <code>true</code> to activate standby mode.
     */
    public void startServer(final String serverName, final boolean standby) {
        domainManagement.startServer(serverName, standby);
    }

    /**
     * Stop the server.
     * @param serverName the name of the server to stop (stop the JVM)
     */
    public void stopServer(final String serverName) {
        stopServer(serverName, true);
    }

    /**
     * Stop the server.
     * @param serverName the name of the server to stop
     * @param standby
     */
    public void stopServer(final String serverName, final boolean standby) {
        domainManagement.stopServer(serverName, standby);
    }

    /**
     * Halt the server.
     * @param serverName the name of the server to halt
     */
    public void haltServer(final String serverName) {
        stopServer(serverName, false);
    }

    /**
     * Return the clusterDaemon of a server in the domain.
     * @param serverName the server's name
     * @return the name of the server's cluster daemon
     */
    public String getServerClusterdaemon(final String serverName) {
        return domainManagement.getServerClusterdaemon(serverName);
    }

    /**
     * Return the state of a cluster in the domain.
     * @param clusterName the cluster's name
     * @return the state of a cluster in the domain
     */
    public String getClusterState(final String clusterName) {
        return domainManagement.getClusterState(clusterName);
    }

    /**
     * Return the type of a cluster in the current domain.
     * @param clusterName the cluster's name
     * @return the result of the getClusterType operation
     */
    public String getClusterType(final String clusterName) {
        return domainManagement.getClusterType(clusterName);
    }

    /**
     * @param clusterName the cluster name
     * @return the server names that are belonging to a cluster
     */
    public String[] getServerNames(final String clusterName) {
        return domainManagement.getServerNames(clusterName);
    }

    // --------------------------------------------------
    // Server management operations.
    // --------------------------------------------------

    /**
     * Get the Java home
     * @param server the server's name.
     * @return the javaHome
     */
    public String getJavaHome(final String serverName) {
        return serverMonitor.getJavaHome(serverName);
    }

    /**
     * Get the memory used by a server in the domain.
     * @param server the server's name.
     * @return the used memory
     */
    public long getCurrentUsedMemory(final String server) {
        return serverMonitor.getCurrentUsedMemory(server);
    }

    /**
     * Get the version of a server in the domain.
     * @param server the server's name.
     * @return the server's version
     */
    public String getServerVersion(final String server) {
        return serverMonitor.getServerVersion(server);
    }

    /**
     * Get the number of threads used by a server in the domain.
     * @param server the server's name.
     * @return the number of threads
     */
    public int getAllThreadsCount(final String server) {
        return serverMonitor.getAllThreadsCount(server);
    }

    /**
     * Get the total memory of the server in the domain.
     * @param server the server's name.
     * @return the total memory
     */
    public Long getCurrentTotalMemory(final String server) {
        return serverMonitor.getCurrentTotalMemory(server);
    }

    /**
     * Get the JMX connection URL of the server.
     * @param server the server's name.
     * @return the JMX connection URL of the server
     */
    public String getConnectionUrl(final String server) {
        return serverMonitor.getConnectionUrl(server);
    }

    /**
     * Get the Jonas Base
     * @param server the server's name.
     * @return the Jonas Base
     */
    public String getJonasBase(final String server) {
        return serverMonitor.getJonasBase(server);
    }

    /**
     * Get the Jonas Root
     * @param server the server's name.
     * @return the Jonas Root
     */
    public String getJonasRoot(final String server) {
        return serverMonitor.getJonasRoot(server);
    }

    /**
     * Get the Xprem
     * @param server the server's name.
     * @return the xprem
     */
    public String getXprem(final String server) {
        return serverMonitor.getXprem(server);
    }

    /**
     * Get the Description
     * @param server the server's name.
     * @return the description
     */
    public String getDescription(final String server) {
        return serverMonitor.getDescription(server);
    }

    /**
     * Get the Auto Boot
     * @param server the server's name.
     * @return the autoBoot
     */
    public String getAutoBoot(final String server) {
        return serverMonitor.getAutoBoot(server);
    }

    /**
     * Get the JVM vendor.
     * @param server the server's name.
     * @return the JVM vendor
     */
    public String getJavaVendor(final String server) {
        return serverMonitor.getJavaVendor(server);
    }

    /**
     * Get the java version.
     * @param server the server's name.
     * @return the java version
     */
    public String getJavaVersion(final String server) {
        return serverMonitor.getJavaVersion(server);
    }

    /**
     * Get the the protocols used bye the server.
     * @param server the server's name.
     * @return the protocols used bye the server
     */
    public String getProtocols(final String server) {
        return serverMonitor.getProtocols(server);
    }

    /**
     * @return total begun transactions.
     * @param server Server name
     */
    public int getTotalBegunTransactions(final String server) {
        return serverMonitor.getTotalBegunTransactions(server);
    }

    /**
     * @return total commited transactions.
     * @param server Server name
     */
    public int getTotalCommittedTransactions(final String server) {
        return serverMonitor.getTotalCommittedTransactions(server);
    }

    /**
     * @return total expired transactions.
     * @param server Server name
     */
    public int getTotalExpiredTransactions(final String server) {
        return serverMonitor.getTotalExpiredTransactions(server);
    }

    /**
     * @return total global transactions.
     * @param server Server name
     */
    public int getTotalRolledbackTransactions(final String server) {
        return serverMonitor.getTotalRolledbackTransactions(server);
    }

    /**
     * @return total current transactions.
     * @param server Server name
     */
    public int getTotalCurrentTransactions(final String server) {
        return serverMonitor.getTotalCurrentTransactions(server);
    }

    /**
     * @return bytes received by connector tomcat.
     * @param server Server name
     */
    public long getBytesReceivedByConnectorTomcat(final String server) {
        return serverMonitor.getBytesReceivedByConnectorTomcat(server);
    }

    /**
     * @return bytes sent by connector tomcat.
     * @param server Server name
     */
    public long getBytesSentByConnectorTomcat(final String server) {
        return serverMonitor.getBytesSentByConnectorTomcat(server);
    }

    /**
     * @return current threads busy by connector tomcat.
     * @param server Server name
     */
    public int getCurrentThreadBusyByConnectorTomcat(final String server) {
        return serverMonitor.getCurrentThreadBusyByConnectorTomcat(server);
    }

    /**
     * @return current threads busy by connector tomcat.
     * @param server Server name
     */
    public int getCurrentThreadCountByConnectorTomcat(final String server) {
        return serverMonitor.getCurrentThreadCountByConnectorTomcat(server);
    }

    /**
     * @return error count by connector tomcat.
     * @param server Server name
     */
    public int getErrorCountByConnectorTomcat(final String server) {
        return serverMonitor.getErrorCountByConnectorTomcat(server);
    }

    /**
     * @param server Server name.
     * @return host name
     */
    public String getHostName(final String serverName) {
        return serverMonitor.getHostName(serverName);
    }

    /**
     * @return the max threads by connector tomcat.
     * @param server Server name
     */
    public int getMaxThreadsByConnectorTomcat(final String server) {
        return serverMonitor.getMaxThreadsByConnectorTomcat(server);
    }

    /**
     * @return processing time by connector tomcat.
     * @param server Server name
     */
    public long getProcessingTimeByConnectorTomcat(final String server) {
        return serverMonitor.getProcessingTimeByConnectorTomcat(server);
    }

    /**
     * @return request count by connector tomcat.
     * @param server Server name
     */
    public int getRequestCountByConnectorTomcat(final String server) {
        return serverMonitor.getRequestCountByConnectorTomcat(server);
    }

    /**
     * @return current number of EJB.
     * @param server Server name
     */
    public int getCurrentNumberOfEJB(final String server) {
        return serverMonitor.getCurrentNumberOfEJB(server);
    }

    /**
     * @return current number of Entity bean.
     * @param server Server name
     */
    public int getCurrentNumberOfEntityBean(final String server) {
        return serverMonitor.getCurrentNumberOfEntityBean(server);
    }

    /**
     * @return current number of mbean.
     * @param server Server name
     */
    public int getCurrentNumberOfMDB(final String server) {
        return serverMonitor.getCurrentNumberOfMDB(server);
    }

    /**
     * @return current number of state full bean.
     * @param server Server name
     */
    public int getCurrentNumberOfSBF(final String server) {
        return serverMonitor.getCurrentNumberOfSBF(server);
    }

    /**
     * @return current number of state less bean.
     * @param server Server name
     */
    public int getCurrentNumberOfSBL(final String server) {
        return serverMonitor.getCurrentNumberOfSBL(server);
    }

    // --------------------------------------------------
    // cluster daemon management operations.
    // --------------------------------------------------
    /**
     * @param clusterdaemonName name
     * @return list of servers controlled by a cluster daemon
     */
    public String[] getControlledServersNames(final String clusterdaemonName) {

        return clusterdaemonManagement.getControlledServersNames(clusterdaemonName);
    }

    /**
     * @param clusterdaemonName name of the cluster daemon to manage.
     * @return true if the cluster daemon is in RUNNING state, false otherwise
     */
    public boolean isRunning(final String clusterdaemonName) {
        return clusterdaemonManagement.isRunning(clusterdaemonName);
    }

    /**
     * @return the state of a cluster daemon in the domain
     * @param clusterdaemonName name of the cluster daemon to manage
     */
    public String getClusterdaemonState(final String clusterdaemonName) {
        return clusterdaemonManagement.getClusterdaemonState(clusterdaemonName);
    }

    /**
     * Start a server controlled by a cluster daemon
     * @param clusterdaemonName name of the cluster daemon
     * @param serverName name of the server to start
     * @return true if successfully started
     */
    public boolean startServer(final String clusterdaemonName, final String serverName) {
        return clusterdaemonManagement.startServer(clusterdaemonName, serverName);
    }

    /**
     * Stop a server controlled by a cluster daemon
     * @param clusterdaemonName name of the cluster daemon
     * @param serverName name of the server to stop
     * @return true if successfully stopped
     */
    public boolean stopServer(final String clusterdaemonName, final String serverName) {
        return clusterdaemonManagement.stopServer(clusterdaemonName, serverName);
    }

    /**
     * Add a server to cluster daemon control
     * @param clusterDaemonName the cluster Daemon name
     * @param serverName the server name
     * @param description server description
     * @param javaHome path to JRE
     * @param jonasRoot path to bin repository
     * @param jonasBase path to lib repository
     * @param xprem extra parameter e.g: -Djava.net.preferIPv4Stack=true
     * @param autoBoot true if the server is launched when cluster daemon starts
     * @param jonasCmd user command
     * @param saveIt true to flush the clusterd configuration
     */

    public void addServer(final String clusterDaemonName, final String serverName, final String description,
            final String jonasRoot, final String jonasBase, final String javaHome, final String xprem, final String autoBoot,
            final String jonasCmd, final String saveIt) {
        clusterdaemonManagement.addServer(clusterDaemonName, serverName, description, jonasRoot, jonasBase, javaHome, xprem,
                autoBoot, jonasCmd, saveIt);
    }

    /* =========== using DomainMonitor========================= */

    /**
     * Get the OperatingSystemAvailableProcessorsof a cluster Daemon Name in the
     * domain.
     * @param clusterDaemonName the cluster Daemon Name's name.
     * @return the OperatingSystemAvailableProcessors of the cluster Daemon
     */
    public String getOperatingSystemAvailableProcessors(final String clusterDaemonName) {
        return clusterdaemonManagement.getOperatingSystemAvailableProcessors(clusterDaemonName);
    }

    /**
     * Get the OperatingSystemName a cluster Daemon Name in the domain.
     * @param clusterDaemonName the cluster Daemon Name's name.
     * @return the operatingSystemName of the cluster Daemon
     */
    public String getOperatingSystemName(final String clusterDaemonName) {
        return clusterdaemonManagement.getOperatingSystemName(clusterDaemonName);
    }

    /**
     * Get the OperatingSystemVersion a cluster Daemon Name in the domain.
     * @param clusterDaemonName the cluster Daemon Name's name.
     * @return the OperatingSystemVersion of the cluster Daemon
     */
    public String getOperatingSystemVersion(final String clusterDaemonName) {
        return clusterdaemonManagement.getOperatingSystemVersion(clusterDaemonName);
    }

    /**
     * Get the RunTimeSpecVendor a cluster Daemon Name in the domain.
     * @param clusterDaemonName the cluster Daemon Name's name.
     * @return the RunTimeSpecVendor of the cluster Daemon
     */
    public String getRunTimeSpecVendor(final String clusterDaemonName) {
        return clusterdaemonManagement.getRunTimeSpecVendor(clusterDaemonName);
    }

    /**
     * Get the RunTimeSpecVersion a cluster Daemon Name in the domain.
     * @param clusterDaemonName the cluster Daemon Name's name.
     * @return the RunTimeSpecVersion of the cluster Daemon
     */
    public String getRunTimeSpecVersion(final String clusterDaemonName) {
        return clusterdaemonManagement.getRunTimeSpecVersion(clusterDaemonName);
    }

    /**
     * Get the RunTimeVmName a cluster Daemon Name in the domain.
     * @param clusterDaemonName the cluster Daemon Name's name.
     * @return the RunTimeVmName of the cluster Daemon
     */
    public String getRunTimeVmName(final String clusterDaemonName) {
        return clusterdaemonManagement.getRunTimeVmName(clusterDaemonName);
    }

    /**
     * Get the RunTimeVmVendor a cluster Daemon Name in the domain.
     * @param clusterDaemonName the cluster Daemon Name's name.
     * @return the runTimeVmVendor of the cluster Daemon
     */
    public String getRunTimeVmVendor(final String clusterDaemonName) {
        return clusterdaemonManagement.getRunTimeVmVendor(clusterDaemonName);
    }

    /**
     * Get the RunTimeVmVersion a cluster Daemon Name in the domain.
     * @param clusterDaemonName the cluster Daemon Name's name.
     * @return the RunTimeVmVersion of the cluster Daemon
     */
    public String getRunTimeVmVersion(final String clusterDaemonName) {
        return clusterdaemonManagement.getRunTimeVmVersion(clusterDaemonName);
    }

    /**
     * Get the OperatingSystemArch a cluster Daemon Name in the domain.
     * @param clusterDaemonName the cluster Daemon Name's name.
     * @return the OperatingSystem Architecture
     */
    public String getOperatingSystemArch(final String clusterDaemonName) {
        return clusterdaemonManagement.getOperatingSystemArch(clusterDaemonName);
    }

    /**
     * Get the vmCurrentUsedMemory a cluster Daemon Name in the domain.
     * @param clusterDaemonName the cluster Daemon Name's name. Getting remote
     *        Vm used Memory
     * @return the value of current used memory of the cluster Daemon
     */
    public String getVmCurrentUsedMemory(final String clusterDaemonName) {
        return clusterdaemonManagement.getVmCurrentUsedMemory(clusterDaemonName);
    }

    /**
     * Get the vmTotalMemory a cluster Daemon Name in the domain.
     * @param clusterDaemonName the cluster Daemon Name's name. Getting remote
     *        Vm Total Memory
     * @return the value of Vm Total memory of the cluster Daemon
     */
    public String getVmTotalMemory(final String clusterDaemonName) {
        return clusterdaemonManagement.getVmTotalMemory(clusterDaemonName);
    }

    /**
     * Getting remote Vm's Current used Heap memory
     * @param clusterDaemonName the cluster Daemon Name's name.
     * @return the value of Vm's Current used Heap memory
     */
    public String getVmCurrentUsedHeapMemory(final String clusterDaemonName) {
        return clusterdaemonManagement.getVmCurrentUsedHeapMemory(clusterDaemonName);
    }

    /**
     * Getting remote Vm's Current used non Heap memory
     * @param clusterDaemonName the cluster Daemon Name's name.
     * @return the value of Vm's Current used non Heap memory of the cluster
     *         Daemon
     */
    public String getVmCurrentUsedNonHeapMemory(final String clusterDaemonName) {
        return clusterdaemonManagement.getVmCurrentUsedNonHeapMemory(clusterDaemonName);
    }

    /**
     * Getting Operating system Current used space
     * @param clusterDaemonName the cluster Daemon Name's name.
     * @return the value of Operating system Current used space of the cluster
     *         Daemon
     */
    public String getOsCurrentUsedSpace(final String clusterDaemonName) {
        return clusterdaemonManagement.getOsCurrentUsedSpace(clusterDaemonName);
    }

    /**
     * Getting Operating system Total space
     * @param clusterDaemonName the cluster Daemon Name's name.
     * @return the value of Operating system Total space of the cluster Daemon
     */
    public String getOsTotalSpace(final String clusterDaemonName) {
        return clusterdaemonManagement.getOsTotalSpace(clusterDaemonName);
    }

    /**
     * Remove this server from cluster daemon control.
     * @param serverName the server to remove
     * @param saveIt true to flush the clusterd configuration
     */
    public void removeServer(final String clusterDaemonName, final String serverName, final String saveIt) {
        clusterdaemonManagement.removeServer(clusterDaemonName, serverName, saveIt);
    }

    /**
     * Ask Cluster Daemon to start all the Servers from cluster daemon control.
     * @param clusterdaemonName name of the cluster daemon
     * @param otherParams the servers to start
     */
    public void startAllServers(final String clusterDaemonName, final String otherParams) {
        clusterdaemonManagement.startAllServers(clusterDaemonName, otherParams);
    }

    /**
     * Ask Cluster Daemon to stop all the Servers from cluster daemon control.
     * @param clusterdaemonName name of the cluster daemon
     * @param otherParams the servers to stop
     */
    public void stopAllServers(final String clusterDaemonName, final String otherParams) {
        clusterdaemonManagement.stopAllServers(clusterDaemonName, otherParams);
    }

    /* =========== end of using DomainMonitor========================= */

    // --------------------------------------------------
    // cluster management operations.
    // --------------------------------------------------
    /**
     * Add server to cluster.
     * @param clusterName cluster name
     * @param serverName server name
     * @param clusterDaemon cluster daemon name
     * @param serverURL server url
     */

    public void addServerToCluster(final String clusterName, final String serverName, final String clusterDaemon,
            final String serverURL) {
        clusterManagement.addServerToCluster(clusterName, serverName, clusterDaemon, serverURL);
    }

    /**
     * start all servers in the cluster.
     * @param clusterName
     */
    public void startAllServers(final String clusterName) {
        clusterManagement.startAllServers(clusterName);
    }

    /**
     * stop all servers in the cluster.
     * @param clusterName
     */
    public void stopAllServers(final String clusterName) {
        clusterManagement.stopAllServers(clusterName);
    }

    /**
     * @param clusterName
     * @return the multicast address
     */
    public String getMcastAddr(final String clusterName) {
        return clusterManagement.getMcastAddr(clusterName);
    }

    /**
     * @param clusterName
     * @return the multicast port
     */
    public int getMcastPort(final String clusterName) {
        return clusterManagement.getMcastPort(clusterName);
    }

    /**
     * @param clusterName
     * @return the delay used by clients to update their cluster view
     */
    public int getDelayToRefresh(final String clusterName) {
        return clusterManagement.getDelayToRefresh(clusterName);
    }

    /**
     * Get the name of the servers in the domain except the ones that are
     * belonging to this cluster.
     * @param clusterName the cluster name
     * @return name of the servers that can be attached to the cluster
     */
    public String[] getServersNotInCluster(final String clusterName) {
        return domainManagement.getServersNotInCluster(clusterName);
    }

    /**
     * @return the current server threads information.
     * @param serverName Server name
     * @throws Exception when operation invocation fails
     */
    public List<List<String>> getServerThreadsInformation(final String serverName) throws Exception {
        return serverManagement.getServerThreadsInformation(serverName);
    }

    /**
     * @return the current server threads information.
     * @param jmxUrl
     * @param username
     * @param password
     * @throws Exception when operation invocation fails
     */
    public List<List<String>> getServerThreadsInformation(final String jmxUrl, final String username, final String password)
    throws Exception {
        return serverManagement.getServerThreadsInformation(jmxUrl, username, password);
    }

    /**
     * Deploy a module on a target server in the domain.
     * @param fileName Name of the module's file.
     * @param serverName Target server name.
     * @throws Exception deploy operation failed.
     */
    public void deploy(final String fileName, final String serverName) throws Exception {
        serverManagement.deploy(fileName, serverName);
    }

    /**
     * Uneploy a module on a target server.
     * @param fileName Name of the module's file.
     * @param serverName Target server name.
     * @throws Exception undeploy operation failed.
     */
    public void undeploy(final String fileName, final String serverName) throws Exception {
        serverManagement.undeploy(fileName, serverName);
    }

    /**
     * Remove a module on a target server.
     * @param fileName Name of the module's file.
     * @param serverName Target server name.
     * @return true if the file successfully deleted
     * @throws Exception remove operation failed.
     */
    public boolean remove(final String fileName, final String serverName) throws Exception {
        return serverManagement.remove(fileName, serverName);
    }

    /**
     * Return true if a given service is in 'development' mode for a given
     * server managed in the domain.
     * @param serviceName The service name, for example "depmonitor".
     * @param serverName Target server name.
     * @return true if a given service is in 'development' mode, false otherwise
     * @throws Exception
     */
    public boolean developmentMode(final String serviceName, final String serverName) throws Exception {
        return serverManagement.developmentMode(serviceName, serverName);
    }

    /**
     * Gets the value of a specific attribute of a named MBean.
     * @param on The ObjectName of the MBean.
     * @param attribute A String specifying the name of the attribute to be
     *        retrieved.
     * @param serverName The server name
     * @return The value of the attribute.
     * @throws ManagementException management operation failed
     */
    public Object getAttribute(final ObjectName on, final String attribute, final String serverName) throws ManagementException {
        return domainManagement.getAttribute(on, attribute, serverName);
    }

    /**
     * Get management attributes.
     * @param objectName
     * @param serverName
     * @return attributes for the given objectName.
     */
    public J2EEMBeanAttributeInfo[] getAttributes(final ObjectName objectName, final String serverName)
    throws ManagementException {
        return domainManagement.getAttributes(objectName, serverName);
    }

    /**
     * Get the integer attribute value of an MBean in the current MBean Server.
     * @param objectName The MBean's ObjectName
     * @param attrName The attribute name
     * @return The value of the attribute
     */
    public int getIntegerAttribute(final ObjectName objectName, final String attrName) throws ManagementException {
        return domainManagement.getIntegerAttribute(objectName, attrName);
    }

    /**
     * Return the value of a key property in an OBJECT_NAME.
     * @param objectName the OBJECT_NAME (String form)
     * @param keyName key property name
     * @return key value
     */
    public String getKeyValue(final String objectName, final String keyName) throws ManagementException {
        return domainManagement.getKeyValue(objectName, keyName);
    }

    /**
     * Return the values of a key property in String OBJECT_NAMEs.
     * @param objectNames the OBJECT_NAMEs
     * @param keyName key name
     * @return array of key values
     */
    public String[] getKeyValues(final String[] objectNames, final String keyName) throws ManagementException {
        return domainManagement.getKeyValues(objectNames, keyName);
    }

    /**
     * Return the list of <code>ObjectName</code> Mbean gotten by the query in
     * the current MbeanServer.
     * @param p_On Query Mbeans to search
     * @return The list of <code>ObjectName</code>
     * @throws ManagementException
     */
    public List getListMbean(final ObjectName on, final String serverName) throws ManagementException {
        return domainManagement.getListMbean(on, serverName);
    }

    /**
     * Get the String attribute value of an MBean in the current MBean Server.
     * @param objectName The MBean's ObjectName
     * @param attrName The attribute name
     * @return The value of the attribute
     */
    public String getStringAttribute(final ObjectName objectName, final String attrName) throws ManagementException {
        return domainManagement.getStringAttribute(objectName, attrName);
    }

    /**
     * Implementation of the <code>invoke</code> method to be applied to a
     * server in the domain.
     * @param on the ObjectName of the MBean that is the target of the invoke.
     * @param operation operation to invoke
     * @param param invoke parameters
     * @param signature invoke parameters signature
     * @param serverName The server's name
     * @return The object returned by the operation
     * @throws ManagementException management operation failed
     */
    public Object invoke(final ObjectName on, final String operation, final Object[] param, final String[] signature,
            final String serverName) throws ManagementException {
        return domainManagement.invoke(on, operation, param, signature, serverName);
    }

    /**
     * Implementation of the <code>isRegistered</code> method to be applied to a
     * server in the domain.
     * @return True if the MBean is already registered in the MBean server,
     *         false otherwise or if an exception is catched.
     * @param on ObjectName of the MBean we are looking for
     * @param serverName The server name
     * @throws ManagementException management operation failed
     */
    public boolean isRegistered(final ObjectName on, final String serverName) throws ManagementException {
        return domainManagement.isRegistered(on, serverName);
    }

    /**
     * Return the MBeanServer connection corresponding to a given server in the
     * current domain. The connection for servers in the domain are provided by
     * the DomainMonitor.
     * @param serverName The managed server name
     * @return The MBeanServerConnection corresponding to the managed server
     * @throws ManagementException Couldn't get the connection
     */
    public MBeanServerConnection getServerConnection(final String serverName) throws ManagementException {
        return domainManagement.getServerConnection(serverName);
    }

    /**
     * Return the MBeanServer connection corresponding to a current server in
     * the current domain. The connection for servers in the domain are provided
     * by the DomainMonitor.
     * @return The MBeanServerConnection corresponding to the managed server
     * @throws ManagementException Couldn't get the connection
     */
    public MBeanServerConnection getServerConnection() throws ManagementException {
        return domainManagement.getServerConnection();
    }

    /**
     * Sets the value of a specific attribute of a named MBean.
     * @param on The ObjectName of the MBean.
     * @param serverName The server name
     * @param attribute A String specifying the name of the attribute to be set.
     * @param value The value to set to the attribute.
     * @throws ManagementException management operation failed
     */
    public void setAttribute(final ObjectName on, final String attribute, final Object value, final String serverName)
    throws ManagementException {
        domainManagement.setAttribute(on, attribute, value, serverName);
    }

    /**
     * Sets the value of a specific attribute of a named MBean within the
     * current server.
     * @param on The ObjectName of the MBean.
     * @param attribute A String specifying the name of the attribute to be set.
     * @param value The value to set to the attribute.
     * @throws ManagementException management operation failed
     */
    public void setAttribute(final ObjectName on, final String attribute, final Object value) throws ManagementException {
        domainManagement.setAttribute(on, attribute, value);

    }

    public ObjectName getTomcatRealm(final String domainName, final String serverName)  throws ManagementException {
        return domainManagement.getTomcatRealm(domainName, serverName);
    }

    public List<?> getRealmItems(final String realmType, final String securityRealmUsed, final String domainName, final String serverName)
    throws ManagementException {
        return domainManagement.getRealmItems(realmType, securityRealmUsed, domainName, serverName);
    }

    public List<?> getRealmItems(final String realmType, final String securityRealmUsed) throws ManagementException {
        return domainManagement.getRealmItems(realmType, securityRealmUsed);
    }

    public List<?> getTomcatRealmItems(final String usedSecurityRealm, final String domainName, final String serverName) throws ManagementException {
        return domainManagement.getTomcatRealmItems(usedSecurityRealm, domainName, serverName);
    }

}
