gt: 					throw new CandybeanException(message);
context: package com.sugarcrm.candybean.automation;
  
  import java.io.File;
  import java.io.IOException;
  import java.util.logging.FileHandler;
  import java.util.logging.Logger;
  
  import org.apache.commons.lang3.StringUtils;
  import org.openqa.selenium.remote.DesiredCapabilities;
  
  import com.sugarcrm.candybean.automation.AutomationInterface.Type;
  import com.sugarcrm.candybean.automation.webdriver.AndroidInterface;
  import com.sugarcrm.candybean.automation.webdriver.ChromeInterface;
  import com.sugarcrm.candybean.automation.webdriver.FirefoxInterface;
  import com.sugarcrm.candybean.automation.webdriver.InternetExplorerInterface;
  import com.sugarcrm.candybean.automation.webdriver.IosInterface;
  import com.sugarcrm.candybean.automation.webdriver.SaucelabsInterface;
  import com.sugarcrm.candybean.automation.webdriver.WebDriverInterface;
  import com.sugarcrm.candybean.configuration.Configuration;
  import com.sugarcrm.candybean.exceptions.CandybeanException;
  import com.sugarcrm.candybean.utilities.CandybeanLogger;
  
  public class AutomationInterfaceBuilder {
  
  	/*
  	 * The type of interface that the user wants to build.
  	 */
  	private Type type = null;
  	
  	/*
  	 * The path to the APP. Required for Android and IOS interface.
  	 */
  	private String appPath = null;
  	
  	/*
  	 * The APP package, required for Android interface.
  	 */
  	private String appPackage = null;
  
  	/*
  	 * The APP activity, required for Android interface.
  	 */
  	private String appActivity = null;
  	
  	/*
  	 * Logger for this class
  	 */
  	private Logger logger = Logger.getLogger(this.getClass().getName());
  	
  	/*
  	 * The class that calls this builder, required for logging and mobile interfaces.
  	 */
  	private Class<?> cls;
  	
  	/*
  	 * Candybean instance
  	 */
  	private Candybean candybean = null;
  	
  	/**
  	 * @param cls Typically the test class which uses this interface builder
  	 */
  	public AutomationInterfaceBuilder(Class<?> cls) {
  		this.cls = cls;
  	}
  
  	/**
  	 * Builds the interface specified. If an interface cannot be built using the specified parameters, an attempt
  	 * will be made using candybean configuration files. If an interface cannot be built, an exception will be thrown.
  	 * <br><br>
  	 * Below are the minimum settings required to build a specific type of interface.
  	 * <br><br>
  	 * <table border="1">
  	 * 		<thead>
  	 * 			<th>Interface</th>
  	 * 			<th>Configuration Required</th>
  	 * 		</thead>
  	 *		<tbody>
  	 *			<tr>
  	 *				<td>Chrome, Firefox, Safari, IE</td>
  	 *				<td>
  	 *					To build a browser interface, the {@link Type} must be specified. If the type is not specified, the builder will attempt to build
  	 *					the interface from the <b>automation.interface</b> setting from the candybean configuration file. If the interface can still not be built,
  	 *					candybean will use a <b>chrome</b> interface by default.
  	 *				</td>
  	 *			</tr>
  	 *			<tr>
  	 *				<td>Android</td>
  	 *				<td>
  	 *					To build an Android interface, the {@link Type} <b>must</b> be set to {@link Type.Android}. If a type is not specified, the builder will
  	 *					throw an exception. Furthermore, for an android test, the following settings must be specified:
  	 *					<ul>
  	 *						<li>appPath</li>
  	 *						<li>appPackage</li>
  	 *						<li>appActivity</li>
  	 *					</ul>
  	 *					If these settings are not specified in the builder, candybean will attempt to retrieve them from the configuration file. If the name of the
  	 *					test class is 'AndroidTest', then candybean will look for the key 'AndroidTest.app-path' in the configuration file, and etc.<br><br>
  	 *					If an Android interface cannot be build from the builder settings or the configuration settings, an exception will be thrown.
  	 *				</td>
  	 *			</tr>
  	 *			<tr>
  	 *				<td>Apple IOS</td>
  	 *				<td>
  	 *					To build an IOS interface, the {@link Type} <b>must</b> be set to {@link Type.IOS}. If a type is not specified, the builder will
  	 *					throw an exception. Furthermore, for an IOS test, the following setting must be specified:
  	 *					<ul>
  	 *						<li>appPath</li>
  	 *					</ul>
  	 *					If the name of the test class is 'IOSTest', then candybean will look for the key 'IOSTest.app-path' in the configuration file.<br><br>
  	 *					If an IOS interface cannot be built from the builder settings or the configuration settings, an exception will be thrown.
  	 *				</td>
  	 *			</tr>
  	 *		</tbody> 	
  	 * </table>
  	 * @return
  	 */
  	public WebDriverInterface build() throws CandybeanException{
  		WebDriverInterface iface = null;
  		candybean = Candybean.getInstance();
  		CandybeanLogger cbLogger;
  		try {
  			cbLogger = (CandybeanLogger) Logger.getLogger(Candybean.class.getSimpleName());
  			if (!cbLogger.containsHandler(cls.getSimpleName())) {
  				FileHandler fh = new FileHandler("./log/" + cls.getSimpleName() + ".log");
  				cbLogger.addHandler(fh, cls.getSimpleName());
  			}
  		} catch (IOException e) {
  			logger.severe("Unable to read/write to file " + "./log/" + cls.getSimpleName() + ".log");
  		}
  		if(type == null) {
  			logger.info("Interface type not specified in the builder, attempting to build an interface using 'automation.interfrace' in the configuration.");
  			iface = getWebDriverInterface();
  		}else {
  			iface = getWebDriverInterface(type);
  		}
  		return iface;
  	}
  	
  	/**
  	 * Instantiates an interface given the type
  	 * 
  	 * @return WebDriverInterface
  	 * @throws Exception
  	 */
  	private WebDriverInterface getWebDriverInterface() throws CandybeanException {
  		logger.info("No webdriverinterface type specified from source code; will attempt to retrieve type from candybean configuration.");
  		Type configType = AutomationInterface.parseType(candybean.config.getValue("automation.interface", "chrome"));
  		logger.info("Found the following webdriverinterface type: " + configType + ", from configuration: " + candybean.config.configFile.getAbsolutePath());
  		return this.getWebDriverInterface(configType);
  	}
  
  	
  	private WebDriverInterface getWebDriverInterface(Type type) throws CandybeanException {
  		WebDriverInterface iface = null;
  		DesiredCapabilities capabilities;
  		String testClassName = cls.getSimpleName();
  		// Required if we are using saucelabs.
  		SaucelabsInterface sauceInterface = new SaucelabsInterface(type);
  		switch (type) {
  		case FIREFOX:
  			iface = new FirefoxInterface();
  			break;
  		case CHROME:
  			iface = new ChromeInterface();
  			break;
  		case IE:
  			iface = new InternetExplorerInterface();
  			break;
  		case SAFARI:
  			throw new CandybeanException("Selenium: SAFARI interface type not yet supported");
  		case ANDROID:
  			if(isAndroidFullyConfigured(true)) {
  				capabilities = new DesiredCapabilities();
  				capabilities.setCapability("app", appPath);
  				capabilities.setCapability("app-package", appPackage);
  				capabilities.setCapability("app-activity", appActivity);
  				sauceInterface.getCapabilities().setCapability("app", appPath);
  				sauceInterface.getCapabilities().setCapability("app-package", appPackage);
  				sauceInterface.getCapabilities().setCapability("app-activity", appActivity);
  				iface = new AndroidInterface(capabilities);
  			}else {
  				logger.info("Builder was not fully configured to create an Android interface. \n" +
  						"The variables appPath, appPackage, appActivity must all be set to create an android interface. \n" +
  						"Trying to create Android interface from configuration file.");
  				if(isAndroidFullyConfigured(false)){
  					capabilities = new DesiredCapabilities();
  					capabilities.setCapability("app", new File(candybean.config.getValue(testClassName + ".app")).getAbsolutePath());
  					capabilities.setCapability("app-package", candybean.config.getValue(testClassName + ".app-package"));
  					capabilities.setCapability("app-activity", candybean.config.getValue(testClassName + ".app-activity"));
  					sauceInterface.getCapabilities().setCapability("app", new File(candybean.config.getValue(testClassName + ".app")).getAbsolutePath());
  					sauceInterface.getCapabilities().setCapability("app-package", candybean.config.getValue(testClassName + ".app-package"));
  					sauceInterface.getCapabilities().setCapability("app-activity", candybean.config.getValue(testClassName + ".app-activity"));
  					iface = new AndroidInterface(capabilities);
  				}else {
  					String message = "Builder was unable to create an Android Interface from the provided settings in the builder, or \n" +
  							"from the configuration file. If creating an android interface using the builder, the variables appPath, appPackage, \n " +
  							"appActivity must all be set. If you want the builder to create the interface from the configuration file, please ensure that \n" +
  							"the keys " + testClassName + ".app"  + ", " + testClassName + ".app-package" + ", and " + testClassName + ".app-activity" + " have \n" +
  							"all been configured.";
  					logger.severe(message);
  					throw new CandybeanException(message);
  				}
  			}
  			break;
  		case IOS:
  			if(isIOSFullyConfigured(true)) {
  				capabilities = new DesiredCapabilities();
  				capabilities.setCapability("app", appPath);
  				sauceInterface.getCapabilities().setCapability("app", appPath);
  				iface = new IosInterface(capabilities);
  			}else {
  				logger.info("Builder was not fully configured to create an IOS interface. \n" +
  						"The variable appPath must be set to create an ios interface. \n" +
  						"Trying to create IOS interface from configuration file.");
  				if(isIOSFullyConfigured(false)){
  					capabilities = new DesiredCapabilities();
  					capabilities.setCapability("app", new File(candybean.config.getValue(testClassName + ".app")).getAbsolutePath());
  					sauceInterface.getCapabilities().setCapability("app", new File(candybean.config.getValue(testClassName + ".app")).getAbsolutePath());
  					iface = new IosInterface(capabilities);
  				}else {
  					String message = "Builder was unable to create an IOS Interface from the provided settings in the builder, or \n" +
  							"from the configuration file. If creating an IOS interface using the builder, the variable appPath \n " +
  							"must be set. If you want the builder to create the interface from the configuration file, please ensure that \n" +
  							"the key " + testClassName + ".app"  + " has been configured.";
  					logger.severe(message);
  