Building on top of #360

We could probably improve the search UX in a couple of ways:

* Visually indicate when the "match" is because of a HOC name, e.g.
<img width="161" alt="Screen Shot 2019-08-03 at 1 54 21 PM" src="https://user-images.githubusercontent.com/29597/62416804-36f32f00-b5f6-11e9-9150-e32f652c7f98.png">

* Match built-in HOC types (e.g. searching "me" should match `React.memo` HOCs, searching "f" should match `React.forwardRef`, etc.)

---
Originally reported via https://github.com/bvaughn/react-devtools-experimental/issues/365
const snapshotLines = [];
  let rootWeight = 0;
  store.roots.forEach(rootID => {
    const {weight} = ((store.getElementByID(rootID): any): Element);
    snapshotLines.push('[root]' + (includeWeight ? ` (${weight})` : ''));
    for (let i = rootWeight; i < rootWeight + weight; i++) {
      const element = store.getElementAtIndex(i);
      if (element == null) {
        throw Error(`Could not find element at index ${i}`);
      }
      snapshotLines.push(printElement(element, includeWeight));
    }
    rootWeight += weight;
  });
  // Make sure the pretty-printed test align with the Store's reported number of total rows.
  if (rootWeight !== store.numElements) {
    throw Error(
      `Inconsistent Store state. Individual root weights (${rootWeight}) do not match total weight (${store.numElements})`,
    );
  }
  // If roots have been unmounted, verify that they've been removed from maps.
  // This helps ensure the Store doesn't leak memory.
  store.assertExpectedRootMapSizes();
  return snapshotLines.join('\n');
}
// We use JSON.parse to parse string values
// e.g. 'foo' is not valid JSON but it is a valid string
// so this method replaces e.g. 'foo' with "foo"
export function sanitizeForParse(value: any) {