diff --git a/docs/Advanced-By.md b/docs/Advanced-By.md
new file mode 100644
index 000000000..4226ed9f6
--- /dev/null
+++ b/docs/Advanced-By.md
@@ -0,0 +1,160 @@
+# Standard Selectors
+
+## AndroidFindBy / iOSXCUITFindBy / WindowsFindBy
+
+# Advanced Selectors
+
+## iOS's String Predicates
+
+You can specify a [predicate](https://developer.apple.com/documentation/foundation/nspredicate)
+in your Class Chain to limit the number of matched items. There's
+[a detailed guide to that](https://appium.io/docs/en/writing-running-appium/ios/ios-predicate/index.html)
+on the Appium Docs website with some Appium-specific considerations.
+
+## iOS's Class Chain Queries
+
+Our XCUiTest integration has full support for the 'Class Chain' concept. This
+can do much of what XPath does...but faster. Note that many Class Chains leverage
+String Predicates too.
+
+### String Predicates in Class Chains
+
+There's a special array-style syntax for defining predicates in a Class Chain:
+
+```
+// Start with [
+// Followed by `
+// Followed by some text
+// Followed by `
+// End with ]
+[`label != 'a'`]
+[`isWDVisible == 1`]
+[`value < 0`]
+```
+
+#### Searching Descendents
+
+If you replace the backticks (`` ` ``) around a predicate with dollar signs (`$`),
+then the Class Chain will match against the children, grandchildren, and other
+descendants of each element.
+
+```
+// Find a cell element with the label 'here'
+XCUIElementTypeCell[`label == 'here'`]
+// Find a cell element which contains SOMETHING ELSE that has the label 'here'
+XCUIElementTypeCell[$label == 'here'$]
+```
+
+#### Handling Quote Marks
+
+Most of the time, you can treat pairs of single quotes or double quotes
+interchangably. If you're searching with a string that contains quote marks,
+though, you [need to be careful](https://stackoverflow.com/q/14116217).
+
+```c
+// Make sure to escape each quote mark that matches your delimiter
+"text with \"some\" 'quote' marks"
+// To NSPredicate, the line above and the line below are equivalent
+'text with "some" \'quote\' marks'
+```
+```java
+// When defining a iOSXCUITFindBy annotation, you'll be constrained by the
+// Java string-quoting rules too.
+@iOSXCUITFindBy(iOSClassChain = "**/SomeElement[`'text with \"some\" \\\'quote\\\' marks'`]")
+```
+
+### External References
+
+Refer to [the official WebDriverAgent query docs](https://github.com/facebookarchive/WebDriverAgent/wiki/Class-Chain-Queries-Construction-Rules)
+to learn more about the general concept.
+
+### Sample usage:
+
+```java
+// Selector for image elements
+@iOSXCUITFindBy(iOSClassChain = "**/XCUIElementTypeImage")
+
+// Selector for the first image element on screen
+@iOSXCUITFindBy(iOSClassChain = "**/XCUIElementTypeImage[1]")
+// Selector for the second image element on screen
+@iOSXCUITFindBy(iOSClassChain = "**/XCUIElementTypeImage[2]")
+// Selector for the last image element on screen
+@iOSXCUITFindBy(iOSClassChain = "**/XCUIElementTypeImage[-1]")
+// Selector for the penultimate image element on screen
+@iOSXCUITFindBy(iOSClassChain = "**/XCUIElementTypeImage[-2]")
+
+// Selector for every cell with the name 'Foo' (single quote style)
+@iOSXCUITFindBy(iOSClassChain = "**/XCUIElementTypeCell[`name == 'Foo'`]")
+// Selector for every cell with the name "Foo" (double quote style)
+@iOSXCUITFindBy(iOSClassChain = "**/XCUIElementTypeCell[`name == \"Foo\"`]")
+
+// Selector for every cell with a name that starts with 'Foo' (single quote style)
+@iOSXCUITFindBy(iOSClassChain = "**/XCUIElementTypeCell[`name BEGINSWITH 'Foo'`]")
+// Selector for every cell with a name that starts with "Foo" (double quote style)
+@iOSXCUITFindBy(iOSClassChain = "**/XCUIElementTypeCell[`name BEGINSWITH \"Foo\"`]")
+
+// Selector for every cell with a name that starts with "it's not"
+@iOSXCUITFindBy(iOSClassChain = "**/XCUIElementTypeCell[`name BEGINSWITH \"it's not\"`]")
+
+// Selector that'll match every top-level element on screen
+@iOSXCUITFindBy(iOSClassChain = "*")
+// Selector that'll match every leaf element on screen (watch out: this can be SLOW)
+@iOSXCUITFindBy(iOSClassChain = "**/*")
+
+// You can place an index after a predicate: the following finds the last image element with name 'Foo'
+@iOSXCUITFindBy(iOSClassChain = "**/XCUIElementTypeCell[`name == 'Foo'`][-1]")
+```
+
+## Android's uiAutomator String
+
+Available when using [AndroidBy](AndroidBy) and [AndroidFindBy](AndroidFindBy) with
+[appium-uiautomator2-server](https://github.com/appium/appium-uiautomator2-server). This
+string will be used by the server to construct a UiSelector or UiScrollable object.
+
+### External References
+
+For an overview of what the backend is capable of, please check out the
+
+* [Main UI Automator Guide](https://developer.android.com/training/testing/ui-automator)
+* [UiScrollable API docs](https://developer.android.com/reference/androidx/test/uiautomator/UiScrollable)
+and
+* [UiSelector API docs](https://developer.android.com/reference/androidx/test/uiautomator/UiSelector)
+
+### Sample Strings
+
+Here are some ways you could configure a UiSelector in your project:
+
+```java
+// Create a selector that looks for the text "Hello World":
+@AndroidFindBy(uiAutomator = "new UiSelector().text(\"Hello World\")")
+
+// Create a selector that tries to find an ImageView:
+@AndroidFindBy(uiAutomator = "new UiSelector().className(\"android.widget.ImageView\")")
+
+// Create a selector that matches resource ids against a regular expression:
+private static final String looksLikeAPage = "page_number_\d*";
+@AndroidFindBy(uiAutomator = "new UiSelector().resourceIdMatches(\"" + looksLikeAPage + "\")")
+
+// The agent also supports some abbreviated forms - all 3 of the below
+// strings are equivalent.
+@AndroidFindBy(uiAutomator = "new UiSelector().className(\"android.widget.EditText\")")
+@AndroidFindBy(uiAutomator = "UiSelector().className(\"android.widget.EditText\")")
+@AndroidFindBy(uiAutomator = ".className(\"android.widget.EditText\")")
+
+// You can connect up conditions to search for multiple things at once
+@AndroidFindBy(uiAutomator = ".resourceId(\"android:id/list\").classNameMatches(\"\.*RecyclerView\").index(3)")
+```
+
+..and here are some that create UiScrollable objects:
+
+```java
+private static final String ourImageSelector = ".className(\"android.widget.ImageView\")";
+private static final String ourListSelector = ".className(\"android.widget.ListView\")";
+
+// Create a scrollable associated with a list (by itself, this doesn't do anything useful...)
+@AndroidFindBy(uiAutomator = "new UiScrollable(" + ourListSelector + ")")
+
+// Create a scrollable that scrolls forward along a list until it finds an ImageView:
+@AndroidFindBy(uiAutomator = "new UiScrollable(" + ourListSelector + ").scrollIntoView(" + ourImageSelector + ")")
+
+```
diff --git a/src/main/java/io/appium/java_client/MobileBy.java b/src/main/java/io/appium/java_client/MobileBy.java
index c76542da9..b8fd3d5db 100644
--- a/src/main/java/io/appium/java_client/MobileBy.java
+++ b/src/main/java/io/appium/java_client/MobileBy.java
@@ -62,8 +62,7 @@ protected MobileBy(MobileSelector selector, String locatorString) {
}
/**
- * Read http://developer.android.com/intl/ru/tools/testing-support-library/
- * index.html#uia-apis
+ * Refer to https://developer.android.com/training/testing/ui-automator
* @param uiautomatorText is Android UIAutomator string
* @return an instance of {@link io.appium.java_client.MobileBy.ByAndroidUIAutomator}
*/
@@ -87,7 +86,7 @@ public static By AccessibilityId(final String accessibilityId) {
/**
* This locator strategy is available in XCUITest Driver mode.
* @param iOSClassChainString is a valid class chain locator string.
- * See
+ * See
* the documentation for more details
* @return an instance of {@link io.appium.java_client.MobileBy.ByIosClassChain}
*/
diff --git a/src/main/java/io/appium/java_client/pagefactory/AndroidBy.java b/src/main/java/io/appium/java_client/pagefactory/AndroidBy.java
index 298956fd7..b40acdd07 100644
--- a/src/main/java/io/appium/java_client/pagefactory/AndroidBy.java
+++ b/src/main/java/io/appium/java_client/pagefactory/AndroidBy.java
@@ -21,9 +21,8 @@
*/
public @interface AndroidBy {
/**
- * It is an Android UIAutomator string.
- * Read http://developer.android.com/intl/ru/tools/testing-support-library/
- * index.html#uia-apis
+ * A String that can build an Android UiSelector or UiScrollable object.
+ * Refer to https://developer.android.com/training/testing/ui-automator
*
* @return an Android UIAutomator string
*/
diff --git a/src/main/java/io/appium/java_client/pagefactory/AndroidFindBy.java b/src/main/java/io/appium/java_client/pagefactory/AndroidFindBy.java
index d789f20ec..25b37c0b6 100644
--- a/src/main/java/io/appium/java_client/pagefactory/AndroidFindBy.java
+++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindBy.java
@@ -36,9 +36,8 @@
@Repeatable(AndroidFindBySet.class)
public @interface AndroidFindBy {
/**
- * It is an Android UIAutomator string.
- * Read http://developer.android.com/intl/ru/tools/testing-support-library/
- * index.html#uia-apis
+ * A String that can build an Android UiSelector or UiScrollable object.
+ * Refer to https://developer.android.com/training/testing/ui-automator
*
* @return an Android UIAutomator string
*/
diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITBy.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITBy.java
index 02eb4da5f..c59a1559d 100644
--- a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITBy.java
+++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITBy.java
@@ -24,7 +24,7 @@
/**
* The Class Chain locator is similar to xpath, but it's faster and can only
* search direct children elements. See the
- *
+ *
* documentation for more details.
*
* @return iOS class chain
diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBy.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBy.java
index cee419e39..5194e4094 100644
--- a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBy.java
+++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBy.java
@@ -31,7 +31,7 @@
/**
* The Class Chain locator is similar to xpath, but it's faster and can only
* search direct children elements. See the
- *
+ *
* documentation for more details.
*
* @return iOS class chain