text:
from __future__ import division, print_function

import os
import shutil
from tempfile import mkstemp, mkdtemp
from subprocess import Popen, PIPE
from distutils.errors import DistutilsError

from numpy.distutils import ccompiler, customized_ccompiler
from numpy.testing import (
    run_module_suite, assert_, assert_equal, dec
    )
from numpy.distutils.system_info import system_info, ConfigParser
from numpy.distutils.system_info import default_lib_dirs, default_include_dirs

def get_class(name, notfound_action=1):
    """
    notfound_action:
      0 - do nothing
      1 - display warning message
      2 - raise error
    """
    cl = {'temp1': Temp1Info,
          'temp2': Temp2Info
          }.get(name.lower(), _system_info)
    return cl()

simple_site = """
[ALL]
library_dirs = {dir1:s}{pathsep:s}{dir2:s}
libraries = {lib1:s},{lib2:s}
extra_compile_args = -I/fake/directory
runtime_library_dirs = {dir1:s}

[temp1]
library_dirs = {dir1:s}
libraries = {lib1:s}
runtime_library_dirs = {dir1:s}

[temp2]
library_dirs = {dir2:s}
libraries = {lib2:s}
extra_link_args = -Wl,-rpath={lib2:s}
rpath = {dir2:s}
"""
site_cfg = simple_site

fakelib_c_text = """
/* This file is generated from numpy/distutils/testing/test_system_info.py */
#include<stdio.h>
void foo(void) {
   printf("Hello foo");
}
void bar(void) {
   printf("Hello bar");
}
"""

def have_compiler():
    """ Return True if there appears to be an executable compiler
    """
    compiler = customized_ccompiler()
    try:
        cmd = compiler.compiler  # Unix compilers
    except AttributeError:
        try:
            if not compiler.initialized:
                compiler.initialize()  # MSVC is different
        except (DistutilsError, ValueError):
            return False
        cmd = [compiler.cc]
    try:
        p = Popen(cmd, stdout=PIPE, stderr=PIPE)
        p.stdout.close()
        p.stderr.close()
        p.wait()
    except OSError:
        return False
    return True

HAVE_COMPILER = have_compiler()

class _system_info(system_info):

    def __init__(self,
                 default_lib_dirs=default_lib_dirs,
                 default_include_dirs=default_include_dirs,
                 verbosity=1,
                 ):
        self.__class__.info = {}
        self.local_prefixes = []
        defaults = {'library_dirs': '',
                    'include_dirs': '',
                    'runtime_library_dirs': '',
                    'rpath': '',
                    'src_dirs': '',
                    'search_static_first': "0",
                    'extra_compile_args': '',
                    'extra_link_args': ''}
        self.cp = ConfigParser(defaults)
        # We have to parse the config files afterwards
        # to have a consistent temporary filepath

    def _check_libs(self, lib_dirs, libs, opt_libs, exts):
        """Override _check_libs to return with all dirs """
        info = {'libraries': libs, 'library_dirs': lib_dirs}
        return info

class Temp1Info(_system_info):
    """For testing purposes"""
    section = 'temp1'

class Temp2Info(_system_info):
    """For testing purposes"""
    section = 'temp2'

class TestSystemInfoReading(object):

    def setup(self):
        """ Create the libraries """
        # Create 2 sources and 2 libraries
        self._dir1 = mkdtemp()
        self._src1 = os.path.join(self._dir1, 'foo.c')
        self._lib1 = os.path.join(self._dir1, 'libfoo.so')
        self._dir2 = mkdtemp()
        self._src2 = os.path.join(self._dir2, 'bar.c')
        self._lib2 = os.path.join(self._dir2, 'libbar.so')
        # Update local site.cfg
        global simple_site, site_cfg
        site_cfg = simple_site.format(**{
            'dir1': self._dir1,
            'lib1': self._lib1,
            'dir2': self._dir2,
            'lib2': self._lib2,
            'pathsep': os.pathsep
        })
        # Write site.cfg
        fd, self._sitecfg = mkstemp()
        os.close(fd)
        with open(self._sitecfg, 'w') as fd:
            fd.write(site_cfg)
        # Write the sources
        with open(self._src1, 'w') as fd:
            fd.write(fakelib_c_text)
        with open(self._src2, 'w') as fd:
            fd.write(fakelib_c_text)
        # We create all class-instances

        def site_and_parse(c, site_cfg):
            c.files = [site_cfg]
            c.parse_config_files()
            return c
        self.c_default = site_and_parse(get_class('default'), self._sitecfg)
        self.c_temp1 = site_and_parse(get_class('temp1'), self._sitecfg)
        self.c_temp2 = site_and_parse(get_class('temp2'), self._sitecfg)

    def tearDown(self):
        # Do each removal separately
        try:
            shutil.rmtree(self._dir1)
        except Exception:
            pass
        try:
            shutil.rmtree(self._dir2)
        except Exception:
            pass
        try:
            os.remove(self._sitecfg)
        except Exception:
            pass

    def test_all(self):
        # Read in all information in the ALL block
        tsi = self.c_default
        assert_equal(tsi.get_lib_dirs(), [self._dir1, self._dir2])
        assert_equal(tsi.get_libraries(), [self._lib1, self._lib2])
        assert_equal(tsi.get_runtime_lib_dirs(), [self._dir1])
        extra = tsi.calc_extra_info()
        assert_equal(extra['extra_compile_args'], ['-I/fake/directory'])

    def test_temp1(self):
        # Read in all information in the temp1 block
        tsi = self.c_temp1
        assert_equal(tsi.get_lib_dirs(), [self._dir1])
        assert_equal(tsi.get_libraries(), [self._lib1])
        assert_equal(tsi.get_runtime_lib_dirs(), [self._dir1])

    def test_temp2(self):
        # Read in all information in the temp2 block
        tsi = self.c_temp2
        assert_equal(tsi.get_lib_dirs(), [self._dir2])
        assert_equal(tsi.get_libraries(), [self._lib2])
        # Now from rpath and not runtime_library_dirs
        assert_equal(tsi.get_runtime_lib_dirs(key='rpath'), [self._dir2])
        extra = tsi.calc_extra_info()
        assert_equal(extra['extra_link_args'], ['-Wl,-rpath=' + self._lib2])

    @dec.skipif(not HAVE_COMPILER)
    def test_compile1(self):
        # Compile source and link the first source
        c = customized_ccompiler()
        previousDir = os.getcwd()
        try:
            # Change directory to not screw up directories
            os.chdir(self._dir1)
            c.compile([os.path.basename(self._src1)], output_dir=self._dir1)
            # Ensure that the object exists
            assert_(os.path.isfile(self._src1.replace('.c', '.o')) or
                    os.path.isfile(self._src1.replace('.c', '.obj')))
        finally:
            os.chdir(previousDir)

    @dec.skipif(not HAVE_COMPILER)
    @dec.skipif('msvc' in repr(ccompiler.new_compiler()))
    def test_compile2(self):
        # Compile source and link the second source
        tsi = self.c_temp2
        c = customized_ccompiler()
        extra_link_args = tsi.calc_extra_info()['extra_link_args']
        previousDir = os.getcwd()
        try:
            # Change directory to not screw up directories
            os.chdir(self._dir2)
            c.compile([os.path.basename(self._src2)], output_dir=self._dir2,
                      extra_postargs=extra_link_args)
            # Ensure that the object exists
            assert_(os.path.isfile(self._src2.replace('.c', '.o')))
        finally:
            os.chdir(previousDir)

if __name__ == '__main__':
    run_module_suite()


text:
'use strict';

// This test is a hot mess. It heavily uses internals and relies on DOM even
// though the responder plugin is only used in React Native. Sadness ensues.
// The coverage is valuable though, so we will keep it for now.
const {HostComponent} = require('react-reconciler/src/ReactWorkTags');

let EventBatching;
let EventPluginUtils;
let ResponderEventPlugin;

const touch = function(nodeHandle, i) {
  return {target: nodeHandle, identifier: i};
};

function injectComponentTree(ComponentTree) {
  EventPluginUtils.setComponentTree(
    ComponentTree.getFiberCurrentPropsFromNode,
    ComponentTree.getInstanceFromNode,
    ComponentTree.getNodeFromInstance,
  );
}

/**
 * @param {NodeHandle} nodeHandle @see NodeHandle. Handle of target.
 * @param {Array<Touch>} touches All active touches.
 * @param {Array<Touch>} changedTouches Only the touches that have changed.
 * @return {TouchEvent} Model of a touch event that is compliant with responder
 * system plugin.
 */
const touchEvent = function(nodeHandle, touches, changedTouches) {
  return {
    target: nodeHandle,
    changedTouches: changedTouches,
    touches: touches,
  };
};

const subsequence = function(arr, indices) {
  const ret = [];
  for (let i = 0; i < indices.length; i++) {
    const index = indices[i];
    ret.push(arr[index]);
  }
  return ret;
};

const antiSubsequence = function(arr, indices) {
  const ret = [];
  for (let i = 0; i < arr.length; i++) {
    if (indices.indexOf(i) === -1) {
      ret.push(arr[i]);
    }
  }
  return ret;
};

/**
 * Helper for creating touch test config data.
 * @param allTouchHandles
 */
const _touchConfig = function(
  topType,
  targetNodeHandle,
  allTouchHandles,
  changedIndices,
  eventTarget,
) {
  const allTouchObjects = allTouchHandles.map(touch);
  const changedTouchObjects = subsequence(allTouchObjects, changedIndices);
  const activeTouchObjects =
    topType === 'topTouchStart'
      ? allTouchObjects
      : topType === 'topTouchMove'
      ? allTouchObjects
      : topType === 'topTouchEnd'
      ? antiSubsequence(allTouchObjects, changedIndices)
      : topType === 'topTouchCancel'
      ? antiSubsequence(allTouchObjects, changedIndices)
      : null;

  return {
    nativeEvent: touchEvent(
      targetNodeHandle,
      activeTouchObjects,
      changedTouchObjects,
    ),
    topLevelType: topType,
    targetInst: getInstanceFromNode(targetNodeHandle),
  };
};

/**
 * Creates test data for touch events using environment agnostic "node
 * handles".
 *
 * @param {NodeHandle} nodeHandle Environment agnostic handle to DOM node.
 * @param {Array<NodeHandle>} allTouchHandles Encoding of all "touches" in the
 * form of a mapping from integer (touch `identifier`) to touch target. This is
 * encoded in array form. Because of this, it is possible for two separate
 * touches (meaning two separate indices) to have the same touch target ID -
 * this corresponds to real world cases where two separate unique touches have
 * the same target. These touches don't just represent all active touches,
 * rather it also includes any touches that are not active, but are in the
 * process of being removed.
 * @param {Array<NodeHandle>} changedIndices Indices of `allTouchHandles` that
 * have changed.
 * @return {object} Config data used by test cases for extracting responder
 * events.
 */
const startConfig = function(nodeHandle, allTouchHandles, changedIndices) {
  return _touchConfig(
    'topTouchStart',
    nodeHandle,
    allTouchHandles,
    changedIndices,
    nodeHandle,
  );
};

/**
 * @see `startConfig`
 */
const moveConfig = function(nodeHandle, allTouchHandles, changedIndices) {
  return _touchConfig(
    'topTouchMove',
    nodeHandle,
    allTouchHandles,
    changedIndices,
    nodeHandle,
  );
};

/**
 * @see `startConfig`
 */
const endConfig = function(nodeHandle, allTouchHandles, changedIndices) {
  return _touchConfig(
    'topTouchEnd',
    nodeHandle,
    allTouchHandles,
    changedIndices,
    nodeHandle,
  );
};

/**
 * Test config for events that aren't negotiation related, but rather result of
 * a negotiation.
 *
 * Returns object of the form:
 *
 *     {
 *       responderReject: {
 *         // Whatever "readableIDToID" was passed in.
 *         grandParent: {order: NA, assertEvent: null, returnVal: blah},
 *         ...
 *         child: {order: NA, assertEvent: null, returnVal: blah},
 *       }
 *       responderGrant: {
 *         grandParent: {order: NA, assertEvent: null, returnVal: blah},
 *         ...
 *         child: {order: NA, assertEvent: null, returnVal: blah}
 *       }
 *       ...
 *     }
 *
 * After this is created, a test case would configure specific event orderings
 * and optional assertions. Anything left with an `order` of `NA` will be
 * required to never be invoked (the test runner will make sure it throws if
 * ever invoked).
 *
 */
const NA = -1;
const oneEventLoopTestConfig = function(readableIDToID) {
  const ret = {
    // Negotiation
    scrollShouldSetResponder: {bubbled: {}, captured: {}},
    startShouldSetResponder: {bubbled: {}, captured: {}},
    moveShouldSetResponder: {bubbled: {}, captured: {}},
    responderTerminationRequest: {},

    // Non-negotiation
    responderReject: {}, // These do not bubble capture.
    responderGrant: {},
    responderStart: {},
    responderMove: {},
    responderTerminate: {},
    responderEnd: {},
    responderRelease: {},
  };
  for (const eventName in ret) {
    for (const readableNodeName in readableIDToID) {
      if (ret[eventName].bubbled) {
        // Two phase
        ret[eventName].bubbled[readableNodeName] = {
          order: NA,
          assertEvent: null,
          returnVal: undefined,
        };
        ret[eventName].captured[readableNodeName] = {
          order: NA,
          assertEvent: null,
          returnVal: undefined,
        };
      } else {
        ret[eventName][readableNodeName] = {
          order: NA,
          assertEvent: null,
          returnVal: undefined,
        };
      }
    }
  }
  return ret;
};

/**
 * @param {object} eventTestConfig
 * @param {object} readableIDToID
 */
const registerTestHandlers = function(eventTestConfig, readableIDToID) {
  const runs = {dispatchCount: 0};
  const neverFire = function(readableID, registrationName) {
    runs.dispatchCount++;
    expect('').toBe(
      'Event type: ' +
        registrationName +
        '\nShould never occur on:' +
        readableID +
        '\nFor event test config:\n' +
        JSON.stringify(eventTestConfig) +
        '\n',
    );
  };

  const registerOneEventType = function(registrationName, eventTypeTestConfig) {
    for (const readableID in eventTypeTestConfig) {
      const nodeConfig = eventTypeTestConfig[readableID];
      const id = readableIDToID[readableID];
      const handler =
        nodeConfig.order === NA
          ? neverFire.bind(null, readableID, registrationName)
          : // We partially apply readableID and nodeConfig, as they change in the
            // parent closure across iterations.
            function(rID, config, e) {
              expect(
                rID +
                  '->' +
                  registrationName +
                  ' index:' +
                  runs.dispatchCount++,
              ).toBe(rID + '->' + registrationName + ' index:' + config.order);
              if (config.assertEvent) {
                config.assertEvent(e);
              }
              return config.returnVal;
            }.bind(null, readableID, nodeConfig);
      putListener(getInstanceFromNode(id), registrationName, handler);
    }
  };
  for (const eventName in eventTestConfig) {
    const oneEventTypeTestConfig = eventTestConfig[eventName];
    const hasTwoPhase = !!oneEventTypeTestConfig.bubbled;
    if (hasTwoPhase) {
      registerOneEventType(
        ResponderEventPlugin.eventTypes[eventName].phasedRegistrationNames
          .bubbled,
        oneEventTypeTestConfig.bubbled,
      );
      registerOneEventType(
        ResponderEventPlugin.eventTypes[eventName].phasedRegistrationNames
          .captured,
        oneEventTypeTestConfig.captured,
      );
    } else {
      registerOneEventType(
        ResponderEventPlugin.eventTypes[eventName].registrationName,
        oneEventTypeTestConfig,
      );
    }
  }
  return runs;
};

const run = function(config, hierarchyConfig, nativeEventConfig) {
  let max = NA;
  const searchForMax = function(nodeConfig) {
    for (const readableID in nodeConfig) {
      const order = nodeConfig[readableID].order;
      max = order > max ? order : max;
    }
  };
  for (const eventName in config) {
    const eventConfig = config[eventName];
    if (eventConfig.bubbled) {
      searchForMax(eventConfig.bubbled);
      searchForMax(eventConfig.captured);
    } else {
      searchForMax(eventConfig);
    }
  }

  // Register the handlers
  const runData = registerTestHandlers(config, hierarchyConfig);

  // Trigger the event
  const extractedEvents = ResponderEventPlugin.extractEvents(
    nativeEventConfig.topLevelType,
    nativeEventConfig.targetInst,
    nativeEventConfig.nativeEvent,
    nativeEventConfig.target,
    0,
  );

  // At this point the negotiation events have been dispatched as part of the
  // extraction process, but not the side effectful events. Below, we dispatch
  // side effectful events.
  EventBatching.runEventsInBatch(extractedEvents);

  // Ensure that every event that declared an `order`, was actually dispatched.
  expect('number of events dispatched:' + runData.dispatchCount).toBe(
    'number of events dispatched:' + (max + 1),
  ); // +1 for extra ++
};

const GRANDPARENT_HOST_NODE = {};
const PARENT_HOST_NODE = {};
const CHILD_HOST_NODE = {};
const CHILD_HOST_NODE2 = {};

// These intentionally look like Fibers. ReactTreeTraversal depends on their field names.
// TODO: we could test this with regular DOM nodes (and real fibers) instead.
const GRANDPARENT_INST = {
  return: null,
  tag: HostComponent,
  stateNode: GRANDPARENT_HOST_NODE,
  memoizedProps: {},
};
const PARENT_INST = {
  return: GRANDPARENT_INST,
  tag: HostComponent,
  stateNode: PARENT_HOST_NODE,
  memoizedProps: {},
};
const CHILD_INST = {
  return: PARENT_INST,
  tag: HostComponent,
  stateNode: CHILD_HOST_NODE,
  memoizedProps: {},
};
const CHILD_INST2 = {
  return: PARENT_INST,
  tag: HostComponent,
  stateNode: CHILD_HOST_NODE2,
  memoizedProps: {},
};

GRANDPARENT_HOST_NODE.testInstance = GRANDPARENT_INST;
PARENT_HOST_NODE.testInstance = PARENT_INST;
CHILD_HOST_NODE.testInstance = CHILD_INST;
CHILD_HOST_NODE2.testInstance = CHILD_INST2;

const three = {
  grandParent: GRANDPARENT_HOST_NODE,
  parent: PARENT_HOST_NODE,
  child: CHILD_HOST_NODE,
};

const siblings = {
  parent: PARENT_HOST_NODE,
  childOne: CHILD_HOST_NODE,
  childTwo: CHILD_HOST_NODE2,
};

function getInstanceFromNode(node) {
  return node.testInstance;
}

function getNodeFromInstance(inst) {
  return inst.stateNode;
}

function getFiberCurrentPropsFromNode(node) {
  return node.testInstance.memoizedProps;
}

function putListener(instance, registrationName, handler) {
  instance.memoizedProps[registrationName] = handler;
}

function deleteAllListeners(instance) {
  instance.memoizedProps = {};
}

describe('ResponderEventPlugin', () => {
  beforeEach(() => {
    jest.resetModules();

    EventBatching = require('react-native-renderer/src/legacy-events/EventBatching');
    EventPluginUtils = require('react-native-renderer/src/legacy-events/EventPluginUtils');
    ResponderEventPlugin = require('react-native-renderer/src/legacy-events/ResponderEventPlugin')
      .default;

    deleteAllListeners(GRANDPARENT_INST);
    deleteAllListeners(PARENT_INST);
    deleteAllListeners(CHILD_INST);
    deleteAllListeners(CHILD_INST2);

    injectComponentTree({
      getInstanceFromNode,
      getNodeFromInstance,
      getFiberCurrentPropsFromNode,
    });
  });

  it('should do nothing when no one wants to respond', () => {
    let config = oneEventLoopTestConfig(three);
    config.startShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.parent = {
      order: 1,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.child = {
      order: 2,
      returnVal: false,
    };
    config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: false};
    config.startShouldSetResponder.bubbled.parent = {
      order: 4,
      returnVal: false,
    };
    config.startShouldSetResponder.bubbled.grandParent = {
      order: 5,
      returnVal: false,
    };
    run(config, three, startConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(null);

    // Now no handlers should be called on `touchEnd`.
    config = oneEventLoopTestConfig(three);
    run(config, three, endConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(null);
  });

  /**
   * Simple Start Granting
   * --------------------
   */

  it('should grant responder grandParent while capturing', () => {
    let config = oneEventLoopTestConfig(three);
    config.startShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: true,
    };
    config.responderGrant.grandParent = {order: 1};
    config.responderStart.grandParent = {order: 2};
    run(config, three, startConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.grandParent),
    );

    config = oneEventLoopTestConfig(three);
    config.responderEnd.grandParent = {order: 0};
    config.responderRelease.grandParent = {order: 1};
    run(config, three, endConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(null);
  });

  it('should grant responder parent while capturing', () => {
    let config = oneEventLoopTestConfig(three);
    config.startShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.parent = {
      order: 1,
      returnVal: true,
    };
    config.responderGrant.parent = {order: 2};
    config.responderStart.parent = {order: 3};
    run(config, three, startConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.parent),
    );

    config = oneEventLoopTestConfig(three);
    config.responderEnd.parent = {order: 0};
    config.responderRelease.parent = {order: 1};
    run(config, three, endConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(null);
  });

  it('should grant responder child while capturing', () => {
    let config = oneEventLoopTestConfig(three);
    config.startShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.parent = {
      order: 1,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.child = {order: 2, returnVal: true};
    config.responderGrant.child = {order: 3};
    config.responderStart.child = {order: 4};
    run(config, three, startConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.child),
    );

    config = oneEventLoopTestConfig(three);
    config.responderEnd.child = {order: 0};
    config.responderRelease.child = {order: 1};
    run(config, three, endConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(null);
  });

  it('should grant responder child while bubbling', () => {
    let config = oneEventLoopTestConfig(three);
    config.startShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.parent = {
      order: 1,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.child = {
      order: 2,
      returnVal: false,
    };
    config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: true};
    config.responderGrant.child = {order: 4};
    config.responderStart.child = {order: 5};
    run(config, three, startConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.child),
    );

    config = oneEventLoopTestConfig(three);
    config.responderEnd.child = {order: 0};
    config.responderRelease.child = {order: 1};
    run(config, three, endConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(null);
  });

  it('should grant responder parent while bubbling', () => {
    let config = oneEventLoopTestConfig(three);
    config.startShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.parent = {
      order: 1,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.child = {
      order: 2,
      returnVal: false,
    };
    config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: false};
    config.startShouldSetResponder.bubbled.parent = {order: 4, returnVal: true};
    config.responderGrant.parent = {order: 5};
    config.responderStart.parent = {order: 6};
    run(config, three, startConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.parent),
    );

    config = oneEventLoopTestConfig(three);
    config.responderEnd.parent = {order: 0};
    config.responderRelease.parent = {order: 1};
    run(config, three, endConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(null);
  });

  it('should grant responder grandParent while bubbling', () => {
    let config = oneEventLoopTestConfig(three);
    config.startShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.parent = {
      order: 1,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.child = {
      order: 2,
      returnVal: false,
    };
    config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: false};
    config.startShouldSetResponder.bubbled.parent = {
      order: 4,
      returnVal: false,
    };
    config.startShouldSetResponder.bubbled.grandParent = {
      order: 5,
      returnVal: true,
    };
    config.responderGrant.grandParent = {order: 6};
    config.responderStart.grandParent = {order: 7};
    run(config, three, startConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.grandParent),
    );

    config = oneEventLoopTestConfig(three);
    config.responderEnd.grandParent = {order: 0};
    config.responderRelease.grandParent = {order: 1};
    run(config, three, endConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(null);
  });

  /**
   * Simple Move Granting
   * --------------------
   */

  it('should grant responder grandParent while capturing move', () => {
    let config = oneEventLoopTestConfig(three);

    config.startShouldSetResponder.captured.grandParent = {order: 0};
    config.startShouldSetResponder.captured.parent = {order: 1};
    config.startShouldSetResponder.captured.child = {order: 2};
    config.startShouldSetResponder.bubbled.child = {order: 3};
    config.startShouldSetResponder.bubbled.parent = {order: 4};
    config.startShouldSetResponder.bubbled.grandParent = {order: 5};
    run(config, three, startConfig(three.child, [three.child], [0]));

    config = oneEventLoopTestConfig(three);
    config.moveShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: true,
    };
    config.responderGrant.grandParent = {order: 1};
    config.responderMove.grandParent = {order: 2};
    run(config, three, moveConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.grandParent),
    );

    config = oneEventLoopTestConfig(three);
    config.responderEnd.grandParent = {order: 0};
    config.responderRelease.grandParent = {order: 1};
    run(config, three, endConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(null);
  });

  it('should grant responder parent while capturing move', () => {
    let config = oneEventLoopTestConfig(three);

    config.startShouldSetResponder.captured.grandParent = {order: 0};
    config.startShouldSetResponder.captured.parent = {order: 1};
    config.startShouldSetResponder.captured.child = {order: 2};
    config.startShouldSetResponder.bubbled.child = {order: 3};
    config.startShouldSetResponder.bubbled.parent = {order: 4};
    config.startShouldSetResponder.bubbled.grandParent = {order: 5};
    run(config, three, startConfig(three.child, [three.child], [0]));

    config = oneEventLoopTestConfig(three);
    config.moveShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.moveShouldSetResponder.captured.parent = {order: 1, returnVal: true};
    config.responderGrant.parent = {order: 2};
    config.responderMove.parent = {order: 3};
    run(config, three, moveConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.parent),
    );

    config = oneEventLoopTestConfig(three);
    config.responderEnd.parent = {order: 0};
    config.responderRelease.parent = {order: 1};
    run(config, three, endConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(null);
  });

  it('should grant responder child while capturing move', () => {
    let config = oneEventLoopTestConfig(three);

    config.startShouldSetResponder.captured.grandParent = {order: 0};
    config.startShouldSetResponder.captured.parent = {order: 1};
    config.startShouldSetResponder.captured.child = {order: 2};
    config.startShouldSetResponder.bubbled.child = {order: 3};
    config.startShouldSetResponder.bubbled.parent = {order: 4};
    config.startShouldSetResponder.bubbled.grandParent = {order: 5};
    run(config, three, startConfig(three.child, [three.child], [0]));

    config = oneEventLoopTestConfig(three);
    config.moveShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.moveShouldSetResponder.captured.parent = {
      order: 1,
      returnVal: false,
    };
    config.moveShouldSetResponder.captured.child = {order: 2, returnVal: true};
    config.responderGrant.child = {order: 3};
    config.responderMove.child = {order: 4};
    run(config, three, moveConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.child),
    );

    config = oneEventLoopTestConfig(three);
    config.responderEnd.child = {order: 0};
    config.responderRelease.child = {order: 1};
    run(config, three, endConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(null);
  });

  it('should grant responder child while bubbling move', () => {
    let config = oneEventLoopTestConfig(three);

    config.startShouldSetResponder.captured.grandParent = {order: 0};
    config.startShouldSetResponder.captured.parent = {order: 1};
    config.startShouldSetResponder.captured.child = {order: 2};
    config.startShouldSetResponder.bubbled.child = {order: 3};
    config.startShouldSetResponder.bubbled.parent = {order: 4};
    config.startShouldSetResponder.bubbled.grandParent = {order: 5};
    run(config, three, startConfig(three.child, [three.child], [0]));

    config = oneEventLoopTestConfig(three);
    config.moveShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.moveShouldSetResponder.captured.parent = {
      order: 1,
      returnVal: false,
    };
    config.moveShouldSetResponder.captured.child = {order: 2, returnVal: false};
    config.moveShouldSetResponder.bubbled.child = {order: 3, returnVal: true};
    config.responderGrant.child = {order: 4};
    config.responderMove.child = {order: 5};
    run(config, three, moveConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.child),
    );

    config = oneEventLoopTestConfig(three);
    config.responderEnd.child = {order: 0};
    config.responderRelease.child = {order: 1};
    run(config, three, endConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(null);
  });

  it('should grant responder parent while bubbling move', () => {
    let config = oneEventLoopTestConfig(three);

    config.startShouldSetResponder.captured.grandParent = {order: 0};
    config.startShouldSetResponder.captured.parent = {order: 1};
    config.startShouldSetResponder.captured.child = {order: 2};
    config.startShouldSetResponder.bubbled.child = {order: 3};
    config.startShouldSetResponder.bubbled.parent = {order: 4};
    config.startShouldSetResponder.bubbled.grandParent = {order: 5};
    run(config, three, startConfig(three.child, [three.child], [0]));

    config = oneEventLoopTestConfig(three);
    config.moveShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.moveShouldSetResponder.captured.parent = {
      order: 1,
      returnVal: false,
    };
    config.moveShouldSetResponder.captured.child = {order: 2, returnVal: false};
    config.moveShouldSetResponder.bubbled.child = {order: 3, returnVal: false};
    config.moveShouldSetResponder.bubbled.parent = {order: 4, returnVal: true};
    config.responderGrant.parent = {order: 5};
    config.responderMove.parent = {order: 6};
    run(config, three, moveConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.parent),
    );

    config = oneEventLoopTestConfig(three);
    config.responderEnd.parent = {order: 0};
    config.responderRelease.parent = {order: 1};
    run(config, three, endConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(null);
  });

  it('should grant responder grandParent while bubbling move', () => {
    let config = oneEventLoopTestConfig(three);

    config.startShouldSetResponder.captured.grandParent = {order: 0};
    config.startShouldSetResponder.captured.parent = {order: 1};
    config.startShouldSetResponder.captured.child = {order: 2};
    config.startShouldSetResponder.bubbled.child = {order: 3};
    config.startShouldSetResponder.bubbled.parent = {order: 4};
    config.startShouldSetResponder.bubbled.grandParent = {order: 5};
    run(config, three, startConfig(three.child, [three.child], [0]));

    config = oneEventLoopTestConfig(three);
    config.moveShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.moveShouldSetResponder.captured.parent = {
      order: 1,
      returnVal: false,
    };
    config.moveShouldSetResponder.captured.child = {order: 2, returnVal: false};
    config.moveShouldSetResponder.bubbled.child = {order: 3, returnVal: false};
    config.moveShouldSetResponder.bubbled.parent = {order: 4, returnVal: false};
    config.moveShouldSetResponder.bubbled.grandParent = {
      order: 5,
      returnVal: true,
    };
    config.responderGrant.grandParent = {order: 6};
    config.responderMove.grandParent = {order: 7};
    run(config, three, moveConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.grandParent),
    );

    config = oneEventLoopTestConfig(three);
    config.responderEnd.grandParent = {order: 0};
    config.responderRelease.grandParent = {order: 1};
    run(config, three, endConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(null);
  });

  /**
   * Common ancestor tests
   * ---------------------
   */

  it('should bubble negotiation to first common ancestor of responder', () => {
    let config = oneEventLoopTestConfig(three);
    config.startShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.parent = {
      order: 1,
      returnVal: true,
    };
    config.responderGrant.parent = {order: 2};
    config.responderStart.parent = {order: 3};
    run(config, three, startConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.parent),
    );

    // While `parent` is still responder, we create new handlers that verify
    // the ordering of propagation, restarting the count at `0`.
    config = oneEventLoopTestConfig(three);
    config.startShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };

    config.startShouldSetResponder.bubbled.grandParent = {
      order: 1,
      returnVal: false,
    };
    config.responderStart.parent = {order: 2};
    run(config, three, startConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.parent),
    );

    config = oneEventLoopTestConfig(three);
    config.responderEnd.parent = {order: 0};
    config.responderRelease.parent = {order: 1};
    run(config, three, endConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(null);
  });

  it('should bubble negotiation to first common ancestor of responder then transfer', () => {
    let config = oneEventLoopTestConfig(three);
    config.startShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.parent = {
      order: 1,
      returnVal: true,
    };
    config.responderGrant.parent = {order: 2};
    config.responderStart.parent = {order: 3};
    run(config, three, startConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.parent),
    );

    config = oneEventLoopTestConfig(three);

    // Parent is responder, and responder is transferred by a second touch start
    config.startShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: true,
    };
    config.responderGrant.grandParent = {order: 1};
    config.responderTerminationRequest.parent = {order: 2, returnVal: true};
    config.responderTerminate.parent = {order: 3};
    config.responderStart.grandParent = {order: 4};
    run(
      config,
      three,
      startConfig(three.child, [three.child, three.child], [1]),
    );
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.grandParent),
    );

    config = oneEventLoopTestConfig(three);
    config.responderEnd.grandParent = {order: 0};
    // one remains\ /one ended \
    run(config, three, endConfig(three.child, [three.child, three.child], [1]));
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.grandParent),
    );

    config = oneEventLoopTestConfig(three);
    config.responderEnd.grandParent = {order: 0};
    config.responderRelease.grandParent = {order: 1};
    run(config, three, endConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(null);
  });

  /**
   * If nothing is responder, then the negotiation should propagate directly to
   * the deepest target in the second touch.
   */
  it('should negotiate with deepest target on second touch if nothing is responder', () => {
    // Initially nothing wants to become the responder
    let config = oneEventLoopTestConfig(three);
    config.startShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.parent = {
      order: 1,
      returnVal: false,
    };
    config.startShouldSetResponder.bubbled.parent = {
      order: 2,
      returnVal: false,
    };
    config.startShouldSetResponder.bubbled.grandParent = {
      order: 3,
      returnVal: false,
    };

    run(config, three, startConfig(three.parent, [three.parent], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(null);

    config = oneEventLoopTestConfig(three);

    // Now child wants to become responder. Negotiation should bubble as deep
    // as the target is because we don't find first common ancestor (with
    // current responder) because there is no current responder.
    // (Even if this is the second active touch).
    config.startShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.parent = {
      order: 1,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.child = {
      order: 2,
      returnVal: false,
    };
    config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: true};
    config.responderGrant.child = {order: 4};
    config.responderStart.child = {order: 5};
    //                                     /  Two active touches  \  /one of them new\
    run(
      config,
      three,
      startConfig(three.child, [three.parent, three.child], [1]),
    );
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.child),
    );

    // Now we remove the original first touch, keeping the second touch that
    // started within the current responder (child). Nothing changes because
    // there's still touches that started inside of the current responder.
    config = oneEventLoopTestConfig(three);
    config.responderEnd.child = {order: 0};
    //                                      / one ended\  /one remains \
    run(
      config,
      three,
      endConfig(three.child, [three.parent, three.child], [0]),
    );
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.child),
    );

    // Okay, now let's add back that first touch (nothing should change) and
    // then we'll try peeling back the touches in the opposite order to make
    // sure that first removing the second touch instantly causes responder to
    // be released.
    config = oneEventLoopTestConfig(three);
    config.startShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.parent = {
      order: 1,
      returnVal: false,
    };
    config.startShouldSetResponder.bubbled.parent = {
      order: 2,
      returnVal: false,
    };
    config.startShouldSetResponder.bubbled.grandParent = {
      order: 3,
      returnVal: false,
    };
    // Interesting: child still gets moves even though touch target is parent!
    // Current responder gets a `responderStart` for any touch while responder.
    config.responderStart.child = {order: 4};
    //                                           /  Two active touches  \  /one of them new\
    run(
      config,
      three,
      startConfig(three.parent, [three.child, three.parent], [1]),
    );
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.child),
    );

    // Now, move that new touch that had no effect, and did not start within
    // the current responder.
    config = oneEventLoopTestConfig(three);
    config.moveShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.moveShouldSetResponder.captured.parent = {
      order: 1,
      returnVal: false,
    };
    config.moveShouldSetResponder.bubbled.parent = {order: 2, returnVal: false};
    config.moveShouldSetResponder.bubbled.grandParent = {
      order: 3,
      returnVal: false,
    };
    // Interesting: child still gets moves even though touch target is parent!
    // Current responder gets a `responderMove` for any touch while responder.
    config.responderMove.child = {order: 4};
    //                                     /  Two active touches  \  /one of them moved\
    run(
      config,
      three,
      moveConfig(three.parent, [three.child, three.parent], [1]),
    );
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.child),
    );

    config = oneEventLoopTestConfig(three);
    config.responderEnd.child = {order: 0};
    config.responderRelease.child = {order: 1};
    //                                        /child end \ /parent remain\
    run(
      config,
      three,
      endConfig(three.child, [three.child, three.parent], [0]),
    );
    expect(ResponderEventPlugin._getResponder()).toBe(null);
  });

  /**
   * If nothing is responder, then the negotiation should propagate directly to
   * the deepest target in the second touch.
   */
  it('should negotiate until first common ancestor when there are siblings', () => {
    // Initially nothing wants to become the responder
    let config = oneEventLoopTestConfig(siblings);
    config.startShouldSetResponder.captured.parent = {
      order: 0,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.childOne = {
      order: 1,
      returnVal: false,
    };
    config.startShouldSetResponder.bubbled.childOne = {
      order: 2,
      returnVal: true,
    };
    config.responderGrant.childOne = {order: 3};
    config.responderStart.childOne = {order: 4};

    run(
      config,
      siblings,
      startConfig(siblings.childOne, [siblings.childOne], [0]),
    );
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(siblings.childOne),
    );

    // If the touch target is the sibling item, the negotiation should only
    // propagate to first common ancestor of current responder and sibling (so
    // the parent).
    config = oneEventLoopTestConfig(siblings);
    config.startShouldSetResponder.captured.parent = {
      order: 0,
      returnVal: false,
    };
    config.startShouldSetResponder.bubbled.parent = {
      order: 1,
      returnVal: false,
    };
    config.responderStart.childOne = {order: 2};

    const touchConfig = startConfig(
      siblings.childTwo,
      [siblings.childOne, siblings.childTwo],
      [1],
    );
    run(config, siblings, touchConfig);
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(siblings.childOne),
    );

    // move childOne
    config = oneEventLoopTestConfig(siblings);
    config.moveShouldSetResponder.captured.parent = {
      order: 0,
      returnVal: false,
    };
    config.moveShouldSetResponder.bubbled.parent = {order: 1, returnVal: false};
    config.responderMove.childOne = {order: 2};
    run(
      config,
      siblings,
      moveConfig(
        siblings.childOne,
        [siblings.childOne, siblings.childTwo],
        [0],
      ),
    );
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(siblings.childOne),
    );

    // move childTwo: Only negotiates to `parent`.
    config = oneEventLoopTestConfig(siblings);
    config.moveShouldSetResponder.captured.parent = {
      order: 0,
      returnVal: false,
    };
    config.moveShouldSetResponder.bubbled.parent = {order: 1, returnVal: false};
    config.responderMove.childOne = {order: 2};
    run(
      config,
      siblings,
      moveConfig(
        siblings.childTwo,
        [siblings.childOne, siblings.childTwo],
        [1],
      ),
    );
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(siblings.childOne),
    );
  });

  it('should notify of being rejected. responderStart/Move happens on current responder', () => {
    // Initially nothing wants to become the responder
    let config = oneEventLoopTestConfig(three);
    config.startShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.parent = {
      order: 1,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.child = {
      order: 2,
      returnVal: false,
    };
    config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: true};
    config.responderGrant.child = {order: 4};
    config.responderStart.child = {order: 5};

    run(config, three, startConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.child),
    );

    // Suppose parent wants to become responder on move, and is rejected
    config = oneEventLoopTestConfig(three);
    config.moveShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.moveShouldSetResponder.captured.parent = {
      order: 1,
      returnVal: false,
    };
    config.moveShouldSetResponder.bubbled.parent = {order: 2, returnVal: true};
    config.responderGrant.parent = {order: 3};
    config.responderTerminationRequest.child = {order: 4, returnVal: false};
    config.responderReject.parent = {order: 5};
    // The start/move should occur on the original responder if new one is rejected
    config.responderMove.child = {order: 6};

    let touchConfig = moveConfig(three.child, [three.child], [0]);
    run(config, three, touchConfig);
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.child),
    );

    config = oneEventLoopTestConfig(three);
    config.startShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.parent = {
      order: 1,
      returnVal: false,
    };
    config.startShouldSetResponder.bubbled.parent = {order: 2, returnVal: true};
    config.responderGrant.parent = {order: 3};
    config.responderTerminationRequest.child = {order: 4, returnVal: false};
    config.responderReject.parent = {order: 5};
    // The start/move should occur on the original responder if new one is rejected
    config.responderStart.child = {order: 6};

    touchConfig = startConfig(three.child, [three.child, three.child], [1]);
    run(config, three, touchConfig);
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.child),
    );
  });

  it('should negotiate scroll', () => {
    // Initially nothing wants to become the responder
    let config = oneEventLoopTestConfig(three);
    config.startShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.parent = {
      order: 1,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.child = {
      order: 2,
      returnVal: false,
    };
    config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: true};
    config.responderGrant.child = {order: 4};
    config.responderStart.child = {order: 5};

    run(config, three, startConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.child),
    );

    // If the touch target is the sibling item, the negotiation should only
    // propagate to first common ancestor of current responder and sibling (so
    // the parent).
    config = oneEventLoopTestConfig(three);
    config.scrollShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.scrollShouldSetResponder.captured.parent = {
      order: 1,
      returnVal: false,
    };
    config.scrollShouldSetResponder.bubbled.parent = {
      order: 2,
      returnVal: true,
    };
    config.responderGrant.parent = {order: 3};
    config.responderTerminationRequest.child = {order: 4, returnVal: false};
    config.responderReject.parent = {order: 5};

    run(config, three, {
      topLevelType: 'topScroll',
      targetInst: getInstanceFromNode(three.parent),
      nativeEvent: {},
    });
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.child),
    );

    // Now lets let the scroll take control this time.
    config = oneEventLoopTestConfig(three);
    config.scrollShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.scrollShouldSetResponder.captured.parent = {
      order: 1,
      returnVal: false,
    };
    config.scrollShouldSetResponder.bubbled.parent = {
      order: 2,
      returnVal: true,
    };
    config.responderGrant.parent = {order: 3};
    config.responderTerminationRequest.child = {order: 4, returnVal: true};
    config.responderTerminate.child = {order: 5};

    run(config, three, {
      topLevelType: 'topScroll',
      targetInst: getInstanceFromNode(three.parent),
      nativeEvent: {},
    });
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.parent),
    );
  });

  it('should cancel correctly', () => {
    // Initially our child becomes responder
    let config = oneEventLoopTestConfig(three);
    config.startShouldSetResponder.captured.grandParent = {
      order: 0,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.parent = {
      order: 1,
      returnVal: false,
    };
    config.startShouldSetResponder.captured.child = {
      order: 2,
      returnVal: false,
    };
    config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: true};
    config.responderGrant.child = {order: 4};
    config.responderStart.child = {order: 5};

    run(config, three, startConfig(three.child, [three.child], [0]));
    expect(ResponderEventPlugin._getResponder()).toBe(
      getInstanceFromNode(three.child),
    );

    config = oneEventLoopTestConfig(three);
    config.responderEnd.child = {order: 0};
    config.responderTerminate.child = {order: 1};

    const nativeEvent = _touchConfig(
      'topTouchCancel',
      three.child,
      [three.child],
      [0],
    );
    run(config, three, nativeEvent);
    expect(ResponderEventPlugin._getResponder()).toBe(null);
  });

  it('should determine the first common ancestor correctly', () => {
    // This test was moved here from the ReactTreeTraversal test since only the
    // ResponderEventPlugin uses `getLowestCommonAncestor`
    const React = require('react');
    const ReactTestUtils = require('react-dom/test-utils');
    const getLowestCommonAncestor = require('react-native-renderer/src/legacy-events/ResponderEventPlugin')
      .getLowestCommonAncestor;
    // This works by accident and will likely break in the future.
    const ReactDOMComponentTree = require('react-dom-bindings/src/client/ReactDOMComponentTree');

    class ChildComponent extends React.Component {
      render() {
        return (
          <div ref="DIV" id={this.props.id + '__DIV'}>
            <div ref="DIV_1" id={this.props.id + '__DIV_1'} />
            <div ref="DIV_2" id={this.props.id + '__DIV_2'} />
          </div>
        );
      }
    }

    class ParentComponent extends React.Component {
      render() {
        return (
          <div ref="P" id="P">
            <div ref="P_P1" id="P_P1">
              <ChildComponent ref="P_P1_C1" id="P_P1_C1" />
              <ChildComponent ref="P_P1_C2" id="P_P1_C2" />
            </div>
            <div ref="P_OneOff" id="P_OneOff" />
          </div>
        );
      }
    }

    const parent = ReactTestUtils.renderIntoDocument(<ParentComponent />);

    const ancestors = [
      // Common ancestor with self is self.
      {
        one: parent.refs.P_P1_C1.refs.DIV_1,
        two: parent.refs.P_P1_C1.refs.DIV_1,
        com: parent.refs.P_P1_C1.refs.DIV_1,
      },
      // Common ancestor with self is self - even if topmost DOM.
      {one: parent.refs.P, two: parent.refs.P, com: parent.refs.P},
      // Siblings
      {
        one: parent.refs.P_P1_C1.refs.DIV_1,
        two: parent.refs.P_P1_C1.refs.DIV_2,
        com: parent.refs.P_P1_C1.refs.DIV,
      },
      // Common ancestor with parent is the parent.
      {
        one: parent.refs.P_P1_C1.refs.DIV_1,
        two: parent.refs.P_P1_C1.refs.DIV,
        com: parent.refs.P_P1_C1.refs.DIV,
      },
      // Common ancestor with grandparent is the grandparent.
      {
        one: parent.refs.P_P1_C1.refs.DIV_1,
        two: parent.refs.P_P1,
        com: parent.refs.P_P1,
      },
      // Grandparent across subcomponent boundaries.
      {
        one: parent.refs.P_P1_C1.refs.DIV_1,
        two: parent.refs.P_P1_C2.refs.DIV_1,
        com: parent.refs.P_P1,
      },
      // Something deep with something one-off.
      {
        one: parent.refs.P_P1_C1.refs.DIV_1,
        two: parent.refs.P_OneOff,
        com: parent.refs.P,
      },
    ];
    let i;
    for (i = 0; i < ancestors.length; i++) {
      const plan = ancestors[i];
      const firstCommon = getLowestCommonAncestor(
        ReactDOMComponentTree.getInstanceFromNode(plan.one),
        ReactDOMComponentTree.getInstanceFromNode(plan.two),
      );
      expect(firstCommon).toBe(
        ReactDOMComponentTree.getInstanceFromNode(plan.com),
      );
    }
  });
});

redpajama_set_name: RedPajamaGithub


text:
import { EventEmitter } from 'events';
import { typeByName as TYPES, Parameter, DataType } from './data-type';
import { RequestError } from './errors';

import Connection from './connection';
import { Metadata } from './metadata-parser';
import { ColumnMetadata } from './token/colmetadata-token-parser';

/**
 * The callback is called when the request has completed, either successfully or with an error.
 * If an error occurs during execution of the statement(s), then `err` will describe the error.
 *
 * As only one request at a time may be executed on a connection, another request should not
 * be initiated until this callback is called.
 *
 * This callback is called before `requestCompleted` is emitted.
 */
type CompletionCallback =
  /**
   * @param error
   *   If an error occured, an error object.
   *
   * @param rowCount
   *   The number of rows emitted as result of executing the SQL statement.
   *
   * @param rows
   *   Rows as a result of executing the SQL statement.
   *   Will only be available if [[ConnectionOptions.rowCollectionOnRequestCompletion]] is `true`.
   */
  // TODO: Figure out how to type the `rows` parameter here.
  (error: Error | null | undefined, rowCount?: number, rows?: any) => void;

interface ParameterOptions {
  output?: boolean;
  length?: number;
  precision?: number;
  scale?: number;
}

/**
 * ```js
 * const { Request } = require('tedious');
 * const request = new Request("select 42, 'hello world'", (err, rowCount) {
 *   // Request completion callback...
 * });
 * connection.execSql(request);
 * ```
 */
class Request extends EventEmitter {
  /**
   * @private
   */
  sqlTextOrProcedure?: string;
  /**
   * @private
   */
  parameters: Parameter[];
  /**
   * @private
   */
  parametersByName: { [key: string]: Parameter };
  /**
   * @private
   */
  originalParameters: Parameter[];
  /**
   * @private
   */
  preparing: boolean;
  /**
   * @private
   */
  canceled: boolean;
  /**
   * @private
   */
  paused: boolean;
  /**
   * @private
   */
  userCallback: CompletionCallback;
  /**
   * @private
   */
  handle?: number;
  /**
   * @private
   */
  error?: Error;
  /**
   * @private
   */
  connection?: Connection;
  /**
   * @private
   */
  timeout?: number;

  /**
   * @private
   */
  rows?: Array<any>;
  /**
   * @private
   */
  rst?: Array<any>;
  /**
   * @private
   */
  rowCount?: number;

  /**
   * @private
   */
  callback: CompletionCallback;

  /**
   * This event, describing result set columns, will be emitted before row
   * events are emitted. This event may be emited multiple times when more
   * than one recordset is produced by the statement.
   *
   * An array like object, where the columns can be accessed either by index
   * or name. Columns with a name that is an integer are not accessible by name,
   * as it would be interpreted as an array index.
   */
  on(
    event: 'columnMetadata',
    listener:
    (columns: ColumnMetadata[] | { [key: string]: ColumnMetadata }) => void
  ): this

  /**
   * The request has been prepared and can be used in subsequent calls to execute and unprepare.
   */
  on(event: 'prepared', listener: () => void): this

  /**
   * The request encountered an error and has not been prepared.
   */
  on(event: 'error', listener: (err: Error) => void): this

  /**
   * A row resulting from execution of the SQL statement.
   */
  on(
    event: 'row',
    listener:
      /**
       * An array or object (depends on [[ConnectionOptions.useColumnNames]]), where the columns can be accessed by index/name.
       * Each column has two properties, `metadata` and `value`:
       *
       * * `metadata`
       *
       *    The same data that is exposed in the `columnMetadata` event.
       *
       * * `value`
       *
       *    The column's value. It will be `null` for a `NULL`.
       *    If there are multiple columns with the same name, then this will be an array of the values.
       */
      (columns: any) => void
  ): this

  /**
   * All rows from a result set have been provided (through `row` events).
   *
   * This token is used to indicate the completion of a SQL statement.
   * As multiple SQL statements can be sent to the server in a single SQL batch, multiple `done` can be generated.
   * An `done` event is emited for each SQL statement in the SQL batch except variable declarations.
   * For execution of SQL statements within stored procedures, `doneProc` and `doneInProc` events are used in place of `done`.
   *
   * If you are using [[Connection.execSql]] then SQL server may treat the multiple calls with the same query as a stored procedure.
   * When this occurs, the `doneProc` and `doneInProc` events may be emitted instead. You must handle both events to ensure complete coverage.
   */
  on(
    event: 'done',
    listener:
      /**
       * @param rowCount
       *   The number of result rows. May be `undefined` if not available.
       *
       * @param more
       *   If there are more results to come (probably because multiple statements are being executed), then `true`.
       *
       * @param rst
       *   Rows as a result of executing the SQL statement.
       *   Will only be avaiable if Connection's [[ConnectionOptions.rowCollectionOnDone]] is `true`.
       */
      (rowCount: number | undefined, more: boolean, rst?: any[]) => void
  ): this

  /**
   * `request.on('doneInProc', function (rowCount, more, rows) { });`
   *
   * Indicates the completion status of a SQL statement within a stored procedure. All rows from a statement
   * in a stored procedure have been provided (through `row` events).
   *
   * This event may also occur when executing multiple calls with the same query using [[execSql]].
   */
  on(
    event: 'doneInProc',
    listener:
      /**
       * @param rowCount
       *   The number of result rows. May be `undefined` if not available.
       *
       * @param more
       *   If there are more results to come (probably because multiple statements are being executed), then `true`.
       *
       * @param rst
       *   Rows as a result of executing the SQL statement.
       *   Will only be avaiable if Connection's [[ConnectionOptions.rowCollectionOnDone]] is `true`.
       */
      (rowCount: number | undefined, more: boolean, rst?: any[]) => void
  ): this

  /**
   * Indicates the completion status of a stored procedure. This is also generated for stored procedures
   * executed through SQL statements.\
   * This event may also occur when executing multiple calls with the same query using [[execSql]].
   */
  on(
    event: 'doneProc',
    listener:
      /**
       * @param rowCount
       *   The number of result rows. May be `undefined` if not available.
       *
       * @param more
       *   If there are more results to come (probably because multiple statements are being executed), then `true`.
       *
       * @param rst
       *   Rows as a result of executing the SQL statement.
       *   Will only be avaiable if Connection's [[ConnectionOptions.rowCollectionOnDone]] is `true`.
       */
      (rowCount: number | undefined, more: boolean, procReturnStatusValue: number, rst?: any[]) => void
  ): this

  /**
   * A value for an output parameter (that was added to the request with [[addOutputParameter]]).
   * See also `Using Parameters`.
   */
  on(
    event: 'returnValue',
    listener:
      /**
       * @param parameterName
       *   The parameter name. (Does not start with '@'.)
       *
       * @param value
       *   The parameter's output value.
       *
       * @param metadata
       *   The same data that is exposed in the `columnMetaData` event.
       */
      (parameterName: string, value: unknown, metadata: Metadata) => void
  ): this

  /**
   * This event gives the columns by which data is ordered, if `ORDER BY` clause is executed in SQL Server.
   */
  on(
    event: 'order',
    listener:
      /**
       * @param orderColumns
       *   An array of column numbers in the result set by which data is ordered.
       */
      (orderColumns: number[]) => void
  ): this

  on(event: 'requestCompleted', listener: () => void): this

  on(event: 'cancel', listener: () => void): this

  on(event: string | symbol, listener: (...args: any[]) => void) {
    return super.on(event, listener);
  }

  /**
   * @private
   */
  emit(event: 'columnMetadata', columns: ColumnMetadata[] | { [key: string]: ColumnMetadata }): boolean
  /**
   * @private
   */
  emit(event: 'prepared'): boolean
  /**
   * @private
   */
  emit(event: 'error', err: Error): boolean
  /**
   * @private
   */
  emit(event: 'row', columns: any): boolean
  /**
   * @private
   */
  emit(event: 'done', rowCount: number | undefined, more: boolean, rst?: any[]): boolean
  /**
   * @private
   */
  emit(event: 'doneInProc', rowCount: number | undefined, more: boolean, rst?: any[]): boolean
  /**
   * @private
   */
  emit(event: 'doneProc', rowCount: number | undefined, more: boolean, procReturnStatusValue: number, rst?: any[]): boolean
  /**
   * @private
   */
  emit(event: 'returnValue', parameterName: string, value: unknown, metadata: Metadata): boolean
  /**
   * @private
   */
  emit(event: 'requestCompleted'): boolean
  /**
   * @private
   */
  emit(event: 'cancel'): boolean
  /**
   * @private
   */
  emit(event: 'order', orderColumns: number[]): boolean
  emit(event: string | symbol, ...args: any[]) {
    return super.emit(event, ...args);
  }

  /**
   * @param sqlTextOrProcedure
   *   The SQL statement to be executed
   *
   * @param callback
   *   The callback to execute once the request has been fully completed.
   */
  constructor(sqlTextOrProcedure: string | undefined, callback: CompletionCallback) {
    super();

    this.sqlTextOrProcedure = sqlTextOrProcedure;
    this.parameters = [];
    this.parametersByName = {};
    this.originalParameters = [];
    this.preparing = false;
    this.handle = undefined;
    this.canceled = false;
    this.paused = false;
    this.error = undefined;
    this.connection = undefined;
    this.timeout = undefined;
    this.userCallback = callback;
    this.callback = function(err: Error | undefined | null, rowCount?: number, rows?: any) {
      if (this.preparing) {
        this.preparing = false;
        if (err) {
          this.emit('error', err);
        } else {
          this.emit('prepared');
        }
      } else {
        this.userCallback(err, rowCount, rows);
        this.emit('requestCompleted');
      }
    };
  }

  /**
   * @param name
   *   The parameter name. This should correspond to a parameter in the SQL,
   *   or a parameter that a called procedure expects. The name should not start with `@`.
   *
   * @param type
   *   One of the supported data types.
   *
   * @param value
   *   The value that the parameter is to be given. The Javascript type of the
   *   argument should match that documented for data types.
   *
   * @param options
   *   Additional type options. Optional.
   */
  // TODO: `type` must be a valid TDS value type
  addParameter(name: string, type: DataType, value: unknown, options?: ParameterOptions) {
    if (options == null) {
      options = {};
    }

    const { output = false, length, precision, scale } = options;

    const parameter: Parameter = {
      type: type,
      name: name,
      value: value,
      output: output,
      length: length,
      precision: precision,
      scale: scale
    };
    this.parameters.push(parameter);
    this.parametersByName[name] = parameter;
  }

  /**
   * @param name
   *   The parameter name. This should correspond to a parameter in the SQL,
   *   or a parameter that a called procedure expects.
   *
   * @param type
   *   One of the supported data types.
   *
   * @param value
   *   The value that the parameter is to be given. The Javascript type of the
   *   argument should match that documented for data types
   *
   * @param options
   *   Additional type options. Optional.
   */
  addOutputParameter(name: string, type: DataType, value?: unknown, options?: ParameterOptions) {
    if (options == null) {
      options = {};
    }
    options.output = true;
    this.addParameter(name, type, value, options);
  }

  /**
   * @private
   */
  makeParamsParameter(parameters: Parameter[]) {
    let paramsParameter = '';
    for (let i = 0, len = parameters.length; i < len; i++) {
      const parameter = parameters[i];
      if (paramsParameter.length > 0) {
        paramsParameter += ', ';
      }
      paramsParameter += '@' + parameter.name + ' ';
      paramsParameter += parameter.type.declaration(parameter);
      if (parameter.output) {
        paramsParameter += ' OUTPUT';
      }
    }
    return paramsParameter;
  }

  /**
   * @private
   */
  transformIntoExecuteSqlRpc() {
    if (this.validateParameters()) {
      return;
    }

    this.originalParameters = this.parameters;
    this.parameters = [];
    this.addParameter('statement', TYPES.NVarChar, this.sqlTextOrProcedure);
    if (this.originalParameters.length) {
      this.addParameter('params', TYPES.NVarChar, this.makeParamsParameter(this.originalParameters));
    }

    for (let i = 0, len = this.originalParameters.length; i < len; i++) {
      const parameter = this.originalParameters[i];
      this.parameters.push(parameter);
    }
    this.sqlTextOrProcedure = 'sp_executesql';
  }

  /**
   * @private
   */
  transformIntoPrepareRpc() {
    this.originalParameters = this.parameters;
    this.parameters = [];
    this.addOutputParameter('handle', TYPES.Int, undefined);
    this.addParameter('params', TYPES.NVarChar, this.makeParamsParameter(this.originalParameters));
    this.addParameter('stmt', TYPES.NVarChar, this.sqlTextOrProcedure);
    this.sqlTextOrProcedure = 'sp_prepare';
    this.preparing = true;
    this.on('returnValue', (name: string, value: any) => {
      if (name === 'handle') {
        this.handle = value;
      } else {
        this.error = RequestError(`Tedious > Unexpected output parameter ${name} from sp_prepare`);
      }
    });
  }

  /**
   * @private
   */
  transformIntoUnprepareRpc() {
    this.parameters = [];
    this.addParameter('handle', TYPES.Int, this.handle);
    this.sqlTextOrProcedure = 'sp_unprepare';
  }

  /**
   * @private
   */
  transformIntoExecuteRpc(parameters: { [key: string]: unknown }) {
    this.parameters = [];
    this.addParameter('handle', TYPES.Int, this.handle);

    for (let i = 0, len = this.originalParameters.length; i < len; i++) {
      const parameter = this.originalParameters[i];
      parameter.value = parameters[parameter.name];
      this.parameters.push(parameter);
    }

    if (this.validateParameters()) {
      return;
    }

    this.sqlTextOrProcedure = 'sp_execute';
  }

  /**
   * @private
   */
  validateParameters() {
    for (let i = 0, len = this.parameters.length; i < len; i++) {
      const parameter = this.parameters[i];
      const value = parameter.type.validate(parameter.value);
      if (value instanceof TypeError) {
        return this.error = new RequestError('Validation failed for parameter \'' + parameter.name + '\'. ' + value.message, 'EPARAM');
      }
      parameter.value = value;
    }
    return null;
  }

  /**
   * Temporarily suspends the flow of data from the database. No more `row` events will be emitted until [[resume] is called.
   * If this request is already in a paused state, calling [[pause]] has no effect.
   */
  pause() {
    if (this.paused) {
      return;
    }
    this.paused = true;
    if (this.connection) {
      this.connection.pauseRequest(this);
    }
  }

  /**
   * Resumes the flow of data from the database.
   * If this request is not in a paused state, calling [[resume]] has no effect.
   */
  resume() {
    if (!this.paused) {
      return;
    }
    this.paused = false;
    if (this.connection) {
      this.connection.resumeRequest(this);
    }
  }

  /**
   * Cancels a request while waiting for a server response.
   */
  cancel() {
    if (this.canceled) {
      return;
    }

    this.canceled = true;
    this.emit('cancel');
  }

  /**
   * Sets a timeout for this request.
   *
   * @param timeout
   *   The number of milliseconds before the request is considered failed,
   *   or `0` for no timeout. When no timeout is set for the request,
   *   the [[ConnectionOptions.requestTimeout]] of the [[Connection]] is used.
   */
  setTimeout(timeout?: number) {
    this.timeout = timeout;
  }
}

export default Request;
module.exports = Request;


text:
namespace Caps.Data.Migrations
{
    using System.Data.Entity.Migrations;
    using System.Data.Entity.Migrations.Infrastructure;
    using System.Resources;

    public sealed partial class AddTags : IMigrationMetadata
    {
        private readonly ResourceManager Resources = new ResourceManager(typeof(AddTags));

        string IMigrationMetadata.Id
        {
            get { return "201309111442207_AddTags"; }
        }

        string IMigrationMetadata.Source
        {
            get { return null; }
        }

        string IMigrationMetadata.Target
        {
            get { return Resources.GetString("Target"); }
        }
    }
}


text:
<?php

namespace wcmf\lib\security\impl;

use wcmf\lib\config\ActionKey;
use wcmf\lib\core\LogManager;
use wcmf\lib\core\Session;
use wcmf\lib\persistence\ObjectId;
use wcmf\lib\persistence\PersistenceAction;
use wcmf\lib\persistence\PersistenceFacade;
use wcmf\lib\security\PermissionManager;
use wcmf\lib\security\principal\User;
use wcmf\lib\security\principal\impl\AnonymousUser;
use wcmf\lib\security\principal\PrincipalFactory;
use wcmf\lib\util\StringUtil;

/**
 * AbstractPermissionManager is the base class for concrete PermissionManager
 * implementations.
 *
 * @author ingo herwig <ingo@wemove.com>
 */
abstract class AbstractPermissionManager implements PermissionManager {

  const RESOURCE_TYPE_ENTITY_TYPE = 'entity.type';
  const RESOURCE_TYPE_ENTITY_TYPE_PROPERTY = 'entity.type.property';
  const RESOURCE_TYPE_ENTITY_INSTANCE = 'entity.instance';
  const RESOURCE_TYPE_ENTITY_INSTANCE_PROPERTY = 'entity.instance.property';
  const RESOURCE_TYPE_OTHER = 'other';

  private $tempPermissions = [];
  private $tempPermissionIndex = 0;

  private static $logger = null;

  protected $persistenceFacade = null;
  protected $session = null;
  protected $dynamicRoles = [];
  protected $principalFactory = null;

  /**
   * Constructor
   * @param $persistenceFacade
   * @param $session
   */
  public function __construct(PersistenceFacade $persistenceFacade,
          Session $session,
          array $dynamicRoles=[]) {
    $this->persistenceFacade = $persistenceFacade;
    $this->session = $session;
    if (self::$logger == null) {
      self::$logger = LogManager::getLogger(__CLASS__);
    }
    $this->dynamicRoles = $dynamicRoles;
  }

  /**
   * Set the principal factory instances.
   * @param $principalFactory
   */
  public function setPrincipalFactory(PrincipalFactory $principalFactory) {
    $this->principalFactory = $principalFactory;
  }

  /**
   * @see PermissionManager::authorize()
   */
  public function authorize($resource, $context, $action, $login=null, $applyDefaultPolicy=true) {
    // get authenticated user, if no user is given
    if ($login == null) {
      $login = $this->session->getAuthUser();
    }
    if (self::$logger->isDebugEnabled()) {
      self::$logger->debug("Checking authorization for: '$resource?$context?$action' and user '".$login."'");
    }

    // normalize resource to string
    $resourceStr = ($resource instanceof ObjectId) ? $resource->__toString() : $resource;

    // determine the resource type and set entity type, oid and property if applicable
    $resourceDesc = $this->parseResource($resourceStr);
    $resourceType = $resourceDesc['resourceType'];
    $oid = $resourceDesc['oid'];
    $type = $resourceDesc['type'];
    $oidProperty = $resourceDesc['oidProperty'];
    $typeProperty = $resourceDesc['typeProperty'];
    if (self::$logger->isDebugEnabled()) {
      self::$logger->debug("Resource type: ".$resourceType);
    }

    // proceed by authorizing type depending resource
    // always start checking from most specific
    switch ($resourceType) {
      case (self::RESOURCE_TYPE_ENTITY_INSTANCE_PROPERTY):
        $authorized = $this->authorizeAction($oidProperty, $oidProperty, $context, $action, $login);
        if ($authorized === null) {
          $authorized = $this->authorizeAction($oidProperty, $typeProperty, $context, $action, $login);
          if ($authorized === null) {
            $authorized = $this->authorizeAction($oidProperty, $oid, $context, $action, $login);
            if ($authorized === null) {
              $authorized = $this->authorizeAction($oidProperty, $type, $context, $action, $login);
            }
          }
        }
        break;

      case (self::RESOURCE_TYPE_ENTITY_INSTANCE):
        $authorized = $this->authorizeAction($oid, $oid, $context, $action, $login);
        if ($authorized === null) {
          $authorized = $this->authorizeAction($oid, $type, $context, $action, $login);
        }
        break;

      case (self::RESOURCE_TYPE_ENTITY_TYPE_PROPERTY):
        $authorized = $this->authorizeAction($typeProperty, $typeProperty, $context, $action, $login);
        if ($authorized === null) {
          $authorized = $this->authorizeAction($typeProperty, $type, $context, $action, $login);
        }
        break;

      default:
        $authorized = $this->authorizeAction($resourceStr, $resourceStr, $context, $action, $login);
        break;
    }

    // check parent entities in composite relations
    if ($authorized === null && $resourceType == self::RESOURCE_TYPE_ENTITY_INSTANCE) {
      if (self::$logger->isDebugEnabled()) {
        self::$logger->debug("Check parent objects");
      }
      $mapper = $this->persistenceFacade->getMapper($type);
      $parentRelations = $mapper->getRelations('parent');
      if (sizeof($parentRelations) > 0) {

        $oidObj = ObjectId::parse($oid);
        $tmpPerm = $this->addTempPermission($oidObj, $context, PersistenceAction::READ);
        $object = $this->persistenceFacade->load($oidObj);
        $this->removeTempPermission($tmpPerm);

        if ($object != null) {
          foreach ($parentRelations as $parentRelation) {
            if ($parentRelation->getThisAggregationKind() == 'composite') {
              $parentType = $parentRelation->getOtherType();

              $tmpPerm = $this->addTempPermission($parentType, $context, PersistenceAction::READ);
              $parents = $object->getValue($parentRelation->getOtherRole());
              $this->removeTempPermission($tmpPerm);

              if ($parents != null) {
                if (!$parentRelation->isMultiValued()) {
                  $parents = [$parents];
                }
                foreach ($parents as $parent) {
                  $authorized = $this->authorize($parent->getOID(), $context, $action);
                  if (!$authorized) {
                    break;
                  }
                }
              }
            }
          }
        }
      }
    }

    if ($authorized === null && $applyDefaultPolicy) {
      $authorized = $this->getDefaultPolicy($login);
    }
    if (self::$logger->isDebugEnabled()) {
      self::$logger->debug("Result for $resource?$context?$action: ".(!$authorized ? "not " : "")."authorized");
    }

    return $authorized;
  }

  /**
   * Authorize a resource, context, action triple by using the permissions set
   * on another resource (e.g. authorize an action on an entity instance base
   * on the permissions defined for it's type).
   * @param $requestedResource The resource string to authorize.
   * @param $permissionResource The resource string to use for selecting permissions.
   * @param $context The context in which the action takes place.
   * @param $action The action to process.
   * @param $login The login of the user to use for authorization
   * @return Boolean or null if undefined
   */
  protected function authorizeAction($requestedResource, $permissionResource,
          $context, $action, $login) {
    if (self::$logger->isDebugEnabled()) {
      self::$logger->debug("Authorizing $requestedResource?$context?$action ".
              "using permissions of $permissionResource?$context?$action");
    }
    $authorized = null;

    // check temporary permissions
    if ($this->hasTempPermission($permissionResource, $context, $action)) {
      if (self::$logger->isDebugEnabled()) {
        self::$logger->debug("Has temporary permission");
      }
      $authorized = true;
    }
    else {
      // check other permissions
      $permissions = $this->getPermissions($permissionResource, $context, $action);
      if (self::$logger->isDebugEnabled()) {
        self::$logger->debug("Permissions: ".StringUtil::getDump($permissions));
      }
      if ($permissions != null) {
        // matching permissions found, check user roles
        $authorized = $this->matchRoles($requestedResource, $permissions, $login);
      }
    }
    if (self::$logger->isDebugEnabled()) {
      self::$logger->debug("Result: ".(is_bool($authorized) ? ((!$authorized ? "not " : "")."authorized") : "not defined"));
    }
    return $authorized;
  }

  /**
   * Get the default policy that is used if no permission is set up
   * for a requested action.
   * @param $login The login of the user to get the default policy for
   * @return Boolean
   */
  protected function getDefaultPolicy($login) {
    return ($login == AnonymousUser::USER_GROUP_NAME) ? false : true;
  }

  /**
   * Get the resource type and parameters (as applicable) from a resource
   * @param $resource The resource represented as string
   * @return Associative array with keys
   *   'resourceType' (one of the RESOURCE_TYPE_ constants),
   *   'oid' (object id),
   *   'type' (entity type),
   *   'oidProperty' (object id with instance property),
   *   'typeProperty' (type id with entity property)
   */
  protected function parseResource($resource) {
    $resourceType = null;
    $oid = null;
    $type = null;
    $oidProperty = null;
    $typeProperty = null;
    $extensionRemoved = preg_replace('/\.[^\.]*?$/', '', $resource);
    if (($oidObj = ObjectId::parse($resource)) !== null) {
      $resourceType = self::RESOURCE_TYPE_ENTITY_INSTANCE;
      $oid = $resource;
      $type = $oidObj->getType();
    }
    elseif (($oidObj = ObjectId::parse($extensionRemoved)) !== null) {
      $resourceType = self::RESOURCE_TYPE_ENTITY_INSTANCE_PROPERTY;
      $oid = $extensionRemoved;
      $type = $oidObj->getType();
      $oidProperty = $resource;
      $typeProperty = $type.substr($resource, strlen($extensionRemoved));
    }
    elseif ($this->persistenceFacade->isKnownType($resource)) {
      $resourceType = self::RESOURCE_TYPE_ENTITY_TYPE;
      $type = $resource;
    }
    elseif ($this->persistenceFacade->isKnownType($extensionRemoved)) {
      $resourceType = self::RESOURCE_TYPE_ENTITY_TYPE_PROPERTY;
      $type = $extensionRemoved;
      $typeProperty = $resource;
    }
    else {
      // defaults to other
      $resourceType = self::RESOURCE_TYPE_OTHER;
    }
    return [
      'resourceType' => $resourceType,
      'oid' => $oid,
      'type' => $type,
      'oidProperty' => $oidProperty,
      'typeProperty' => $typeProperty
    ];
  }

  /**
   * Parse a permissions string and return an associative array with the keys
   * 'default', 'allow', 'deny', where 'allow', 'deny' are arrays itself holding roles
   * and 'default' is a boolean value derived from the wildcard policy (+* or -*).
   * @param $value A role string (+*, +administrators, -guest, entries without '+' or '-'
   *     prefix default to allow rules).
   * @return Associative array containing the permissions as an associative array with the keys
   *     'default', 'allow', 'deny' or null, if value is empty
   */
  protected function deserializePermissions($value) {
    if (strlen($value) == 0) {
      return null;
    }
    $result = [
      'default' => null,
      'allow' => [],
      'deny' => [],
    ];

    $roleValues = explode(" ", $value);
    foreach ($roleValues as $roleValue) {
      $roleValue = trim($roleValue);
      $matches = [];
      preg_match('/^([+-]?)(.+)$/', $roleValue, $matches);
      if (sizeof($matches) > 0) {
        $prefix = $matches[1];
        $role = $matches[2];
        if ($role === '*') {
          $result['default'] = $prefix == '-' ? false : true;
        }
        else {
          if ($prefix === '-') {
            $result['deny'][] = $role;
          }
          else {
            // entries without '+' or '-' prefix default to allow rules
            $result['allow'][] = $role;
          }
        }
      }
    }
    // if no wildcard policy is defined, set default to false
    if (!isset($result['default'])) {
      $result['default'] = false;
    }
    return $result;
  }

  /**
   * Convert an associative permissions array with keys 'default', 'allow', 'deny'
   * into a string.
   * @param $permissions Associative array with keys 'default', 'allow', 'deny',
   *     where 'allow', 'deny' are arrays itself holding roles and 'default' is a
   *     boolean value derived from the wildcard policy (+* or -*).
   * @return A role string (+*, +administrators, -guest, entries without '+' or '-'
   *     prefix default to allow rules).
   */
  protected function serializePermissions($permissions) {
    $result = $permissions['default'] === true ? PermissionManager::PERMISSION_MODIFIER_ALLOW.'* ' :
        PermissionManager::PERMISSION_MODIFIER_DENY.'* ';
    if (isset($permissions['allow'])) {
      foreach ($permissions['allow'] as $role) {
        $result .= PermissionManager::PERMISSION_MODIFIER_ALLOW.$role.' ';
      }
    }
    if (isset($permissions['deny'])) {
      foreach ($permissions['deny'] as $role) {
        $result .= PermissionManager::PERMISSION_MODIFIER_DENY.$role.' ';
      }
    }
    return trim($result);
  }

  /**
   * Matches the roles of the user and the roles in the given permissions
   * @param $resource The resource string to authorize.
   * @param $permissions An array containing permissions as an associative array
   *     with the keys 'default', 'allow', 'deny', where 'allow', 'deny' are arrays
   *     itself holding roles and 'default' is a boolean value derived from the
   *     wildcard policy (+* or -*). 'allow' overwrites 'deny' overwrites 'default'
   * @param $login the login of the user to match the roles for
   * @return Boolean whether the user is authorized according to the permissions
   */
  protected function matchRoles($resource, $permissions, $login) {
    if (self::$logger->isDebugEnabled()) {
      self::$logger->debug("Matching roles for ".$login);
    }
    $user = $this->principalFactory->getUser($login, true);
    if ($user != null) {
      foreach (['allow' => true, 'deny' => false] as $key => $result) {
        if (isset($permissions[$key])) {
          foreach ($permissions[$key] as $role) {
            if ($this->matchRole($user, $role, $resource)) {
              if (self::$logger->isDebugEnabled()) {
                self::$logger->debug($key." because of role ".$role);
              }
              return $result;
            }
          }
        }
      }
    }
    if (self::$logger->isDebugEnabled()) {
      self::$logger->debug("Check default ".$permissions['default']);
    }
    return (isset($permissions['default']) ? $permissions['default'] : false);
  }

  /**
   * Check if a user matches the role for a resource
   * @param $user The user instance.
   * @param $role The role name.
   * @param $resource The resource string to authorize.
   * @return Boolean
   */
  protected function matchRole(User $user, $role, $resource) {
    $isDynamicRole = isset($this->dynamicRoles[$role]);
    return (($isDynamicRole && $this->dynamicRoles[$role]->match($user, $resource) === true)
            || (!$isDynamicRole && $user->hasRole($role)));
  }

  /**
   * @see PermissionManager::addTempPermission()
   */
  public function addTempPermission($resource, $context, $action) {
    $this->tempPermissionIndex++;
    $actionKey = ActionKey::createKey($resource, $context, $action);
    if (self::$logger->isDebugEnabled()) {
      self::$logger->debug("Adding temporary permission for '$actionKey'");
    }
    $handle = $actionKey.'#'.$this->tempPermissionIndex;
    $this->tempPermissions[$handle] = $actionKey;
    return $handle;
  }

  /**
   * @see PermissionManager::removeTempPermission()
   */
  public function removeTempPermission($handle) {
    if (self::$logger->isDebugEnabled()) {
      self::$logger->debug("Removing temporary permission for '$handle'");
    }
    unset($this->tempPermissions[$handle]);
  }

  /**
   * @see PermissionManager::hasTempPermission()
   */
  public function hasTempPermission($resource, $context, $action) {
    if (sizeof($this->tempPermissions) == 0) {
      return false;
    }

    // check if the resource has a direct permission
    $permissions = array_flip($this->tempPermissions);
    $actionKey = ActionKey::createKey($resource, $context, $action);
    if (!isset($permissions[$actionKey])) {
      // if not and the resource belongs to an entity instance,
      // we might have a permission for the type
      $resourceDesc = $this->parseResource($resource);
      switch ($resourceDesc['resourceType']) {
        case self::RESOURCE_TYPE_ENTITY_INSTANCE:
          $typeResource = $resourceDesc['type'];
          break;
        case self::RESOURCE_TYPE_ENTITY_INSTANCE_PROPERTY:
          $typeResource = $resourceDesc['typeProperty'];
          break;
        default:
          $typeResource = null;
      }
      // set alternative action key
      if ($typeResource != null) {
        $actionKey = ActionKey::createKey($typeResource, $context, $action);
      }
    }
    return isset($permissions[$actionKey]);
  }

  /**
   * @see PermissionManager::clearTempPermissions()
   */
  public function clearTempPermissions() {
    $this->tempPermissions = [];
  }
}
?>


text:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="electroscholars.com.diylinefollowerrobot.SensorViewActivity">

    <WebView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/sensorWebView"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true" />
</RelativeLayout>


text:
package org.apache.syncope.common.lib;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.SchemaType;

@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Schema {

    SchemaType[] type() default { SchemaType.PLAIN };

    AnyTypeKind anyTypeKind() default AnyTypeKind.USER;
}


text:
package org.wikipedia.readinglist.page.database.disk;

import android.support.annotation.NonNull;

import org.wikipedia.database.DatabaseClient;
import org.wikipedia.database.async.AsyncDao;

import java.util.Collection;

public class DiskRowDao<Dat, Row extends DiskRow<Dat>> extends AsyncDao<DiskStatus, Dat, Row> {
    public DiskRowDao(@NonNull DatabaseClient<Row> client) {
        super(client);
    }

    public synchronized void markOnline(@NonNull Row row) {
        Row query = queryPrimaryKey(row);
        switch (query == null ? DiskStatus.SAVED : query.status()) {
            case SAVED:
            case OUTDATED:
            case DELETED:
                resetTransaction(row, DiskStatus.UNSAVED);
                break;
            case ONLINE:
            case UNSAVED:
                break;
            default:
                throw new RuntimeException("status=" + row.status());
        }
    }

    public synchronized void markOutdated(@NonNull Row row) {
        Row query = queryPrimaryKey(row);
        switch (query == null ? DiskStatus.ONLINE : query.status()) {
            case ONLINE:
            case SAVED:
            case UNSAVED:
            case DELETED:
                resetTransaction(row, DiskStatus.OUTDATED);
                break;
            case OUTDATED:
                break;
            default:
                throw new RuntimeException("status=" + row.status());
        }
    }

    public synchronized void markDeleted(@NonNull Row row) {
        Row query = queryPrimaryKey(row);
        switch (query == null ? DiskStatus.DELETED : query.status()) {
            case ONLINE:
            case SAVED:
            case OUTDATED:
            case UNSAVED:
                resetTransaction(row, DiskStatus.DELETED);
                break;
            case DELETED:
                break;
            default:
                throw new RuntimeException("status=" + row.status());
        }
    }

    @Override public synchronized boolean completeTransaction(@NonNull Row row, long timestamp) {
        if (super.completeTransaction(row, timestamp)) {
            if (row.status() == DiskStatus.DELETED) {
                delete(row);
            } else {
                upsert(row);
            }
            return true;
        }
        return false;
    }

    @Override public synchronized void clear() {
        final String selection = null;
        final String[] selectionArgs = null;
        Collection<Row> rows = query(selection, selectionArgs);
        for (Row row : rows) {
            delete(row);
        }
    }
}