$methods[] = $mSetContext;
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// ---- shutDownSeleniumServer
$mShutDownSeleniumServer = Method::createNew();
$mShutDownSeleniumServer->name = 'shutDownSeleniumServer';
$mShutDownSeleniumServer->type = Method::determineTypeByName($mShutDownSeleniumServer->name);
$mShutDownSeleniumServer->subtype = Method::determineSubtypeByName($mShutDownSeleniumServer->name);
$mShutDownSeleniumServer->description = <<<TEXT
    Kills the running Selenium Server and all browser sessions. After you run this command, you will no longer be able
    to send commands to the server; you can't remotely start the server once it has been stopped.
    Normally you should prefer to run the "stop" command, which terminates the current browser session,
    rather than shutting down the entire server.
TEXT;
// return value
$mShutDownSeleniumServer->returnValue = ReturnValue::createNew();
$mShutDownSeleniumServer->returnValue->type = ReturnValue::TYPE_VOID;
// add to common method list (method and its derivative methods)
$methods[] = $mShutDownSeleniumServer;
// .... other methods place here. Should be added:
// keyDownNative
// keyPressNative
// keyUpNative
// retrieveLastRemoteControlLogs
// setContext
// shutDownSeleniumServer
// index by method name
$methodsByName = [];
foreach ($methods as $method) {
    $methodsByName[$method->name] = $method;
}
 /**
  * Creates method and load data from specified XML nodes.
  *
  *
  * Typical html code that described method:
  * <pre><code>
  *    <dt>
  *        <strong>
  *            <a name="addLocationStrategy"></a>
  *            addLocationStrategy(strategyName,functionDefinition)
  *        </strong>
  *    </dt>
  *
  *    <dd>Defines a new function for Selenium to locate elements on the page.
  *        For example, if you define the strategy "foo", and someone runs click("foo=blah"), we'll run your
  *        function, passing you the string "blah", and click on the element that your function returns, or throw an
  *        "Element not found" error if your function returns null.
  *
  *        We'll pass three arguments to your function:
  *        <ul>
  *            <li>locator: the string the user passed in</li>
  *            <li>inWindow: the currently selected window</li>
  *            <li>inDocument: the currently selected document</li>
  *        </ul>
  *        The function must return null if the element can't be found.
  *
  *        <p>Arguments:</p>
  *        <ul>
  *            <li>strategyName - the name of the strategy to define; this should use only letters [a-zA-Z] with no
  *            spaces or other punctuation.
  *            </li>
  *            <li>functionDefinition - a string defining the body of a function in JavaScript. For example:
  *            < code >return inDocument.getElementById(locator);< / code >
  *            </li>
  *        </ul>
  *    </dd>
  * </code></pre>
  *
  * @param \SimpleXMLElement $dt XML node, which contain determination
  * @param \SimpleXMLElement $dd XML node, which contain description
  *
  * @return Method
  */
 private function _createMethodFromXML(\SimpleXMLElement $dt, \SimpleXMLElement $dd)
 {
     $method = Method::createNew();
     // Name
     $method->name = (string) $dt->xpath('descendant::a[@name]')[0]->attributes()['name'];
     // Description (without arguments, returnValue, and related commands)
     $text = $dd->asXML();
     if (Helper::contain('Arguments:', $text)) {
         $assertion = '<p>[\\s]*Arguments:';
     } elseif (Helper::contain('Returns:', $text)) {
         $assertion = '<p>\\s*<dl>';
     } elseif (Helper::contain('Related Assertions, automatically generated:', $text)) {
         $assertion = '<p>Related Assertions,';
     } else {
         $assertion = null;
     }
     $regExp = $assertion ? '/<dd>\\s*(?P<description>[\\s\\S]+)(?=' . $assertion . ')/' : '/<dd>\\s*(?P<description>[\\s\\S]+)\\s*<\\/dd>/';
     preg_match($regExp, $text, $matches) && array_key_exists('description', $matches) or die('Error at parse method description: ' . $text);
     $method->description = $matches['description'];
     // Arguments
     // arguments from determination
     preg_match('/([a-zA-Z]+)\\s*\\((?P<args>[a-zA-Z0-9\\,\\s]+)\\)/', $dt->asXML(), $m) && array_key_exists('args', $m) or die('Error at parse args from determination of method: ' . $dt->asXML());
     $dtArgs = [];
     if ($args = trim($m['args'])) {
         foreach (explode(',', $args) as $arg) {
             $dtArgs[] = trim($arg);
         }
     }
     // arguments from description
     $xmlArguments = $dd->xpath("p[normalize-space(text())='Arguments:']/following-sibling::ul[1]/li");
     foreach ($xmlArguments as $xmlArgument) {
         $argument = $this->_createArgumentFromXML($xmlArgument)->setMethod($method);
         $method->addArgument($argument);
     }
     $argsDiff = array_diff($dtArgs, array_keys($method->arguments));
     if (!empty($argsDiff)) {
         echo 'Warning [method = ' . $method->name . ']: not all arguments has been parsed. Problem arguments: ' . join(',', $argsDiff) . Helper::EOL;
         if (empty($method->arguments)) {
             // add as arguments with empty description
             foreach ($argsDiff as $diffArgName) {
                 $argument = Argument::createNew()->setMethod($method);
                 $argument->name = $diffArgName;
                 $argument->type = Argument::DEFAULT_TYPE;
                 $method->addArgument($argument);
             }
             echo '    ...added as args with empty description' . Helper::EOL;
         } else {
             echo '    ...cannot be added!' . Helper::EOL;
         }
     }
     // Return value
     $xmlReturnValue = $dd->xpath("descendant::dt[normalize-space(text())='Returns:']/following-sibling::dd");
     $method->returnValue = ReturnValue::createNew();
     $method->returnValue->description = empty($xmlReturnValue) ? '' : str_replace(['<dd>', '</dd>'], '', $xmlReturnValue[0]->asXML());
     // Derivative methods
     $xmlRelatedAssertions = $dd->xpath("p[normalize-space(text())='Related Assertions, automatically generated:']/following-sibling::ul[1]/li");
     foreach ($xmlRelatedAssertions as $xmlRelatedAssertion) {
         $derivativeMethod = $this->_createDerivativeMethodFromXML($xmlRelatedAssertion);
         $method->addDerivativeMethod($derivativeMethod);
     }
     return $method;
 }
$manualMethodsDescription = (require_once 'source-doc/manual_methods_description.php');
// Parsing of official documentation
$parser = new Parser(file_get_contents(SELENIUM_DOC_REFERENCE));
// Search description for available selenium commands (methods of phpunit-selenium-driver)
$driver = new phpunitSeleniumDriver();
$generator = new CodeGenerator();
$seleniumCommands = $driver->getAvailableSeleniumCommands();
$methodsByBaseName = [];
$notFounded = [];
foreach ($seleniumCommands as $methodFullName => $returnType) {
    // Create model of available method
    $method = models\Method::createNew();
    $method->name = $methodFullName;
    $method->type = models\Method::determineTypeByName($methodFullName);
    $method->subtype = models\Method::determineSubtypeByName($methodFullName);
    $method->returnValue = models\ReturnValue::createNew();
    $method->returnValue->type = $returnType;
    // Search of description in manual/parsed docs
    $documentedMethod = null;
    if (array_key_exists($methodFullName, $manualMethodsDescription)) {
        $documentedMethod = $manualMethodsDescription[$methodFullName];
    } elseif ($foundMethod = $parser->getMethodByBaseName($method->getBaseName(true))) {
        $documentedMethod = $generator->createNewMethodWithName($foundMethod, $method->name);
        // convert to target method
        $documentedMethod->returnValue->type = $returnType;
        // selenium documentation has no info about php variable type
    }
    if ($documentedMethod) {
        $methodsByBaseName[$method->getBaseName()][] = $documentedMethod;
    } else {
        $notFounded[$method->getBaseName()][] = $method->name;