/**
  * Creates new method with the specified name (converts from current method).
  * Only {@link Method::SUBTYPE_BASE} + {@link Method::SUBTYPE_STORE} supported for current method.
  *
  * @param Method $oldMethod     Source method, from which created new method
  * @param string $newMethodName Name of new method
  *
  * @return Method               New converted method
  * @throws \Exception           If current method has unsupported subtype, or incorrect name for new method
  */
 function createNewMethodWithName(Method $oldMethod, $newMethodName)
 {
     $newMethod = $oldMethod->createClone();
     $newMethod->name = $newMethodName;
     $newMethod->type = Method::determineTypeByName($newMethod->name);
     $newMethod->subtype = Method::determineSubtypeByName($newMethod->name);
     $newMethod->description = $this->_addEndDotIfNotExist($newMethod->description);
     // add end of last sentence
     // see also links
     $newMethod->seeLinks = Helper::prependAssoc($newMethod->seeLinks, [$oldMethod->getNameFQSEN() => 'Base method, from which has been generated (automatically) current method']);
     if ($oldMethod->subtype === Method::SUBTYPE_BASE) {
         // ---- Source method has Action type
         switch ($newMethod->subtype) {
             case Method::SUBTYPE_BASE:
                 // Action --> Action
                 return $newMethod;
             case Method::SUBTYPE_AND_WAIT:
                 // Action --> Action
                 $newMethod->description .= '<h4>Notes:</h4>' . '<p>After execution of this action, Selenium wait for a new page to load ' . '(see ' . CodeGenerator::linkToMethod('waitForPageToLoad') . ')</p>';
                 return $newMethod;
             default:
                 self::throwException("Incorrect subtype for creating of new method: '{$oldMethod->subtype}'. " . "Source method (Action) should be converted only to Action.");
         }
     } elseif ($oldMethod->subtype === Method::SUBTYPE_STORE) {
         // ---- Source method has Accessor type
         switch ($newMethod->subtype) {
             case Method::SUBTYPE_STORE:
                 // Accessor --> Accessor
                 $newMethod->description .= '<h4>Stored value:</h4>' . '<p>' . $newMethod->returnValue->description . ' (see ' . CodeGenerator::linkToProperty('doc_Stored_Variables', '', 'Stored Variables') . ')</p>';
                 $newMethod->returnValue->description = '';
                 // store* methods has no return value todo to check this
                 return $newMethod;
             case Method::SUBTYPE_GET:
                 // Accessor --> Accessor
                 $newMethod->deleteArgumentByName('variableName');
                 return $newMethod;
             case Method::SUBTYPE_IS:
                 // Accessor --> Accessor
                 $newMethod->deleteArgumentByName('variableName');
                 return $newMethod;
             case Method::SUBTYPE_ASSERT:
                 // Accessor --> Assertion
             // Accessor --> Assertion
             case Method::SUBTYPE_ASSERT_NOT:
                 $derivativeMethod = $newMethod->getDerivativeMethodByName($newMethodName, true);
                 $newMethod->setArgumentsAndKeepOldDescription($derivativeMethod->arguments);
                 $relatedVerifyMethodName = $newMethod->makeNameForSubtype(Method::SUBTYPE_VERIFY);
                 $newMethod->description = 'Assertion: ' . $newMethod->description . '<h4>Value to verify:</h4> ' . '<p>' . $newMethod->returnValue->description . '</p>' . '<h4>Notes:</h4> ' . '<p>If assertion will fail the test, it will abort the current test case ' . '(in contrast to the ' . CodeGenerator::linkToMethod($relatedVerifyMethodName) . ').</p>';
                 $newMethod->returnValue->description = '';
                 // assert* methods has no return value todo to check this
                 return $newMethod;
             case Method::SUBTYPE_VERIFY:
                 // Accessor --> Assertion
             // Accessor --> Assertion
             case Method::SUBTYPE_VERIFY_NOT:
                 $derivativeMethod = $newMethod->getDerivativeMethodByName($newMethodName, true);
                 $newMethod->setArgumentsAndKeepOldDescription($derivativeMethod->arguments);
                 $relatedAssertMethodName = $newMethod->makeNameForSubtype(Method::SUBTYPE_ASSERT);
                 $newMethod->description = 'Assertion: ' . $newMethod->description . '<h4>Value to verify:</h4> ' . '<p>' . $newMethod->returnValue->description . '</p>' . '<h4>Notes:</h4> ' . '<p>If assertion will fail the test, it will continue to run the test case ' . '(in contrast to the ' . CodeGenerator::linkToMethod($relatedAssertMethodName) . ').</p>';
                 $newMethod->returnValue->description = '';
                 // verify* methods has no return value todo to check this
                 return $newMethod;
             case Method::SUBTYPE_WAIT_FOR:
                 // Accessor --> Assertion
             // Accessor --> Assertion
             case Method::SUBTYPE_WAIT_FOR_NOT:
                 $derivativeMethod = $newMethod->getDerivativeMethodByName($newMethodName, true);
                 $newMethod->setArgumentsAndKeepOldDescription($derivativeMethod->arguments);
                 $newMethod->description = 'Assertion: ' . $newMethod->description . '<h4>Expected value/condition:</h4> ' . '<p>' . $newMethod->returnValue->description . '</p>' . '<h4>Notes:</h4> ' . "<p>This command wait for some condition to become true (or returned value is equal specified value).</p>" . '<p>This command will succeed immediately if the condition is already true.</p>';
                 $newMethod->returnValue->description = '';
                 // waitFor* methods has no return value todo to check this
                 return $newMethod;
             default:
                 self::throwException("Incorrect subtype for creating of new method: '{$oldMethod->subtype}'. " . "Source method (Accessor) should be converted only to Accessor or Assertion.");
         }
     } else {
         self::throwException("Incorrect subtype of source method: '{$oldMethod->subtype}'. " . "Source method support only Method::SUBTYPE_BASE and Method::SUBTYPE_STORE subtypes.");
     }
     return $newMethod;
 }
// add to common method list (method and its derivative methods)
$methods[] = $mSelect;
$methods[] = $generator->createNewMethodWithName($mSelect, 'selectAndWait');
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// ---- attachFile
$mAttachFile = Method::createNew();
$mAttachFile->name = 'attachFile';
$mAttachFile->type = Method::determineTypeByName($mAttachFile->name);
$mAttachFile->subtype = Method::determineSubtypeByName($mAttachFile->name);
$mAttachFile->description = 'Sets a file input (upload) field to the file listed in fileLocator.';
// first argument
$argument = Argument::createNew();
$argument->name = 'fieldLocator';
$argument->type = Argument::DEFAULT_TYPE;
$argument->description = 'an element locator (see ' . CodeGenerator::linkToProperty('doc_Element_Locators', '', 'Element Locators') . ')';
$mAttachFile->addArgument($argument);
// second argument
$argument = Argument::createNew();
$argument->name = 'fileLocator';
$argument->type = Argument::DEFAULT_TYPE;
$argument->description = <<<TEXT
    a URL pointing to the specified file. Before the file can be set in the input field (fieldLocator),
    Selenium RC may need to transfer the file to the local machine before attaching the file in a web page form.
    This is common in selenium grid configurations where the RC server driving the browser is not the same machine
    that started the test. Supported Browsers: Firefox ("*chrome") only.
TEXT;
$mAttachFile->addArgument($argument);
// return value
$mAttachFile->returnValue = ReturnValue::createNew();
$mAttachFile->returnValue->type = ReturnValue::TYPE_VOID;