text: /**
   * Copyright 2013-2015, Facebook, Inc.
   * All rights reserved.
   *
   * This source code is licensed under the BSD-style license found in the
   * LICENSE file in the root directory of this source tree. An additional grant
   * of patent rights can be found in the PATENTS file in the same directory.
   *
   * @providesModule ReactChildren
   */
  
  'use strict';
  
  var PooledClass = require('PooledClass');
  var ReactFragment = require('ReactFragment');
  
  var traverseAllChildren = require('traverseAllChildren');
  var warning = require('warning');
  
  var twoArgumentPooler = PooledClass.twoArgumentPooler;
  var threeArgumentPooler = PooledClass.threeArgumentPooler;
  
  /**
   * PooledClass representing the bookkeeping associated with performing a child
   * traversal. Allows avoiding binding callbacks.
   *
   * @constructor ForEachBookKeeping
   * @param {!function} forEachFunction Function to perform traversal with.
   * @param {?*} forEachContext Context to perform context with.
   */
  function ForEachBookKeeping(forEachFunction, forEachContext) {
    this.forEachFunction = forEachFunction;
    this.forEachContext = forEachContext;
  }
  PooledClass.addPoolingTo(ForEachBookKeeping, twoArgumentPooler);
  
  function forEachSingleChild(traverseContext, child, name, i) {
    var forEachBookKeeping = traverseContext;
    forEachBookKeeping.forEachFunction.call(
      forEachBookKeeping.forEachContext, child, i);
  }
  
  /**
   * Iterates through children that are typically specified as `props.children`.
   *
   * The provided forEachFunc(child, index) will be called for each
   * leaf child.
   *
   * @param {?*} children Children tree container.
   * @param {function(*, int)} forEachFunc.
   * @param {*} forEachContext Context for forEachContext.
   */
  function forEachChildren(children, forEachFunc, forEachContext) {
    if (children == null) {
      return children;
    }
  
    var traverseContext =
      ForEachBookKeeping.getPooled(forEachFunc, forEachContext);
    traverseAllChildren(children, forEachSingleChild, traverseContext);
    ForEachBookKeeping.release(traverseContext);
  }
  
  /**
   * PooledClass representing the bookkeeping associated with performing a child
   * mapping. Allows avoiding binding callbacks.
   *
   * @constructor MapBookKeeping
   * @param {!*} mapResult Object containing the ordered map of results.
   * @param {!function} mapFunction Function to perform mapping with.
   * @param {?*} mapContext Context to perform mapping with.
   */
  function MapBookKeeping(mapResult, mapFunction, mapContext) {
    this.mapResult = mapResult;
    this.mapFunction = mapFunction;
    this.mapContext = mapContext;
  }
  PooledClass.addPoolingTo(MapBookKeeping, threeArgumentPooler);
  
  function mapSingleChildIntoContext(traverseContext, child, name, i) {
    var mapBookKeeping = traverseContext;
    var mapResult = mapBookKeeping.mapResult;
  
    var keyUnique = (mapResult[name] === undefined);
    if (__DEV__) {
      warning(
        keyUnique,
        'ReactChildren.map(...): Encountered two children with the same key, ' +
        '`%s`. Child keys must be unique; when two children share a key, only ' +
        'the first child will be used.',
        name
      );
    }
  
    if (keyUnique) {
      var mappedChild =
        mapBookKeeping.mapFunction.call(mapBookKeeping.mapContext, child, i);
      mapResult[name] = mappedChild;
    }
  }
  
  /**
   * Maps children that are typically specified as `props.children`.
   *
   * The provided mapFunction(child, key, index) will be called for each
   * leaf child.
   *
   * TODO: This may likely break any calls to `ReactChildren.map` that were
   * previously relying on the fact that we guarded against null children.
   *
   * @param {?*} children Children tree container.
   * @param {function(*, int)} mapFunction.
   * @param {*} mapContext Context for mapFunction.
   * @return {object} Object containing the ordered map of results.
   */
  function mapChildren(children, func, context) {
    if (children == null) {
      return children;
    }
  
    var mapResult = {};
    var traverseContext = MapBookKeeping.getPooled(mapResult, func, context);
    traverseAllChildren(children, mapSingleChildIntoContext, traverseContext);
    MapBookKeeping.release(traverseContext);
    return ReactFragment.create(mapResult);
  }
  
  function forEachSingleChildDummy(traverseContext, child, name, i) {
    return null;
  }
  
  /**
   * Count the number of children that are typically specified as
   * `props.children`.
   *
   * @param {?*} children Children tree container.
   * @return {number} The number of children.
   */
  function countChildren(children, context) {
    return traverseAllChildren(children, forEachSingleChildDummy, null);
  }
  
  var ReactChildren = {
    forEach: forEachChildren,
    map: mapChildren,
    count: countChildren
  };
  
  module.exports = ReactChildren;
  