function isTagInstanceOfTextInput(tag) {
  const instance = getInstanceFromNode(tag);
  return instance && instance.viewConfig && (
    instance.viewConfig.uiViewClassName === 'AndroidTextInput' ||
    instance.viewConfig.uiViewClassName === 'RCTMultilineTextInputView' ||
    instance.viewConfig.uiViewClassName === 'RCTSinglelineTextInputView'
  );
}
Mixin that can be integrated in order to handle scrolling that plays well
with `ResponderEventPlugin`. Integrate with your platform specific scroll
views, or even your custom built (every-frame animating) scroll views so that
all of these systems play well with the `ResponderEventPlugin`.

iOS scroll event timing nuances:
===============================


Scrolling without bouncing, if you touch down:
-------------------------------

1. `onMomentumScrollBegin` (when animation begins after letting up)
   ... physical touch starts ...
2. `onTouchStartCapture`   (when you press down to stop the scroll)
3. `onTouchStart`          (same, but bubble phase)
4. `onResponderRelease`    (when lifting up - you could pause forever before * lifting)
5. `onMomentumScrollEnd`


Scrolling with bouncing, if you touch down:
-------------------------------

1. `onMomentumScrollBegin` (when animation begins after letting up)
   ... bounce begins ...
   ... some time elapses ...
   ... physical touch during bounce ...
2. `onMomentumScrollEnd`   (Makes no sense why this occurs first during bounce)
3. `onTouchStartCapture`   (immediately after `onMomentumScrollEnd`)
4. `onTouchStart`          (same, but bubble phase)
5. `onTouchEnd`            (You could hold the touch start for a long time)
6. `onMomentumScrollBegin` (When releasing the view starts bouncing back)

So when we receive an `onTouchStart`, how can we tell if we are touching
*during* an animation (which then causes the animation to stop)? The only way
to tell is if the `touchStart` occurred immediately after the
`onMomentumScrollEnd`.

This is abstracted out for you, so you can just call this.scrollResponderIsAnimating() if
necessary

`ScrollResponder` also includes logic for blurring a currently focused input
if one is focused while scrolling. The `ScrollResponder` is a natural place
to put this logic since it can support not dismissing the keyboard while
scrolling, unless a recognized "tap"-like gesture has occurred.

The public lifecycle API includes events for keyboard interaction, responder
interaction, and scrolling (among others). The keyboard callbacks
`onKeyboardWill/Did/*` are *global* events, but are invoked on scroll
responder's props so that you can guarantee that the scroll responder's
internal state has been updated accordingly (and deterministically) by
the time the props callbacks are invoke. Otherwise, you would always wonder
if the scroll responder is currently in a state where it recognizes new
keyboard positions etc. If coordinating scrolling with keyboard movement,
*always* use these hooks instead of listening to your own global keyboard
events.

Public keyboard lifecycle API: (props callbacks)

Standard Keyboard Appearance Sequence:

  this.props.onKeyboardWillShow
  this.props.onKeyboardDidShow

`onScrollResponderKeyboardDismissed` will be invoked if an appropriate
tap inside the scroll responder's scrollable region was responsible
for the dismissal of the keyboard. There are other reasons why the
keyboard could be dismissed.

  this.props.onScrollResponderKeyboardDismissed

Standard Keyboard Hide Sequence:

  this.props.onKeyboardWillHide
  this.props.onKeyboardDidHide