http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c0221bed/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/AgentConfigImpl.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/AgentConfigImpl.java
 
b/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/AgentConfigImpl.java
new file mode 100644
index 0000000..2edd468
--- /dev/null
+++ 
b/geode-core/src/main/java/org/apache/geode/internal/admin/api/jmx/impl/AgentConfigImpl.java
@@ -0,0 +1,1794 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.geode.internal.admin.api.jmx.impl;
+
+import static org.apache.geode.distributed.ConfigurationProperties.*;
+import static org.apache.geode.distributed.internal.DistributionConfig.*;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.InetAddress;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import org.apache.geode.GemFireIOException;
+import org.apache.geode.internal.admin.api.DistributedSystemConfig;
+import org.apache.geode.internal.admin.api.DistributionLocatorConfig;
+import org.apache.geode.internal.admin.api.impl.DistributedSystemConfigImpl;
+import org.apache.geode.internal.admin.api.impl.InetAddressUtil;
+import org.apache.geode.internal.admin.api.jmx.Agent;
+import org.apache.geode.internal.admin.api.jmx.AgentConfig;
+import org.apache.geode.internal.ClassPathLoader;
+import org.apache.geode.internal.i18n.LocalizedStrings;
+import org.apache.geode.internal.util.IOUtils;
+
+/**
+ * Provides the JMX Agent configuration properties.
+ * <p>
+ * Supports importing of persisted properties from an external configuration
+ * file.
+ * <p>
+ * Select values can also be overridden with command line arguments.  See
+ * remarks on individual properties for further information.
+ * <p>
+ * Extends and implements DistributedSystemConfig.
+ * @since GemFire     3.5 (in which it was named AgentConfig)
+ */
+public class AgentConfigImpl extends DistributedSystemConfigImpl implements 
AgentConfig {
+
+  // -------------------------------------------------------------------------
+  //   Static class variable(s)
+  // -------------------------------------------------------------------------
+
+  /**
+   * Command-line arg to enable agent debugging
+   */
+  public static final String AGENT_DEBUG = "agent-debug";
+
+  /**
+   * The name of the "propertyFile" property. May specify as cmd-line arg
+   */
+  public static final String PROPERTY_FILE_NAME = "property-file";
+
+  /**
+   * The name of the "gfAgentPropertyFile" property, can be specified as 
System Property
+   */
+  public static final String AGENT_PROPSFILE_PROPERTY_NAME = 
"gfAgentPropertyFile";
+
+  // -------------------------------------------------------------------------
+  //   DistributionLocator properties...
+  // -------------------------------------------------------------------------
+
+  /**
+   * The name of the "locator.host-" property
+   */
+  public static final String LOCATOR_HOST_NAME = "locator.host-";
+  /**
+   * The name of the "locator.port-" property
+   */
+  public static final String LOCATOR_PORT_NAME = "locator.port-";
+  /**
+   * The name of the "locator.product-directory-" property
+   */
+  public static final String LOCATOR_PRODUCT_DIRECTORY_NAME = 
"locator.product-directory-";
+  /**
+   * The name of the "locator.working-directory-" property
+   */
+  public static final String LOCATOR_WORKING_DIRECTORY_NAME = 
"locator.working-directory-";
+  /**
+   * The name of the "locator.remote-command-" property
+   */
+  public static final String LOCATOR_REMOTE_COMMAND = 
"locator.remote-command-";
+  /**
+   * The name of the "locator.bind-address-" property
+   */
+  public static final String LOCATOR_BIND_ADDRESS = "locator.bind-address-";
+  /**
+   * the properties used in configuring a locator's distributed system
+   */
+  public static final String LOCATOR_DS_PROPERTIES = "locator.ds-properties";
+
+  /**
+   * The default log file for stand-alone JMX agents
+   */
+  /*package scope*/
+  static final String DEFAULT_LOG_FILE = "agent.log";
+
+  /**
+   * The default startup log file to be used by agent launcher
+   */
+  /*package scope*/
+  static final String DEFAULT_STARTUP_LOG_FILE = "start_agent.log";
+
+  private static String OBFUSCATED_STRING = "********";
+
+  //////////////////////  Static Methods  //////////////////////
+
+  /**
+   * The <code>propertyFile</code> is the name of the property file that will
+   * be loaded on startup of the Agent.
+   * <p>
+   * The file will be searched for, in order, in the following directories:
+   * <ol>
+   * <li> the current directory
+   * <li> the home directory
+   * <li> the class path
+   * </ol>
+   * Only the first file found will be used.
+   * <p>
+   * The default value of propertyFile is <code>"agent.properties"</code>. 
However
+   * if the "gfAgentPropertyFile" system property is set then its value is the
+   * value of propertyFile. If this value is a relative file system path then
+   * the above search is done. If its an absolute file system path then that
+   * file must exist; no search for it is done.
+   */
+  static String retrievePropertyFile() {
+    return System.getProperty(AGENT_PROPSFILE_PROPERTY_NAME, 
DEFAULT_PROPERTY_FILE);
+  }
+
+  /**
+   * Creates a new <code>Properties</code> object that contains all of
+   * the default values.
+   */
+  private static Properties getDefaultProperties() {
+    Properties props = new Properties();
+
+    props.setProperty(AUTO_CONNECT_NAME, String.valueOf(DEFAULT_AUTO_CONNECT));
+
+    props.setProperty(HTTP_ENABLED_NAME, String.valueOf(DEFAULT_HTTP_ENABLED));
+    props.setProperty(HTTP_BIND_ADDRESS_NAME, 
String.valueOf(DEFAULT_HTTP_BIND_ADDRESS));
+    props.setProperty(HTTP_PORT_NAME, String.valueOf(DEFAULT_HTTP_PORT));
+    props.setProperty(HTTP_AUTHENTICATION_ENABLED_NAME, 
String.valueOf(DEFAULT_HTTP_AUTHENTICATION_ENABLED));
+    props.setProperty(HTTP_AUTHENTICATION_USER_NAME, 
String.valueOf(DEFAULT_HTTP_AUTHENTICATION_USER));
+    props.setProperty(HTTP_AUTHENTICATION_PASSWORD_NAME, 
String.valueOf(DEFAULT_HTTP_AUTHENTICATION_PASSWORD));
+
+    props.setProperty(RMI_ENABLED_NAME, String.valueOf(DEFAULT_RMI_ENABLED));
+    props.setProperty(RMI_REGISTRY_ENABLED_NAME, 
String.valueOf(DEFAULT_RMI_REGISTRY_ENABLED));
+    props.setProperty(RMI_BIND_ADDRESS_NAME, 
String.valueOf(DEFAULT_RMI_BIND_ADDRESS));
+    props.setProperty(RMI_PORT_NAME, String.valueOf(DEFAULT_RMI_PORT));
+    props.setProperty(RMI_SERVER_PORT_NAME, 
String.valueOf(DEFAULT_RMI_SERVER_PORT));
+
+    props.setProperty(SNMP_ENABLED_NAME, String.valueOf(DEFAULT_SNMP_ENABLED));
+    props.setProperty(SNMP_DIRECTORY_NAME, 
String.valueOf(DEFAULT_SNMP_DIRECTORY));
+
+    props.setProperty(AGENT_SSL_ENABLED_NAME, 
String.valueOf(DEFAULT_AGENT_SSL_ENABLED));
+    props.setProperty(AGENT_SSL_PROTOCOLS_NAME, 
String.valueOf(DEFAULT_AGENT_SSL_PROTOCOLS));
+    props.setProperty(AGENT_SSL_CIPHERS_NAME, 
String.valueOf(DEFAULT_AGENT_SSL_CIPHERS));
+    props.setProperty(AGENT_SSL_REQUIRE_AUTHENTICATION_NAME, 
String.valueOf(DEFAULT_AGENT_SSL_REQUIRE_AUTHENTICATION));
+    props.setProperty(HTTP_SSL_REQUIRE_AUTHENTICATION_NAME, 
String.valueOf(DEFAULT_HTTP_SSL_REQUIRE_AUTHENTICATION));
+
+    return props;
+  }
+
+  /**
+   * Returns default values for all valid agent properties as a Properties
+   * object.
+   * @return default values for all valid agent properties
+   */
+  static Properties getDefaultValuesForAllProperties() {
+    Properties props = new Properties();
+
+    props.setProperty(AUTO_CONNECT_NAME, String.valueOf(DEFAULT_AUTO_CONNECT));
+
+    props.setProperty(HTTP_ENABLED_NAME, String.valueOf(DEFAULT_HTTP_ENABLED));
+
+    props.setProperty(HTTP_BIND_ADDRESS_NAME, 
String.valueOf(DEFAULT_HTTP_BIND_ADDRESS));
+
+    props.setProperty(HTTP_PORT_NAME, String.valueOf(DEFAULT_HTTP_PORT));
+
+    props.setProperty(HTTP_AUTHENTICATION_ENABLED_NAME, 
String.valueOf(DEFAULT_HTTP_AUTHENTICATION_ENABLED));
+
+    props.setProperty(HTTP_AUTHENTICATION_USER_NAME, 
String.valueOf(DEFAULT_HTTP_AUTHENTICATION_USER));
+
+    props.setProperty(HTTP_AUTHENTICATION_PASSWORD_NAME, 
String.valueOf(DEFAULT_HTTP_AUTHENTICATION_PASSWORD));
+
+    props.setProperty(RMI_ENABLED_NAME, String.valueOf(DEFAULT_RMI_ENABLED));
+
+    props.setProperty(RMI_REGISTRY_ENABLED_NAME, 
String.valueOf(DEFAULT_RMI_REGISTRY_ENABLED));
+
+    props.setProperty(RMI_BIND_ADDRESS_NAME, 
String.valueOf(DEFAULT_RMI_BIND_ADDRESS));
+
+    props.setProperty(RMI_PORT_NAME, String.valueOf(DEFAULT_RMI_PORT));
+
+    props.setProperty(RMI_SERVER_PORT_NAME, 
String.valueOf(DEFAULT_RMI_SERVER_PORT));
+
+    props.setProperty(SNMP_ENABLED_NAME, String.valueOf(DEFAULT_SNMP_ENABLED));
+
+    props.setProperty(SNMP_DIRECTORY_NAME, 
String.valueOf(DEFAULT_SNMP_DIRECTORY));
+
+    props.setProperty(AGENT_SSL_ENABLED_NAME, 
String.valueOf(DEFAULT_AGENT_SSL_ENABLED));
+
+    props.setProperty(AGENT_SSL_PROTOCOLS_NAME, 
String.valueOf(DEFAULT_AGENT_SSL_PROTOCOLS));
+
+    props.setProperty(AGENT_SSL_CIPHERS_NAME, 
String.valueOf(DEFAULT_AGENT_SSL_CIPHERS));
+
+    props.setProperty(AGENT_SSL_REQUIRE_AUTHENTICATION_NAME, 
String.valueOf(DEFAULT_AGENT_SSL_REQUIRE_AUTHENTICATION));
+
+    props.setProperty(HTTP_SSL_REQUIRE_AUTHENTICATION_NAME, 
String.valueOf(DEFAULT_HTTP_SSL_REQUIRE_AUTHENTICATION));
+
+    props.setProperty(SNMP_BIND_ADDRESS_NAME, 
String.valueOf(DEFAULT_SNMP_BIND_ADDRESS));
+
+    props.setProperty(EMAIL_NOTIFICATIONS_ENABLED_NAME, 
String.valueOf(DEFAULT_EMAIL_NOTIFICATIONS_ENABLED));
+
+    props.setProperty(EMAIL_NOTIFICATIONS_HOST_NAME, 
String.valueOf(DEFAULT_EMAIL_HOST));
+
+    props.setProperty(EMAIL_NOTIFICATIONS_FROM_NAME, 
String.valueOf(DEFAULT_EMAIL_FROM));
+
+    props.setProperty(EMAIL_NOTIFICATIONS_TO_LIST_NAME, 
String.valueOf(DEFAULT_EMAIL_TO_LIST));
+
+    props.setProperty(STATE_SAVE_FILE_NAME, 
String.valueOf(DEFAULT_STATE_SAVE_FILE));
+
+    props.setProperty(CLUSTER_SSL_ENABLED, 
String.valueOf(DEFAULT_SSL_ENABLED));
+
+    props.setProperty(CLUSTER_SSL_PROTOCOLS, 
String.valueOf(DEFAULT_SSL_PROTOCOLS));
+
+    props.setProperty(CLUSTER_SSL_CIPHERS, 
String.valueOf(DEFAULT_SSL_CIPHERS));
+
+    props.setProperty(CLUSTER_SSL_REQUIRE_AUTHENTICATION, 
String.valueOf(DEFAULT_SSL_REQUIRE_AUTHENTICATION));
+
+    props.setProperty(ENTITY_CONFIG_XML_FILE_NAME, 
String.valueOf(DEFAULT_ENTITY_CONFIG_XML_FILE));
+
+    props.setProperty(MCAST_PORT, String.valueOf(DEFAULT_MCAST_PORT));
+
+    props.setProperty(MCAST_ADDRESS, String.valueOf(DEFAULT_MCAST_ADDRESS));
+
+    props.setProperty(LOCATORS, String.valueOf(DEFAULT_LOCATORS));
+
+    props.setProperty(BIND_ADDRESS, String.valueOf(DEFAULT_BIND_ADDRESS));
+
+    props.setProperty(REMOTE_COMMAND_NAME, 
String.valueOf(DEFAULT_REMOTE_COMMAND));
+
+    props.setProperty(LOG_FILE_NAME, String.valueOf(DEFAULT_LOG_FILE));
+
+    props.setProperty(LOG_LEVEL_NAME, String.valueOf(DEFAULT_LOG_LEVEL));
+
+    props.setProperty(LOG_DISK_SPACE_LIMIT_NAME, 
String.valueOf(DEFAULT_LOG_DISK_SPACE_LIMIT));
+
+    props.setProperty(LOG_FILE_SIZE_LIMIT_NAME, 
String.valueOf(DEFAULT_LOG_FILE_SIZE_LIMIT));
+
+    props.setProperty(REFRESH_INTERVAL_NAME, 
String.valueOf(DEFAULT_REFRESH_INTERVAL));
+
+    return props;
+
+  }
+
+  // -------------------------------------------------------------------------
+  //   Member variable(s)
+  // -------------------------------------------------------------------------
+
+  /**
+   * Does agent automatically connect to the distributed system?
+   */
+  private boolean autoConnect;
+
+  /**
+   * True if Agent adaptors should use SSL
+   */
+  private boolean agentSSLEnabled;
+
+  /**
+   * The SSL Protocols that the Agent adaptors will use
+   */
+  private String agentSSLProtocols;
+
+  /**
+   * The SSL Ciphers that the Agent adaptors will use
+   */
+  private String agentSSLCiphers;
+
+  /**
+   * True if Agent adaptors require authentication when SSL is enabled
+   */
+  private boolean agentSSLRequireAuth;
+
+  /**
+   * HttpAdaptor won't work with ssl authentication required, so this attribute
+   * allows this option to be turned on for RMI but off for HTTP in the event
+   * that both adaptors are being used with ssl.
+   */
+  private boolean httpSSLRequireAuth;
+
+  /**
+   * True if HttpAdaptor authentication is enabled
+   */
+  private boolean httpAuthEnabled;
+
+  /**
+   * The login user for HttpAdaptor authentication
+   */
+  private String httpAuthUser;
+
+  /**
+   * The login password for HttpAdaptor authentication
+   */
+  private String httpAuthPassword;
+
+  /**
+   * True if the HttpAdaptor is enabled
+   */
+  private boolean httpEnabled;
+
+  /**
+   * The port for the MX4J HttpAdatper
+   */
+  private int httpPort;
+
+  /**
+   * The host for the MX4J HttpAdatper
+   */
+  private String httpBindAddress;
+
+  /**
+   * True if the RMIConnectorServer is enabled
+   */
+  private boolean rmiEnabled;
+
+  /**
+   * True if the Agent is to create its own RMI registry
+   */
+  private boolean rmiRegistryEnabled;
+
+  /**
+   * The host for the MX4J RMIConnectorServer
+   */
+  private String rmiBindAddress;
+
+  /**
+   * The port for the RMI Registry created by the Agent
+   */
+  private int rmiPort;
+
+  /**
+   * The port for the MX4J RMIConnectorServer
+   */
+  private int rmiServerPort;
+
+  /**
+   * True if the SnmpAdaptor is enabled
+   */
+  private boolean snmpEnabled;
+
+  /**
+   * The bind address for sockets used by the SNMP adapter
+   */
+  private String snmpBindAddress;
+
+  /**
+   * Path to the directory containing the SNMP Adaptor and its sub-dirs
+   */
+  private String snmpDirectory;
+
+  /**
+   * Is Email notification enabled
+   */
+  private boolean isEmailNotificationEnabled;
+
+  /**
+   * Email notification from: emailID
+   */
+  private String emailNotificationFrom;
+
+  /**
+   * The host name of the mail server to be used for email communication.
+   */
+  private String emailNotificationHostName;
+
+  /**
+   * Email notification to: emailIDs list
+   */
+  private String emailNotificationToList;
+
+  /**
+   * State Save File Name
+   */
+  private String stateSaveFile;
+
+  /**
+   * Describes the property file used to load configuration from.
+   * Null if no file was found.
+   */
+  private URL url;
+
+  /**
+   * Original command line arguments
+   */
+  private String[] originalCmdLineArgs = null;
+
+  /**
+   * The <code>Agent</code> that is configured by this
+   * <code>AgentConfigImpl</code>
+   */
+  private Agent agent;
+
+  // -------------------------------------------------------------------------
+  //   Constructor(s)
+  // -------------------------------------------------------------------------
+
+  /**
+   * Constructs new instance of <code>AgentConfigImpl</code> with the
+   * default configuration.
+   */
+  public AgentConfigImpl() {
+    this(getDefaultProperties());
+  }
+
+  /**
+   * Constructs new instance of AgentConfig. Supplied command-line arguments
+   * are used to create a set of non-default properties for initializing this
+   * AgentConfig.
+   * @param args array of non-default configuration arguments
+   */
+  public AgentConfigImpl(String[] args) {
+    this(toProperties(args));
+    this.originalCmdLineArgs = args;
+  }
+
+  /**
+   * Creates a new <code>AgentConfig</code> with the given non-default
+   * configuration properties.
+   * @param props overriding non-default configuration properties
+   */
+  public AgentConfigImpl(Properties props) {
+    // for admin bug #40434
+    
super(filterOutAgentProperties(appendOptionalPropertyFileProperties(props)), 
true/*ignore gemfire.properties*/);
+
+    // first get any property values set in the optional property file
+    this.url = getPropertyFileURL(retrievePropertyFile());
+
+    initialize(appendOptionalPropertyFileProperties(props));
+  }
+
+  /**
+   * Constructs new instance of AgentConfig using the specified property file.
+   * @param propFile the file to load configuration properties from
+   */
+  public AgentConfigImpl(File propFile) {
+    // Initialize default values
+    this();
+
+    Properties props = new Properties();
+    if (propFile.exists()) {
+      try {
+        FileInputStream in = new FileInputStream(propFile);
+        props.load(in);
+        in.close();
+      } catch (java.io.IOException e) {
+        throw new 
GemFireIOException(LocalizedStrings.AgentConfigImpl_FAILED_READING_0.toLocalizedString(propFile),
 e);
+      }
+    } else {
+      throw new 
IllegalArgumentException(LocalizedStrings.AgentConfigImpl_SPECIFIED_PROPERTIES_FILE_DOES_NOT_EXIST_0.toLocalizedString(propFile));
+    }
+
+    initialize(props);
+  }
+
+  //////////////////////  Instance Methods  //////////////////////
+
+  /**
+   * Sets the <code>Agent</code> associated with this
+   * <code>AgentConfigImpl</code>.
+   */
+  void setAgent(Agent agent) {
+    this.agent = agent;
+  }
+
+  /**
+   * Checks to see if this config object is "read only".  If it is,
+   * then an {@link IllegalStateException} is thrown.
+   * @since GemFire 4.0
+   */
+  @Override
+  protected void checkReadOnly() {
+    if (this.agent != null) {
+      throw new 
IllegalStateException(LocalizedStrings.AgentConfigImpl_AN_AGENTCONFIG_OBJECT_CANNOT_BE_MODIFIED_AFTER_IT_HAS_BEEN_USED_TO_CREATE_AN_AGENT.toLocalizedString());
+    }
+
+    super.checkReadOnly();
+  }
+
+  // -------------------------------------------------------------------------
+  //   Methods for handling Properties and the Properties file
+  // -------------------------------------------------------------------------
+
+  /**
+   * Returns a description of the property file used to load this config.
+   * If no property file was used then the description will say so.
+   */
+  public String getPropertyFileDescription() {
+    /*
+     * Checking if the specified or the default properties file exists. If not,
+     * just log this as an information.
+     */
+    if (this.url == null) {
+      return 
LocalizedStrings.AgentConfigImpl_USING_DEFAULT_CONFIGURATION_BECAUSE_PROPERTY_FILE_WAS_FOUND.toLocalizedString();
+    } else {
+      return 
LocalizedStrings.AgentConfigImpl_CONFIGURATION_LOADED_FROM_0.toLocalizedString(this.url);
+    }
+  }
+
+  /**
+   * Returns the default property file that will be used when configuration
+   * is saved.
+   */
+  public File getPropertyFile() {
+    File f;
+    if (this.url == null) {
+      f = new File(retrievePropertyFile());
+      if (!f.isAbsolute()) {
+        // save to <cwd>/propertyFile
+        f = new File(System.getProperty("user.dir"), retrievePropertyFile());
+      }
+    } else {
+      f = new File(this.url.getFile());
+    }
+    return f;
+  }
+
+  /**
+   * Converts the contents of this config to a property instance and 
Stringifies
+   * it
+   * @return contents of this config as String
+   */
+  public String toPropertiesAsString() {
+    Properties p = toProperties(true /* include DS properties */);
+
+    StringWriter sw = new StringWriter();
+    PrintWriter pw = new PrintWriter(sw);
+    
pw.println(LocalizedStrings.AgentConfigImpl_AGENT_CONFIGURATION.toLocalizedString());
+    Enumeration e = p.propertyNames();
+    while (e.hasMoreElements()) {
+      String pn = (String) e.nextElement();
+      String pv = p.getProperty(pn);
+      pw.println("  " + pn + " = " + pv);
+    }
+    pw.close();
+
+    return sw.toString();
+  }
+
+  /**
+   * Converts the contents of this config to a property instance.
+   * @return contents of this config as java.util.Properties
+   */
+  public Properties toProperties() {
+    return toProperties(false /* include DS properties */);
+  }
+
+  /**
+   * Converts the contents of this config to a property instance.
+   * @param includeDSProperties Should distributed system properties be 
included in the
+   * <code>Properties</code> object?  See bug 32682.
+   *
+   * @return contents of this config as java.util.Properties
+   */
+  public Properties toProperties(boolean includeDSProperties) {
+    Properties props = new Properties();
+
+    props.setProperty(AUTO_CONNECT_NAME, toString(AUTO_CONNECT_NAME, 
getAutoConnect()));
+
+    props.setProperty(HTTP_ENABLED_NAME, toString(HTTP_ENABLED_NAME, 
isHttpEnabled()));
+    props.setProperty(HTTP_BIND_ADDRESS_NAME, toString(HTTP_BIND_ADDRESS_NAME, 
getHttpBindAddress()));
+    props.setProperty(HTTP_PORT_NAME, toString(HTTP_PORT_NAME, getHttpPort()));
+
+    props.setProperty(RMI_ENABLED_NAME, toString(RMI_ENABLED_NAME, 
isRmiEnabled()));
+    props.setProperty(RMI_REGISTRY_ENABLED_NAME, 
toString(RMI_REGISTRY_ENABLED_NAME, isRmiRegistryEnabled()));
+    props.setProperty(RMI_BIND_ADDRESS_NAME, toString(RMI_BIND_ADDRESS_NAME, 
getRmiBindAddress()));
+    props.setProperty(RMI_PORT_NAME, toString(RMI_PORT_NAME, getRmiPort()));
+    props.setProperty(RMI_SERVER_PORT_NAME, toString(RMI_SERVER_PORT_NAME, 
getRmiServerPort()));
+
+    props.setProperty(SNMP_ENABLED_NAME, toString(SNMP_ENABLED_NAME, 
isSnmpEnabled()));
+    props.setProperty(SNMP_BIND_ADDRESS_NAME, toString(SNMP_BIND_ADDRESS_NAME, 
getSnmpBindAddress()));
+    props.setProperty(SNMP_DIRECTORY_NAME, toString(SNMP_DIRECTORY_NAME, 
getSnmpDirectory()));
+
+    props.setProperty(AGENT_SSL_ENABLED_NAME, toString(AGENT_SSL_ENABLED_NAME, 
isAgentSSLEnabled()));
+    props.setProperty(AGENT_SSL_PROTOCOLS_NAME, 
toString(AGENT_SSL_PROTOCOLS_NAME, getAgentSSLProtocols()));
+    props.setProperty(AGENT_SSL_CIPHERS_NAME, toString(AGENT_SSL_CIPHERS_NAME, 
getAgentSSLCiphers()));
+    props.setProperty(AGENT_SSL_REQUIRE_AUTHENTICATION_NAME, 
toString(AGENT_SSL_REQUIRE_AUTHENTICATION_NAME, isAgentSSLRequireAuth()));
+    props.setProperty(HTTP_SSL_REQUIRE_AUTHENTICATION_NAME, 
toString(HTTP_SSL_REQUIRE_AUTHENTICATION_NAME, isHttpSSLRequireAuth()));
+
+    props.setProperty(HTTP_AUTHENTICATION_ENABLED_NAME, 
toString(HTTP_AUTHENTICATION_ENABLED_NAME, isHttpAuthEnabled()));
+    props.setProperty(HTTP_AUTHENTICATION_USER_NAME, 
toString(HTTP_AUTHENTICATION_USER_NAME, getHttpAuthUser()));
+    props.setProperty(HTTP_AUTHENTICATION_PASSWORD_NAME, 
toString(HTTP_AUTHENTICATION_PASSWORD_NAME, getHttpAuthPassword()));
+
+    props.setProperty(EMAIL_NOTIFICATIONS_ENABLED_NAME, 
toString(EMAIL_NOTIFICATIONS_ENABLED_NAME, isEmailNotificationEnabled()));
+    props.setProperty(EMAIL_NOTIFICATIONS_HOST_NAME, 
toString(EMAIL_NOTIFICATIONS_HOST_NAME, getEmailNotificationHost()));
+    props.setProperty(EMAIL_NOTIFICATIONS_FROM_NAME, 
toString(EMAIL_NOTIFICATIONS_FROM_NAME, getEmailNotificationFrom()));
+    props.setProperty(EMAIL_NOTIFICATIONS_TO_LIST_NAME, 
toString(EMAIL_NOTIFICATIONS_TO_LIST_NAME, getEmailNotificationToList()));
+
+    props.setProperty(STATE_SAVE_FILE_NAME, toString(STATE_SAVE_FILE_NAME, 
getStateSaveFile()));
+
+    props.setProperty(EMAIL_NOTIFICATIONS_ENABLED_NAME, 
toString(EMAIL_NOTIFICATIONS_ENABLED_NAME, isEmailNotificationEnabled()));
+    props.setProperty(EMAIL_NOTIFICATIONS_HOST_NAME, 
toString(EMAIL_NOTIFICATIONS_HOST_NAME, getEmailNotificationHost()));
+    props.setProperty(EMAIL_NOTIFICATIONS_FROM_NAME, 
toString(EMAIL_NOTIFICATIONS_FROM_NAME, getEmailNotificationFrom()));
+    props.setProperty(EMAIL_NOTIFICATIONS_TO_LIST_NAME, 
toString(EMAIL_NOTIFICATIONS_TO_LIST_NAME, getEmailNotificationToList()));
+
+    props.setProperty(CLUSTER_SSL_ENABLED, toString(CLUSTER_SSL_ENABLED, 
isSSLEnabled()));
+    props.setProperty(CLUSTER_SSL_PROTOCOLS, toString(CLUSTER_SSL_PROTOCOLS, 
getSSLProtocols()));
+    props.setProperty(CLUSTER_SSL_CIPHERS, toString(CLUSTER_SSL_CIPHERS, 
getSSLCiphers()));
+    props.setProperty(CLUSTER_SSL_REQUIRE_AUTHENTICATION, 
toString(CLUSTER_SSL_REQUIRE_AUTHENTICATION, isSSLAuthenticationRequired()));
+
+    Properties sslProps = getSSLProperties();
+    if (sslProps.size() > 0) {
+      int sequence = 0;
+      for (Iterator iter = sslProps.keySet().iterator(); iter.hasNext(); ) {
+        String key = (String) iter.next();
+        String value = sslProps.getProperty(key);
+        props.setProperty("ssl-property-" + sequence, key + "=" + 
OBFUSCATED_STRING);
+        sequence++;
+      }
+    }
+
+    if (this.getDistributionLocatorConfigs().length > 0) {
+      DistributionLocatorConfig[] configs = 
this.getDistributionLocatorConfigs();
+      for (int i = 0; i < configs.length; i++) {
+        DistributionLocatorConfig locator = configs[i];
+        props.setProperty(LOCATOR_HOST_NAME + i, toString(LOCATOR_HOST_NAME, 
locator.getHost()));
+        props.setProperty(LOCATOR_PORT_NAME + i, toString(LOCATOR_PORT_NAME, 
locator.getPort()));
+        props.setProperty(LOCATOR_PRODUCT_DIRECTORY_NAME + i, 
toString(LOCATOR_PRODUCT_DIRECTORY_NAME, locator.getProductDirectory()));
+        props.setProperty(LOCATOR_WORKING_DIRECTORY_NAME + i, 
toString(LOCATOR_WORKING_DIRECTORY_NAME, locator.getWorkingDirectory()));
+        props.setProperty(LOCATOR_REMOTE_COMMAND + i, 
toString(LOCATOR_REMOTE_COMMAND, locator.getRemoteCommand()));
+        props.setProperty(LOCATOR_BIND_ADDRESS + i, 
toString(LOCATOR_BIND_ADDRESS, locator.getBindAddress()));
+        //        props.setProperty(LOCATOR_DS_PROPERTIES + i,
+        //                          getdsPropertiesString(locator));
+      }
+    }
+
+    if (includeDSProperties) {
+      props.setProperty(ENTITY_CONFIG_XML_FILE_NAME, 
toString(ENTITY_CONFIG_XML_FILE_NAME, getEntityConfigXMLFile()));
+      // This could be different each time agent is started
+      //       props.setProperty(SYSTEM_ID_NAME, toString(getSystemId()));
+      props.setProperty(MCAST_PORT, toString(MCAST_PORT, getMcastPort()));
+      props.setProperty(MCAST_ADDRESS, toString(MCAST_ADDRESS, 
getMcastAddress()));
+      props.setProperty(LOCATORS, toString(LOCATORS, getLocators()));
+      props.setProperty(MEMBERSHIP_PORT_RANGE_NAME, getMembershipPortRange());
+      props.setProperty(TCP_PORT, "" + getTcpPort());
+      props.setProperty(BIND_ADDRESS, toString(BIND_ADDRESS, 
getBindAddress()));
+      props.setProperty(REMOTE_COMMAND_NAME, toString(REMOTE_COMMAND_NAME, 
getRemoteCommand()));
+      props.setProperty(LOG_FILE_NAME, toString(LOG_FILE_NAME, getLogFile()));
+      props.setProperty(LOG_LEVEL_NAME, toString(LOG_LEVEL_NAME, 
getLogLevel()));
+      props.setProperty(LOG_DISK_SPACE_LIMIT_NAME, 
toString(LOG_DISK_SPACE_LIMIT_NAME, getLogDiskSpaceLimit()));
+      props.setProperty(LOG_FILE_SIZE_LIMIT_NAME, 
toString(LOG_FILE_SIZE_LIMIT_NAME, getLogFileSizeLimit()));
+      props.setProperty(REFRESH_INTERVAL_NAME, toString(REFRESH_INTERVAL_NAME, 
getRefreshInterval()));
+    }
+
+    return props;
+  }
+
+
+  // -------------------------------------------------------------------------
+  //   Agent specific properties
+  // -------------------------------------------------------------------------
+
+  public boolean isAgentSSLEnabled() {
+    return this.agentSSLEnabled;
+  }
+
+  public void setAgentSSLEnabled(boolean agentSSLEnabled) {
+    checkReadOnly();
+    this.agentSSLEnabled = agentSSLEnabled;
+    configChanged();
+  }
+
+  public String getAgentSSLProtocols() {
+    return this.agentSSLProtocols;
+  }
+
+  public void setAgentSSLProtocols(String agentSSLProtocols) {
+    checkReadOnly();
+    this.agentSSLProtocols = agentSSLProtocols;
+    configChanged();
+  }
+
+  public String getAgentSSLCiphers() {
+    return this.agentSSLCiphers;
+  }
+
+  public void setAgentSSLCiphers(String agentSSLCiphers) {
+    checkReadOnly();
+    this.agentSSLCiphers = agentSSLCiphers;
+    configChanged();
+  }
+
+  public boolean isAgentSSLRequireAuth() {
+    return this.agentSSLRequireAuth;
+  }
+
+  public void setAgentSSLRequireAuth(boolean agentSSLRequireAuth) {
+    checkReadOnly();
+    this.agentSSLRequireAuth = agentSSLRequireAuth;
+    configChanged();
+  }
+
+  public boolean isHttpSSLRequireAuth() {
+    return this.httpSSLRequireAuth;
+  }
+
+  public void setHttpSSLRequireAuth(boolean httpSSLRequireAuth) {
+    checkReadOnly();
+    this.httpSSLRequireAuth = httpSSLRequireAuth;
+    configChanged();
+  }
+
+  public boolean isHttpAuthEnabled() {
+    return this.httpAuthEnabled;
+  }
+
+  public void setHttpAuthEnabled(boolean httpAuthEnabled) {
+    checkReadOnly();
+    this.httpAuthEnabled = httpAuthEnabled;
+    configChanged();
+  }
+
+  public String getHttpAuthUser() {
+    return this.httpAuthUser;
+  }
+
+  public void setHttpAuthUser(String httpAuthUser) {
+    checkReadOnly();
+    this.httpAuthUser = httpAuthUser;
+    configChanged();
+  }
+
+  public String getHttpAuthPassword() {
+    return this.httpAuthPassword;
+  }
+
+  public void setHttpAuthPassword(String httpAuthPassword) {
+    checkReadOnly();
+    this.httpAuthPassword = httpAuthPassword;
+    configChanged();
+  }
+
+  public boolean isSnmpEnabled() {
+    return this.snmpEnabled;
+  }
+
+  public void setSnmpEnabled(boolean snmpEnabled) {
+    checkReadOnly();
+    this.snmpEnabled = snmpEnabled;
+    configChanged();
+  }
+
+  public String getSnmpBindAddress() {
+    return this.snmpBindAddress;
+  }
+
+  public void setSnmpBindAddress(String snmpBindAddress) {
+    checkReadOnly();
+    this.snmpBindAddress = validateSnmpBindAddress(snmpBindAddress);
+    configChanged();
+  }
+
+  public String getSnmpDirectory() {
+    return this.snmpDirectory;
+  }
+
+  public void setSnmpDirectory(String snmpDirectory) {
+    checkReadOnly();
+    this.snmpDirectory = validateSnmpDirectory(snmpDirectory);
+    configChanged();
+  }
+
+  public boolean isRmiEnabled() {
+    return this.rmiEnabled;
+  }
+
+  public void setRmiEnabled(boolean rmiEnabled) {
+    checkReadOnly();
+    this.rmiEnabled = rmiEnabled;
+    configChanged();
+  }
+
+  public boolean isRmiRegistryEnabled() {
+    return this.rmiRegistryEnabled;
+  }
+
+  public void setRmiRegistryEnabled(boolean rmiRegistryEnabled) {
+    checkReadOnly();
+    this.rmiRegistryEnabled = rmiRegistryEnabled;
+    configChanged();
+  }
+
+  public String getRmiBindAddress() {
+    return this.rmiBindAddress;
+  }
+
+  public void setRmiBindAddress(String rmiBindAddress) {
+    checkReadOnly();
+    this.rmiBindAddress = validateRmiBindAddress(rmiBindAddress);
+    configChanged();
+  }
+
+  public int getRmiPort() {
+    return this.rmiPort;
+  }
+
+  public void setRmiPort(int rmiPort) {
+    checkReadOnly();
+    this.rmiPort = validateRmiPort(rmiPort);
+    configChanged();
+  }
+
+  /**
+   * Returns the port of the RMI Connector Server.
+   * <p>
+   * See <a href="#rmi-server-port">description</a> above.
+   * @return the value set for rmi-server-port
+   *
+   * @since GemFire 6.5
+   */
+  public int getRmiServerPort() {
+    return this.rmiServerPort;
+  }
+
+  /**
+   * Sets the port of the RMI Connector Server.
+   * @param port rmi-server-port to set.
+   *
+   * @since GemFire 6.5
+   */
+  public void setRmiServerPort(int port) {
+    checkReadOnly();
+    this.rmiServerPort = validateRmiServerPort(rmiServerPort);
+    configChanged();
+  }
+
+  public boolean isHttpEnabled() {
+    return this.httpEnabled;
+  }
+
+  public void setHttpEnabled(boolean httpEnabled) {
+    checkReadOnly();
+    this.httpEnabled = httpEnabled;
+    configChanged();
+  }
+
+  public int getHttpPort() {
+    return this.httpPort;
+  }
+
+  public void setHttpPort(int httpPort) {
+    checkReadOnly();
+    this.httpPort = validateHttpPort(httpPort);
+    configChanged();
+  }
+
+  public String getHttpBindAddress() {
+    return this.httpBindAddress;
+  }
+
+  public void setHttpBindAddress(String httpBindAddress) {
+    checkReadOnly();
+    this.httpBindAddress = validateHttpBindAddress(httpBindAddress);
+    configChanged();
+  }
+
+  public void setHttpBindAddress(InetAddress httpBindAddress) {
+    checkReadOnly();
+    this.httpBindAddress = validateHttpBindAddress(httpBindAddress);
+    configChanged();
+  }
+
+  public boolean getAutoConnect() {
+    return this.autoConnect;
+  }
+
+  public void setAutoConnect(boolean v) {
+    checkReadOnly();
+    this.autoConnect = v;
+    configChanged();
+  }
+
+  // -------------------------------------------------------------------------
+  //   Implementation methods
+  // -------------------------------------------------------------------------
+
+  /**
+   * Initialize the values of this AgentConfig.
+   * @param props the configuration values to use
+   */
+  private void initialize(Properties props) {
+    this.autoConnect = validateBoolean(props.getProperty(AUTO_CONNECT_NAME), 
DEFAULT_AUTO_CONNECT);
+
+    this.httpEnabled = validateBoolean(props.getProperty(HTTP_ENABLED_NAME), 
DEFAULT_HTTP_ENABLED);
+    this.httpBindAddress = 
validateHttpBindAddress(props.getProperty(HTTP_BIND_ADDRESS_NAME));
+    this.httpPort = validateHttpPort(props.getProperty(HTTP_PORT_NAME));
+
+    this.rmiEnabled = validateBoolean(props.getProperty(RMI_ENABLED_NAME), 
DEFAULT_RMI_ENABLED);
+    this.rmiRegistryEnabled = 
validateBoolean(props.getProperty(RMI_REGISTRY_ENABLED_NAME), 
DEFAULT_RMI_REGISTRY_ENABLED);
+
+    this.rmiBindAddress = 
validateRmiBindAddress(props.getProperty(RMI_BIND_ADDRESS_NAME));
+    this.rmiPort = validateRmiPort(props.getProperty(RMI_PORT_NAME));
+    this.rmiServerPort = 
validateRmiServerPort(props.getProperty(RMI_SERVER_PORT_NAME));
+
+    this.snmpEnabled = validateBoolean(props.getProperty(SNMP_ENABLED_NAME), 
DEFAULT_SNMP_ENABLED);
+    this.snmpDirectory = 
validateSnmpDirectory(props.getProperty(SNMP_DIRECTORY_NAME));
+
+    this.agentSSLEnabled = 
validateBoolean(props.getProperty(AGENT_SSL_ENABLED_NAME), 
DEFAULT_AGENT_SSL_ENABLED);
+    this.agentSSLProtocols = 
validateNonEmptyString(props.getProperty(AGENT_SSL_PROTOCOLS_NAME), 
DEFAULT_AGENT_SSL_PROTOCOLS);
+    this.agentSSLCiphers = 
validateNonEmptyString(props.getProperty(AGENT_SSL_CIPHERS_NAME), 
DEFAULT_AGENT_SSL_CIPHERS);
+    this.agentSSLRequireAuth = 
validateBoolean(props.getProperty(AGENT_SSL_REQUIRE_AUTHENTICATION_NAME), 
DEFAULT_AGENT_SSL_REQUIRE_AUTHENTICATION);
+    this.httpSSLRequireAuth = 
validateBoolean(props.getProperty(HTTP_SSL_REQUIRE_AUTHENTICATION_NAME), 
DEFAULT_HTTP_SSL_REQUIRE_AUTHENTICATION);
+
+    this.httpAuthEnabled = 
validateBoolean(props.getProperty(HTTP_AUTHENTICATION_ENABLED_NAME), 
DEFAULT_HTTP_AUTHENTICATION_ENABLED);
+    this.httpAuthUser = 
validateNonEmptyString(props.getProperty(HTTP_AUTHENTICATION_USER_NAME), 
DEFAULT_HTTP_AUTHENTICATION_USER);
+    this.httpAuthPassword = 
validateNonEmptyString(props.getProperty(HTTP_AUTHENTICATION_PASSWORD_NAME), 
DEFAULT_HTTP_AUTHENTICATION_PASSWORD);
+
+    this.sslEnabled = validateBoolean(props.getProperty(CLUSTER_SSL_ENABLED), 
DEFAULT_SSL_ENABLED);
+    this.sslProtocols = 
validateNonEmptyString(props.getProperty(CLUSTER_SSL_PROTOCOLS), 
DEFAULT_SSL_PROTOCOLS);
+    this.sslCiphers = 
validateNonEmptyString(props.getProperty(CLUSTER_SSL_CIPHERS), 
DEFAULT_SSL_CIPHERS);
+    this.sslAuthenticationRequired = 
validateBoolean(props.getProperty(CLUSTER_SSL_REQUIRE_AUTHENTICATION), 
DEFAULT_SSL_REQUIRE_AUTHENTICATION);
+    this.sslProperties = new Properties();
+    for (int i = 0; true; i++) {
+      String key = "ssl-property-" + i;
+      String value = props.getProperty(key);
+      if (value == null) {
+        break;
+      }
+      StringTokenizer st = new StringTokenizer(value, "=");
+      if (!st.hasMoreTokens()) {
+        break;
+      }
+      String propKey = st.nextToken();
+      if (!st.hasMoreTokens()) {
+        break;
+      }
+      String propValue = st.nextToken();
+      this.sslProperties.put(propKey, propValue);
+    }
+
+    this.isEmailNotificationEnabled = 
validateBoolean(props.getProperty(AgentConfig.EMAIL_NOTIFICATIONS_ENABLED_NAME),
 DEFAULT_EMAIL_NOTIFICATIONS_ENABLED);
+    this.emailNotificationHostName = 
validateNonEmptyString(props.getProperty(AgentConfig.EMAIL_NOTIFICATIONS_HOST_NAME),
 DEFAULT_EMAIL_HOST);
+    this.emailNotificationFrom = 
validateNonEmptyString(props.getProperty(AgentConfig.EMAIL_NOTIFICATIONS_FROM_NAME),
 DEFAULT_EMAIL_FROM);
+    this.emailNotificationToList = 
validateNonEmptyString(props.getProperty(AgentConfig.EMAIL_NOTIFICATIONS_TO_LIST_NAME),
 DEFAULT_EMAIL_TO_LIST);
+
+    this.stateSaveFile = 
validateNonEmptyString(props.getProperty(AgentConfig.STATE_SAVE_FILE_NAME), 
DEFAULT_STATE_SAVE_FILE);
+
+    try {
+      for (int i = 0; true; i++) {
+        String hostProp = props.getProperty(LOCATOR_HOST_NAME + i);
+        if (isEmpty(hostProp)) {
+          break;
+        }
+        String host = hostProp;
+        int port = Integer.parseInt(props.getProperty(LOCATOR_PORT_NAME + i));
+        File workDir = 
validateWorkingDirectory(props.getProperty(LOCATOR_WORKING_DIRECTORY_NAME + i));
+        File prodDir = new 
File(validateProductDirectory(props.getProperty(LOCATOR_PRODUCT_DIRECTORY_NAME 
+ i)));
+        String remoteCmd = props.getProperty(LOCATOR_REMOTE_COMMAND + i);
+        String bindAddr = props.getProperty(LOCATOR_BIND_ADDRESS + i);
+
+        DistributionLocatorConfig config = 
this.createDistributionLocatorConfig();
+        config.setHost(host);
+        config.setPort(port);
+        config.setBindAddress(bindAddr);
+        config.setWorkingDirectory(workDir.getAbsolutePath());
+        config.setProductDirectory(prodDir.getAbsolutePath());
+        config.setRemoteCommand(remoteCmd);
+      }
+    } catch (IllegalArgumentException e) {
+      // This is how we break out of the loop?  Yuck!
+      /*
+       * LogWriter is initialized afterwards. Hence printing the stack trace.
+       * This is done to avoid creation of duplicate log writer.
+       */
+      e.printStackTrace();
+    }
+  }
+
+  /**
+   * Filter all agent configuration attributes out of the given 
<code>Properties</code> object.
+   * <p/>
+   * @param props the <code>Properties</code> object of filter agent 
configuration attributes out of.
+   *
+   * @see AgentConfigImpl#_getPropertyDescription(String)
+   */
+  private static Properties filterOutAgentProperties(final Properties props) {
+    final Properties filteredProps = new Properties();
+
+    for (final Object key : props.keySet()) {
+      if (_getPropertyDescription(key.toString()) == null) {
+        final String value = props.getProperty(key.toString());
+        if (value != null) {
+          filteredProps.setProperty(key.toString(), value);
+        }
+      }
+    }
+
+    appendLogFileProperty(filteredProps);
+
+    return filteredProps;
+  }
+
+  /**
+   * Appends the log-file property to the Properties object if set of 
properties does not already define the
+   * log-file property or the gemfire.agent.log-file property.
+   * <p/>
+   * @param props the <code>Properties</code> to append the log-file property 
to if the property does not exist.
+   */
+  private static void appendLogFileProperty(final Properties props) {
+    if (!(props.containsKey(DistributedSystemConfig.LOG_FILE_NAME) || 
props.containsKey(SYSTEM_PROPERTY_PREFIX + 
DistributedSystemConfig.LOG_FILE_NAME))) {
+      props.put(DistributedSystemConfig.LOG_FILE_NAME, DEFAULT_LOG_FILE);
+    }
+  }
+
+  /**
+   * Appends any additional property-file specified properties to the supplied
+   * Properties. If the supplied property overrides the property in the
+   * property-file, then property-file value is ignored. System Properties 
always
+   * override the supplied properties
+   * @return appendedProps Properties appened to from the property-file if any
+   */
+  private static Properties appendOptionalPropertyFileProperties(final 
Properties props) {
+    final URL url = getPropertyFileURL(retrievePropertyFile());
+    final Properties appendedProps = new Properties();
+
+    appendedProps.putAll(props);
+
+    // first, get any property values set in the optional property file
+    if (url != null) {
+      InputStream in = null;
+
+      try {
+        in = url.openStream();
+
+        final Properties agentPropertyFileProperties = new Properties();
+
+        agentPropertyFileProperties.load(in);
+
+        // don't let any properties from the file override those on the 
command-line
+        for (final Object key : agentPropertyFileProperties.keySet()) {
+          if (props.getProperty(key.toString()) == null) {
+            appendedProps.setProperty(key.toString(), 
agentPropertyFileProperties.getProperty(key.toString()));
+          }
+        }
+      } catch (IOException e) {
+        throw new 
GemFireIOException(LocalizedStrings.AgentConfigImpl_FAILED_READING_0.toLocalizedString(url.toString()),
 e);
+      } finally {
+        IOUtils.close(in);
+      }
+    }
+
+    // last override values with those from the system properties
+    // TODO this is not exactly overriding!
+    for (final Object propSuffix : props.keySet()) {
+      final String key = SYSTEM_PROPERTY_PREFIX + propSuffix;
+      final String value = System.getProperty(key);
+
+      if (value != null) {
+        appendedProps.put(key, value);
+      }
+    }
+
+    return appendedProps;
+  }
+
+  /**
+   * Returns a description of the given agent config property
+   * @throws IllegalArgumentException If <code>prop</code> is not a recognized 
agent
+   * configuration property
+   */
+  public static String getPropertyDescription(String prop) {
+    if (prop.equals(LOG_FILE_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_NAME_OF_THE_AGENTS_LOG_FILE.toLocalizedString();
+    } else if (prop.equals(LOG_LEVEL_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_MINIMUM_LEVEL_OF_LOGGING_PERFORMED_BY_AGENT.toLocalizedString();
+    } else if (prop.equals(AGENT_DEBUG)) {
+      return 
LocalizedStrings.AgentConfigImpl_WHETHER_THE_AGENT_SHOULD_PRINT_DEBUGGING_INFORMATION.toLocalizedString();
+    } else if (prop.equals(LOG_DISK_SPACE_LIMIT_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_LIMIT_IN_MEGABYTES_OF_HOW_MUCH_DISK_SPACE_CAN_BE_CONSUMED_BY_OLD_INACTIVE_LOG_FILES.toLocalizedString();
+    } else if (prop.equals(LOG_FILE_SIZE_LIMIT_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_LIMIT_IN_MEGABYTES_OF_HOW_LARGE_THE_CURRENT_STATISTIC_ARCHIVE_FILE_CAN_GROW_BEFORE_IT_IS_CLOSED_AND_ARCHIVAL_ROLLS_ON_TO_A_NEW_FILE
+        .toLocalizedString();
+    } else if (prop.equals(MCAST_PORT)) {
+      return 
LocalizedStrings.AgentConfigImpl_MULTICAST_PORT_USED_TO_CONNECT_TO_DISTRIBUTED_SYSTEM.toLocalizedString();
+    } else if (prop.equals(MCAST_ADDRESS)) {
+      return 
LocalizedStrings.AgentConfigImpl_MULTICAST_ADDRESS_USED_TO_CONNECT_TO_DISTRIBUTED_SYSTEM.toLocalizedString();
+    } else if (prop.equals(BIND_ADDRESS)) {
+      return 
LocalizedStrings.AgentConfigImpl_IP_ADDRESS_OF_THE_AGENTS_DISTRIBUTED_SYSTEM.toLocalizedString();
+    } else if (prop.equals(TCP_PORT)) {
+      return LocalizedStrings.AgentConfigImpl_TCP_PORT.toLocalizedString();
+    } else if (prop.equals(LOCATORS)) {
+      return 
LocalizedStrings.AgentConfigImpl_ADDRESSES_OF_THE_LOCATORS_OF_THE_DISTRIBUTED_SYSTEM.toLocalizedString();
+    } else if (prop.equals(MEMBERSHIP_PORT_RANGE_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_ALLOWED_RANGE_OF_UDP_PORTS_TO_FORM_UNIQUE_MEMBERSHIP_ID.toLocalizedString();
+      //     } else if (prop.equals(SYSTEM_ID_NAME)) {
+      //       return "The id of the distributed system";
+    } else if (prop.equals(ENTITY_CONFIG_XML_FILE_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_XML_CONFIGURATION_FILE_FOR_MANAGED_ENTITIES.toLocalizedString();
+    } else if (prop.equals(REFRESH_INTERVAL_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_REFRESH_INTERVAL_IN_SECONDS_FOR_AUTOREFRESH_OF_MEMBERS_AND_STATISTIC_RESOURCES.toLocalizedString();
+    } else if (prop.equals(REMOTE_COMMAND_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_COMMAND_PREFIX_USED_FOR_LAUNCHING_MEMBERS_OF_THE_DISTRIBUTED_SYSTEM.toLocalizedString();
+    } else if (prop.equals(CLUSTER_SSL_ENABLED)) {
+      return 
LocalizedStrings.AgentConfigImpl_DOES_THE_DISTRIBUTED_SYSTEM_COMMUNICATE_USING_SSL.toLocalizedString();
+    } else if (prop.equals(CLUSTER_SSL_PROTOCOLS)) {
+      return 
LocalizedStrings.AgentConfigImpl_SSL_PROTOCOLS_USED_TO_COMMUNICATE_WITH_DISTRIBUTED_SYSTEM.toLocalizedString();
+    } else if (prop.equals(CLUSTER_SSL_CIPHERS)) {
+      return 
LocalizedStrings.AgentConfigImpl_SSL_CIPHERS_USED_TO_COMMUNICATE_WITH_DISTRIBUTED_SYSTEM.toLocalizedString();
+    } else if (prop.equals(CLUSTER_SSL_REQUIRE_AUTHENTICATION)) {
+      return 
LocalizedStrings.AgentConfigImpl_DOES_CONNECTING_TO_THE_DISTRIBUTED_SYSTEM_REQUIRE_SSL_AUTHENTICATION.toLocalizedString();
+    } else {
+      String description = _getPropertyDescription(prop);
+      if (description == null) {
+        throw new 
IllegalArgumentException(LocalizedStrings.AgentConfigImpl_UNKNOWN_CONFIG_PROPERTY_0.toLocalizedString(prop));
+
+      } else {
+        return description;
+      }
+    }
+  }
+
+  /**
+   * Returns a description of the given agent config property or
+   * <code>null</code> if <code>prop</code> is not a recognized agent
+   * property.
+   */
+  public static String _getPropertyDescription(String prop) {
+    if (prop.equals(AUTO_CONNECT_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_WILL_THE_AGENT_AUTOMATICALLY_CONNECT_TO_THE_DISTRIBUTED_SYSTEM.toLocalizedString();
+
+      //     } else if (prop.equals(SYSTEM_NAME_NAME)) {
+      //       return "The logical name of the distributed system";
+
+    } else if (prop.equals(HTTP_ENABLED_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_WILL_THE_AGENT_START_THE_HTTP_JMX_ADAPTER.toLocalizedString();
+
+    } else if (prop.equals(HTTP_BIND_ADDRESS_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_BIND_ADDRESS_OF_HTTP_ADAPTERS_SOCKETS.toLocalizedString();
+
+    } else if (prop.equals(HTTP_PORT_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_THE_PORT_ON_WHICH_THE_HTTP_ADAPTER_WILL_BE_STARTED.toLocalizedString();
+
+    } else if (prop.equals(RMI_ENABLED_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_WILL_THE_AGENT_START_THE_RMI_JMX_ADAPTER.toLocalizedString();
+
+    } else if (prop.equals(RMI_REGISTRY_ENABLED_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_WILL_THE_AGENT_HOST_AN_RMI_REGISTRY.toLocalizedString();
+
+    } else if (prop.equals(RMI_BIND_ADDRESS_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_BIND_ADDRESS_OF_RMI_ADAPTERS_SOCKETS.toLocalizedString();
+
+    } else if (prop.equals(RMI_PORT_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_THE_PORT_ON_WHICH_TO_CONTACT_THE_RMI_REGISTER.toLocalizedString();
+
+    } else if (prop.equals(RMI_SERVER_PORT_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_THE_PORT_USED_TO_CONFIGURE_RMI_CONNECTOR_SERVER.toLocalizedString();
+
+    } else if (prop.equals(SNMP_ENABLED_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_WILL_THE_AGENT_START_THE_SNMP_JMX_ADAPTER.toLocalizedString();
+
+    } else if (prop.equals(SNMP_BIND_ADDRESS_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_BIND_ADDRESS_OF_SNMP_ADAPTERS_SOCKETS.toLocalizedString();
+
+    } else if (prop.equals(SNMP_DIRECTORY_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_THE_DIRECTORY_IN_WHICH_SNMP_CONFIGURATION_RESIDES.toLocalizedString();
+
+    } else if (prop.equals(AGENT_SSL_ENABLED_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_WILL_THE_AGENT_COMMUNICATE_USING_SSL.toLocalizedString();
+
+    } else if (prop.equals(AGENT_SSL_PROTOCOLS_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_THE_SSL_PROTOCOLS_USED_BY_THE_AGENT.toLocalizedString();
+
+    } else if (prop.equals(AGENT_SSL_CIPHERS_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_THE_SSL_CIPHERS_USED_BY_THE_AGENT.toLocalizedString();
+
+    } else if (prop.equals(AGENT_SSL_REQUIRE_AUTHENTICATION_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_WILL_THE_AGENT_REQUIRE_SSL_AUTHENTICATION.toLocalizedString();
+
+    } else if (prop.equals(HTTP_SSL_REQUIRE_AUTHENTICATION_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_WILL_THE_HTTP_ADAPTER_REQUIRE_SSL_AUTHENTICATION.toLocalizedString();
+
+    } else if (prop.equals(HTTP_AUTHENTICATION_ENABLED_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_WILL_THE_HTTP_JMX_ADAPTER_USE_HTTP_AUTHENTICATION.toLocalizedString();
+
+    } else if (prop.equals(HTTP_AUTHENTICATION_USER_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_THE_USER_NAME_FOR_AUTHENTICATION_IN_THE_HTTP_JMX_ADAPTER.toLocalizedString();
+
+    } else if (prop.equals(HTTP_AUTHENTICATION_PASSWORD_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_THE_PASSWORD_FOR_AUTHENTICATION_IN_THE_HTTP_JMX_ADAPTER.toLocalizedString();
+
+    } else if (prop.equals(PROPERTY_FILE_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_PROPERTY_FILE_FROM_WHICH_AGENT_READS_CONFIGURATION.toLocalizedString();
+
+    } else if (prop.equals(LOCATOR_HOST_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_HOST_ON_WHICH_THE_DISTRIBUTED_SYSTEMS_LOCATOR_RUNS.toLocalizedString();
+
+    } else if (prop.equals(LOCATOR_PORT_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_HOST_ON_WHICH_THE_DISTRIBUTED_SYSTEMS_LOCATOR_RUNS.toLocalizedString();
+
+    } else if (prop.equals(LOCATOR_PRODUCT_DIRECTORY_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_GEMFIRE_PRODUCT_DIRECTORY_USED_TO_LAUNCH_A_LOCATOR.toLocalizedString();
+
+    } else if (prop.equals(LOCATOR_WORKING_DIRECTORY_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_DIRECTORY_IN_WHICH_A_LOCATOR_WILL_BE_LAUNCHED.toLocalizedString();
+
+    } else if (prop.equals(LOCATOR_REMOTE_COMMAND)) {
+      return 
LocalizedStrings.AgentConfigImpl_COMMAND_PREFIX_USED_WHEN_LAUNCHING_A_LOCATOR.toLocalizedString();
+
+    } else if (prop.equals(LOCATOR_BIND_ADDRESS)) {
+      return 
LocalizedStrings.AgentConfigImpl_IP_ADDRESS_TO_USE_WHEN_CONTACTING_LOCATOR.toLocalizedString();
+
+    } else if (prop.equals(LOCATOR_DS_PROPERTIES)) {
+      return 
LocalizedStrings.AgentConfigImpl_PROPERTIES_FOR_CONFIGURING_A_LOCATORS_DISTRIBUTED_SYSTEM.toLocalizedString();
+
+    } else if (prop.equals(EMAIL_NOTIFICATIONS_ENABLED_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_IDENTIFY_IF_EMAIL_NOTIFICATIONS_ARE_ENABLED_OR_NOT.toLocalizedString();
+
+    } else if (prop.equals(EMAIL_NOTIFICATIONS_FROM_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_IDENTIFY_THE_EMAIL_ADDRESS_USING_WHICH_EMAIL_NOTIFICATIONS_ARE_SENT.toLocalizedString();
+
+    } else if (prop.equals(EMAIL_NOTIFICATIONS_HOST_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_IDENTIFY_THE_EMAIL_SERVER_HOST_USING_WHICH_EMAIL_NOTIFICATIONS_ARE_SENT.toLocalizedString();
+
+    } else if (prop.equals(EMAIL_NOTIFICATIONS_TO_LIST_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_IDENTIFY_THE_COMMA_SEPARATED_EMAIL_ADDRESSES_LIST_TO_WHICH_EMAIL_NOTIFICATIONS_ARE_SENT.toLocalizedString();
+
+    } else if (prop.equals(STATE_SAVE_FILE_NAME)) {
+      return 
LocalizedStrings.AgentConfigImpl_IDENTIFY_THE_NAME_OF_THE_FILE_TO_BE_USED_FOR_SAVING_AGENT_STATE.toLocalizedString();
+
+    } else {
+      return null;
+    }
+  }
+
+  /**
+   * Parses the array of command-line arguments (format: key=value) into an
+   * instance of Properties.
+   * @param args the command-line arguments to convert into a Properties
+   */
+  private static Properties toProperties(String[] args) {
+    Properties props = new Properties();
+    // loop all args and pick out key=value pairs...
+    for (int i = 0; i < args.length; i++) {
+      // VM args...
+      if (args[i].startsWith("-J")) {
+        int eq = args[i].indexOf("=");
+        String key = args[i].substring(2, eq);
+        String value = args[i].substring(eq + 1);
+        System.setProperty(key, value);
+      } else if (args[i].indexOf(AGENT_DEBUG) > 0) {
+        int eq = args[i].indexOf("=");
+        String key = args[i].substring(2, eq);
+        String value = args[i].substring(eq + 1);
+        System.setProperty(key, value);
+      }
+
+      // all other args
+      else if (args[i].indexOf("=") > 0) {
+        int eq = args[i].indexOf("=");
+        String key = args[i].substring(0, eq);
+        String value = args[i].substring(eq + 1);
+        props.setProperty(key, value);
+      }
+    }
+
+    return props;
+  }
+
+  /**
+   * Returns the original command-line arguments.
+   */
+  public String[] getOriginalArgs() {
+    return this.originalCmdLineArgs;
+  }
+
+  // -------------------------------------------------------------------------
+  //   Validation methods for configuration options
+  // -------------------------------------------------------------------------
+
+  /**
+   * Makes sure that the mcast port and locators are correct and
+   * consistent.
+   * @throws IllegalArgumentException If configuration is not valid
+   */
+  @Override
+  public void validate() {
+    super.validate();
+
+    if (this.httpPort < 0 || this.httpPort > MAX_HTTP_PORT) {
+      throw new 
IllegalArgumentException(LocalizedStrings.AgentConfigImpl_0_MUST_BE_ZERO_OR_AN_INTEGER_BETWEEN_1_AND_2.toLocalizedString(new
 Object[] {
+        HTTP_PORT_NAME, Integer.valueOf(MIN_HTTP_PORT), 
Integer.valueOf(MAX_HTTP_PORT)
+      }));
+    }
+
+    if (this.rmiPort < 0 || this.rmiPort > MAX_RMI_PORT) {
+      throw new 
IllegalArgumentException(LocalizedStrings.AgentConfigImpl_0_MUST_BE_ZERO_OR_AN_INTEGER_BETWEEN_1_AND_2.toLocalizedString(new
 Object[] {
+        RMI_PORT_NAME, Integer.valueOf(MIN_RMI_PORT), 
Integer.valueOf(MAX_RMI_PORT)
+      }));
+    }
+
+    if (this.rmiServerPort < 0 || this.rmiServerPort > MAX_RMI_PORT) {
+      throw new 
IllegalArgumentException(LocalizedStrings.AgentConfigImpl_0_MUST_BE_ZERO_OR_AN_INTEGER_BETWEEN_1_AND_2.toLocalizedString(new
 Object[] {
+        RMI_SERVER_PORT_NAME, Integer.valueOf(MIN_RMI_PORT), 
Integer.valueOf(MAX_RMI_PORT)
+      }));
+    }
+
+  }
+
+  /**
+   * Returns defaultValue if value is empty.
+   */
+  private String validateNonEmptyString(String value, String defaultValue) {
+    return isEmpty(value) ? defaultValue : value;
+  }
+
+  /**
+   * Validates that systemHost can be used for an InetAddress.
+   */
+  private String validateSystemHost(String systemHost) {
+    return InetAddressUtil.validateHost(systemHost);
+  }
+
+  /**
+   * Returns null if productDir is empty; else converts it to File.
+   */
+  private String validateProductDirectory(String productDir) {
+    if (isEmpty(productDir)) {
+      return null;
+    }
+    return productDir;
+  }
+
+  /**
+   * Returns true if value parses as true; null value returns defaultValue.
+   */
+  private boolean validateBoolean(String value, boolean defaultValue) {
+    if (isEmpty(value)) {
+      return defaultValue;
+    }
+    return Boolean.valueOf(value).booleanValue();
+  }
+
+  // HttpAdaptor property validators...
+
+  /**
+   * Returns {@link
+   * AgentConfig#DEFAULT_HTTP_PORT}
+   * if httpPort is empty; else validates
+   * that it's an integer and returns the int form.
+   */
+  private int validateHttpPort(String val) {
+    if (isEmpty(val)) {
+      return DEFAULT_HTTP_PORT;
+    } else {
+      return validateHttpPort(Integer.parseInt(val));
+    }
+  }
+
+  /**
+   * Validates that httpPort is either zero or within the {@link
+   * AgentConfig#MIN_HTTP_PORT} and {@link
+   * AgentConfig#MAX_HTTP_PORT} values.
+   */
+  private int validateHttpPort(int val) {
+    if (val < 0 || val > MAX_HTTP_PORT) {
+      throw new 
IllegalArgumentException(LocalizedStrings.AgentConfigImpl_0_MUST_BE_ZERO_OR_AN_INTEGER_BETWEEN_1_AND_2.toLocalizedString(new
 Object[] {
+        HTTP_PORT_NAME, Integer.valueOf(MIN_HTTP_PORT), 
Integer.valueOf(MAX_HTTP_PORT)
+      }));
+    }
+    return val;
+  }
+
+  /**
+   * Returns {@link
+   * AgentConfig#DEFAULT_HTTP_BIND_ADDRESS}
+   * unless httpBindAddress can be used to
+   * create a valid InetAddress.
+   */
+  private String validateHttpBindAddress(String val) {
+    String value = InetAddressUtil.validateHost(val);
+    if (value == null) {
+      return DEFAULT_HTTP_BIND_ADDRESS;
+    } else {
+      return value;
+    }
+  }
+
+  /**
+   * Validates that httpBindAddress is not null and then returns the string 
form of it.
+   */
+  private String validateHttpBindAddress(InetAddress val) {
+    if (val == null) {
+      throw new 
IllegalArgumentException(LocalizedStrings.AgentConfigImpl_HTTPBINDADDRESS_MUST_NOT_BE_NULL.toLocalizedString());
+    }
+    return toString("", val);
+  }
+
+  // SnmpAdaptor property validators...
+
+  /**
+   * Returns {@link
+   * AgentConfig#DEFAULT_SNMP_BIND_ADDRESS}
+   * unless snmpBindAddress can be used to
+   * create a valid InetAddress.
+   */
+  private String validateSnmpBindAddress(String val) {
+    String value = InetAddressUtil.validateHost(val);
+    if (value == null) {
+      return DEFAULT_SNMP_BIND_ADDRESS;
+    } else {
+      return value;
+    }
+  }
+
+  //  /**
+  //   * Validates that snmpBindAddress is not null and then returns the 
string form of it.
+  //   */
+  //  private String validateSnmpBindAddress(InetAddress snmpBindAddress) {
+  //    if (snmpBindAddress == null) {
+  //      throw new IllegalArgumentException("SnmpBindAddress must not be 
null");
+  //    }
+  //    return toString(snmpBindAddress);
+  //  }
+
+  /**
+   * SnmpDirectory must be specified if SNMP is enabled.  This directory must
+   * also exist.
+   */
+  private String validateSnmpDirectory(String snmpDir) {
+    /*if (isSnmpEnabled() && isEmpty(snmpDir)) {
+      throw new 
IllegalArgumentException(LocalizedStrings.AgentConfigImpl_SNMPDIRECTORY_MUST_BE_SPECIFIED_BECAUSE_SNMP_IS_ENABLED.toLocalizedString());
+    }
+    File root new File(snmpDir);
+    if (!root.exists())
+      throw new 
IllegalArgumentException(LocalizedStrings.AgentConfigImpl_SNMPDIRECTORY_DOES_NOT_EXIST.toLocalizedString());
+    */
+
+    return snmpDir;
+  }
+
+  // RMIConnectorServer property validators...
+
+  /**
+   * Returns {@link AgentConfig#DEFAULT_RMI_PORT}
+   * if rmiPort is empty; else validates
+   * that it's an integer and returns the int form.
+   */
+  private int validateRmiPort(String val) {
+    if (isEmpty(val)) {
+      return DEFAULT_RMI_PORT;
+    } else {
+      return validateRmiPort(Integer.parseInt(val));
+    }
+  }
+
+  /**
+   * Validates that rmiPort is either zero or within the {@link
+   * AgentConfig#MIN_RMI_PORT}
+   * and {@link AgentConfig#MAX_RMI_PORT}
+   * values.
+   */
+  private int validateRmiPort(int val) {
+    if (val < MIN_RMI_PORT || val > MAX_RMI_PORT) {
+      throw new 
IllegalArgumentException(LocalizedStrings.AgentConfigImpl_0_MUST_BE_ZERO_OR_AN_INTEGER_BETWEEN_1_AND_2.toLocalizedString(new
 Object[] {
+        RMI_PORT_NAME, Integer.valueOf(MIN_RMI_PORT), 
Integer.valueOf(MAX_RMI_PORT)
+      }));
+    }
+    return val;
+  }
+
+  /**
+   * Returns {@link AgentConfig#DEFAULT_RMI_SERVER_PORT}
+   * if rmi-server-port is empty; else validates that it's an integer within 
the
+   * allowed range and returns the int form.
+   */
+  private int validateRmiServerPort(String val) {
+    if (isEmpty(val)) {
+      return DEFAULT_RMI_SERVER_PORT;
+    } else {
+      return validateRmiServerPort(Integer.parseInt(val));
+    }
+  }
+
+  /**
+   * Validates that rmiPort is either zero or within the {@link
+   * AgentConfig#MIN_RMI_PORT}
+   * and {@link AgentConfig#MAX_RMI_PORT}
+   * values.
+   */
+  private int validateRmiServerPort(int val) {
+    if (val < MIN_RMI_PORT || val > MAX_RMI_PORT) {
+      throw new 
IllegalArgumentException(LocalizedStrings.AgentConfigImpl_0_MUST_BE_ZERO_OR_AN_INTEGER_BETWEEN_1_AND_2.toLocalizedString(new
 Object[] {
+        RMI_SERVER_PORT_NAME, Integer.valueOf(MIN_RMI_PORT), 
Integer.valueOf(MAX_RMI_PORT)
+      }));
+    }
+    return val;
+  }
+
+  /**
+   * Returns {@link
+   * AgentConfig#DEFAULT_RMI_BIND_ADDRESS}
+   * unless rmiBindAddress can be used to create a
+   * valid InetAddress.
+   */
+  private String validateRmiBindAddress(String val) {
+    String value = InetAddressUtil.validateHost(val);
+    if (value == null) {
+      return DEFAULT_RMI_BIND_ADDRESS;
+    } else {
+      return value;
+    }
+  }
+  //  /**
+  //   * Validates that rmiBindAddress is not null and then returns the string 
form of it.
+  //   */
+  //  private String validateRmiBindAddress(InetAddress rmiBindAddress) {
+  //    if (rmiBindAddress == null) {
+  //      throw new IllegalArgumentException("RmiBindAddress must not be 
null");
+  //    }
+  //    return toString(rmiBindAddress);
+  //  }
+
+  /**
+   * Validates working directory is not null or empty.
+   */
+  private File validateWorkingDirectory(String workingDir) {
+    if (isEmpty(workingDir)) {
+      throw new 
IllegalArgumentException(LocalizedStrings.AgentConfigImpl_LOCATOR_WORKINGDIRECTORY_MUST_NOT_BE_NULL.toLocalizedString());
+    }
+    return new File(workingDir);
+  }
+
+  // -------------------------------------------------------------------------
+  //   Static utility methods
+  // -------------------------------------------------------------------------
+
+  /**
+   * Gets an <code>URL</code> for the property file, if one can be found,
+   * that the create method would use to determine the systemName and
+   * product home.
+   * <p>
+   * The file will be searched for, in order, in the following locations:
+   * <ol>
+   * <li> the current directory
+   * <li> the home directory
+   * <li> the class path
+   * </ol>
+   * Only the first file found will be used.
+   * @return a <code>URL</code> that names the property file;
+   * otherwise Null if no property file was found.
+   */
+  public static URL getPropertyFileURL(final String propFileLocation) {
+    File propFile = new File(propFileLocation);
+
+    // first, try the current directory...
+    if (propFile.exists()) {
+      propFile = IOUtils.tryGetCanonicalFileElseGetAbsoluteFile(propFile);
+
+      try {
+        return propFile.toURI().toURL();
+      } catch (java.net.MalformedURLException ignore) {
+      }
+    }
+
+    // next, try the user's home directory...
+    if (propFileLocation != null && propFileLocation.length() > 0) {
+      propFile = new File(System.getProperty("user.home"), propFileLocation);
+
+      if (propFile.exists()) {
+        propFile = IOUtils.tryGetCanonicalFileElseGetAbsoluteFile(propFile);
+
+        try {
+          return propFile.toURI().toURL();
+        } catch (java.net.MalformedURLException ignore) {
+        }
+      }
+    }
+
+    // finally, try the classpath...
+    return ClassPathLoader.getLatest().getResource(AgentConfigImpl.class, 
propFileLocation);
+  }
+
+  private static boolean okToDisplayPropertyValue(String attName) {
+    if (attName.startsWith(HTTP_AUTHENTICATION_USER_NAME)) {
+      return false;
+    }
+    if (attName.startsWith(HTTP_AUTHENTICATION_PASSWORD_NAME)) {
+      return false;
+    }
+    if (attName.startsWith(AGENT_SSL_PROTOCOLS_NAME)) {
+      return false;
+    }
+    if (attName.startsWith(AGENT_SSL_CIPHERS_NAME)) {
+      return false;
+    }
+    if (attName.toLowerCase().contains("javax.net.ssl")) {
+      return false;
+    }
+    if (attName.toLowerCase().contains("password")) {
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * Returns string representation of the specified object with special
+   * handling for InetAddress.
+   * @param obj the object to convert to string
+   *
+   * @return string representation of the specified object
+   */
+  private static String toString(String attName, java.lang.Object obj) {
+    if (okToDisplayPropertyValue(attName)) {
+      if (obj == null) {
+        return "";
+      }
+      if (obj instanceof InetAddress) {
+        return InetAddressUtil.toString(obj);
+      }
+      return obj.toString();
+    } else {
+      return OBFUSCATED_STRING;
+    }
+  }
+
+  /**
+   * Returns string representation of the int.
+   */
+  private static String toString(String attName, int num) {
+    if (okToDisplayPropertyValue(attName)) {
+      return String.valueOf(num);
+    } else {
+      return OBFUSCATED_STRING;
+    }
+  }
+
+  /**
+   * Returns string representation of the boolean value.
+   */
+  private static String toString(String attName, boolean v) {
+    if (okToDisplayPropertyValue(attName)) {
+      return String.valueOf(v);
+    } else {
+      return OBFUSCATED_STRING;
+    }
+  }
+
+  /**
+   * Returns true if the string is null or empty.
+   */
+  public static boolean isEmpty(String string) {
+    return string == null || string.length() == 0;
+  }
+
+  // -------------------------------------------------------------------------
+  //   SSL support...
+  // -------------------------------------------------------------------------
+  private boolean sslEnabled = DEFAULT_SSL_ENABLED;
+  private String sslProtocols = DEFAULT_SSL_PROTOCOLS;
+  private String sslCiphers = DEFAULT_SSL_CIPHERS;
+  private boolean sslAuthenticationRequired = 
DEFAULT_SSL_REQUIRE_AUTHENTICATION;
+  private Properties sslProperties = new Properties();
+
+  @Override
+  public boolean isSSLEnabled() {
+    return this.sslEnabled;
+  }
+
+  @Override
+  public void setSSLEnabled(boolean enabled) {
+    this.sslEnabled = enabled;
+    configChanged();
+  }
+
+  @Override
+  public String getSSLProtocols() {
+    return this.sslProtocols;
+  }
+
+  @Override
+  public void setSSLProtocols(String protocols) {
+    this.sslProtocols = protocols;
+    configChanged();
+  }
+
+  @Override
+  public String getSSLCiphers() {
+    return this.sslCiphers;
+  }
+
+  @Override
+  public void setSSLCiphers(String ciphers) {
+    this.sslCiphers = ciphers;
+    configChanged();
+  }
+
+  @Override
+  public boolean isSSLAuthenticationRequired() {
+    return this.sslAuthenticationRequired;
+  }
+
+  @Override
+  public void setSSLAuthenticationRequired(boolean authRequired) {
+    this.sslAuthenticationRequired = authRequired;
+    configChanged();
+  }
+
+  @Override
+  public Properties getSSLProperties() {
+    return this.sslProperties;
+  }
+
+  @Override
+  public void setSSLProperties(Properties sslProperties) {
+    this.sslProperties = sslProperties;
+    if (this.sslProperties == null) {
+      this.sslProperties = new Properties();
+    }
+    configChanged();
+  }
+
+  public String getStateSaveFile() {
+    return this.stateSaveFile;
+  }
+
+  public void setStateSaveFile(String file) {
+    checkReadOnly();
+    this.stateSaveFile = file;
+    configChanged();
+  }
+
+  public boolean isEmailNotificationEnabled() {
+    return this.isEmailNotificationEnabled;
+  }
+
+  public void setEmailNotificationEnabled(boolean enabled) {
+    checkReadOnly();
+    this.isEmailNotificationEnabled = enabled;
+    configChanged();
+  }
+
+  public String getEmailNotificationFrom() {
+    return this.emailNotificationFrom;
+  }
+
+  public void setEmailNotificationFrom(String emailID) {
+    this.emailNotificationFrom = emailID;
+    configChanged();
+  }
+
+  public String getEmailNotificationHost() {
+    return this.emailNotificationHostName;
+  }
+
+  public void setEmailNotificationHost(String hostName) {
+    this.emailNotificationHostName = hostName;
+    configChanged();
+  }
+
+  public String getEmailNotificationToList() {
+    return this.emailNotificationToList;
+  }
+
+  public void setEmailNotificationToList(String emailIDs) {
+    this.emailNotificationToList = emailIDs;
+    configChanged();
+  }
+
+  @Override
+  public Object clone() throws CloneNotSupportedException {
+    return super.clone();
+  }
+}
+

Reply via email to