'use strict';

var _ = require('lodash'),
    util = require('./util'),
    Hash = util.Hash;

/*----------------------------------------------------------------------------*/

/** Used to map aliases to their real names. */
exports.aliasToReal = new Hash({
  'commit': 'wrapperCommit',
  'each': 'forEach',
  'eachRight': 'forEachRight',
  'entries': 'toPairs',
  'entriesIn': 'toPairsIn',
  'extend': 'assignIn',
  'extendWith': 'assignInWith',
  'first': 'head',
  'next': 'wrapperNext',
  'plant': 'wrapperPlant',
  'toIterator': 'wrapperToIterator',
  'toJSON': 'wrapperValue',
  'valueOf': 'wrapperValue',
  'value': 'wrapperValue',
  'wrapperLodash': 'lodash'
});

/** Used to track the category of identifiers. */
exports.category = new Hash({
  'Array': [
    'chunk',
    'compact',
    'concat',
    'difference',
    'differenceBy',
    'differenceWith',
    'drop',
    'dropRight',
    'dropRightWhile',
    'dropWhile',
    'fill',
    'findIndex',
    'findLastIndex',
    'flatten',
    'flattenDeep',
    'flattenDepth',
    'fromPairs',
    'head',
    'indexOf',
    'initial',
    'intersection',
    'intersectionBy',
    'intersectionWith',
    'join',
    'last',
    'lastIndexOf',
    'nth',
    'pull',
    'pullAll',
    'pullAllBy',
    'pullAllWith',
    'pullAt',
    'remove',
    'reverse',
    'slice',
    'sortedIndex',
    'sortedIndexBy',
    'sortedIndexOf',
    'sortedLastIndex',
    'sortedLastIndexBy',
    'sortedLastIndexOf',
    'sortedUniq',
    'sortedUniqBy',
    'tail',
    'take',
    'takeRight',
    'takeRightWhile',
    'takeWhile',
    'union',
    'unionBy',
    'unionWith',
    'uniq',
    'uniqBy',
    'uniqWith',
    'unzip',
    'unzipWith',
    'without',
    'xor',
    'xorBy',
    'xorWith',
    'zip',
    'zipObject',
    'zipObjectDeep',
    'zipWith'
  ],
  'Collection': [
    'countBy',
    'every',
    'filter',
    'find',
    'findLast',
    'flatMap',
    'flatMapDeep',
    'flatMapDepth',
    'forEach',
    'forEachRight',
    'groupBy',
    'includes',
    'invokeMap',
    'keyBy',
    'map',
    'orderBy',
    'partition',
    'reduce',
    'reduceRight',
    'reject',
    'sample',
    'sampleSize',
    'shuffle',
    'size',
    'some',
    'sortBy'
  ],
  'Date': [
    'now'
  ],
  'Function': [
    'after',
    'ary',
    'before',
    'bind',
    'bindKey',
    'curry',
    'curryRight',
    'debounce',
    'defer',
    'delay',
    'flip',
    'memoize',
    'negate',
    'once',
    'overArgs',
    'partial',
    'partialRight',
    'rearg',
    'rest',
    'spread',
    'throttle',
    'unary',
    'wrap'
  ],
  'Lang': [
    'castArray',
    'clone',
    'cloneDeep',
    'cloneDeepWith',
    'cloneWith',
    'conformsTo',
    'eq',
    'gt',
    'gte',
    'isArguments',
    'isArray',
    'isArrayBuffer',
    'isArrayLike',
    'isArrayLikeObject',
    'isBoolean',
    'isBuffer',
    'isDate',
    'isElement',
    'isEmpty',
    'isEqual',
    'isEqualWith',
    'isError',
    'isFinite',
    'isFunction',
    'isInteger',
    'isLength',
    'isMap',
    'isMatch',
    'isMatchWith',
    'isNaN',
    'isNative',
    'isNil',
    'isNull',
    'isNumber',
    'isObject',
    'isObjectLike',
    'isPlainObject',
    'isRegExp',
    'isSafeInteger',
    'isSet',
    'isString',
    'isSymbol',
    'isTypedArray',
    'isUndefined',
    'isWeakMap',
    'isWeakSet',
    'lt',
    'lte',
    'toArray',
    'toFinite',
    'toInteger',
    'toLength',
    'toNumber',
    'toPlainObject',
    'toSafeInteger',
    'toString'
  ],
  'Math': [
    'add',
    'ceil',
    'divide',
    'floor',
    'max',
    'maxBy',
    'mean',
    'meanBy',
    'min',
    'minBy',
    'multiply',
    'round',
    'subtract',
    'sum',
    'sumBy'
  ],
  'Number': [
    'clamp',
    'random',
    'inRange'
  ],
  'Object': [
    'assign',
    'assignIn',
    'assignInWith',
    'assignWith',
    'at',
    'create',
    'defaults',
    'defaultsDeep',
    'findKey',
    'findLastKey',
    'forIn',
    'forInRight',
    'forOwn',
    'forOwnRight',
    'functions',
    'functionsIn',
    'get',
    'has',
    'hasIn',
    'invert',
    'invertBy',
    'invoke',
    'keys',
    'keysIn',
    'mapKeys',
    'mapValues',
    'merge',
    'mergeWith',
    'omit',
    'omitBy',
    'pick',
    'pickBy',
    'result',
    'set',
    'setWith',
    'toPairs',
    'toPairsIn',
    'transform',
    'unset',
    'update',
    'updateWith',
    'values',
    'valuesIn'
  ],
  'Seq': [
    'chain',
    'lodash',
    'tap',
    'thru',
    'wrapperAt',
    'wrapperChain',
    'wrapperCommit',
    'wrapperNext',
    'wrapperPlant',
    'wrapperReverse',
    'wrapperToIterator',
    'wrapperValue'
  ],
  'String': [
    'camelCase',
    'capitalize',
    'deburr',
    'endsWith',
    'escape',
    'escapeRegExp',
    'kebabCase',
    'lowerCase',
    'lowerFirst',
    'pad',
    'padEnd',
    'padStart',
    'parseInt',
    'repeat',
    'replace',
    'snakeCase',
    'split',
    'startCase',
    'startsWith',
    'template',
    'templateSettings',
    'toLower',
    'toUpper',
    'trim',
    'trimEnd',
    'trimStart',
    'truncate',
    'unescape',
    'upperCase',
    'upperFirst',
    'words'
  ],
  'Util': [
    'attempt',
    'bindAll',
    'cond',
    'conforms',
    'constant',
    'defaultTo',
    'flow',
    'flowRight',
    'identity',
    'iteratee',
    'matches',
    'matchesProperty',
    'method',
    'methodOf',
    'mixin',
    'noConflict',
    'noop',
    'nthArg',
    'over',
    'overEvery',
    'overSome',
    'property',
    'propertyOf',
    'range',
    'rangeRight',
    'runInContext',
    'stubArray',
    'stubFalse',
    'stubObject',
    'stubString',
    'stubTrue',
    'times',
    'toPath',
    'uniqueId'
  ]
});

/* Used to map categories to their dependency name. */
exports.categoryToDepName = new Hash({
  'Array': 'array',
  'Collection': 'collection',
  'Date': 'date',
  'Function': 'func',
  'Lang': 'lang',
  'Math': 'math',
  'Number': 'number',
  'Object': 'object',
  'Seq': 'seq',
  'String': 'string',
  'Util': 'util'
});

/* Used to force referencing identifers by their alias. */
exports.forceAlias = new Hash({
  'lodash': 'wrapperLodash',
  'wrapperCommit': 'commit',
  'wrapperNext': 'next',
  'wrapperPlant': 'plant',
  'wrapperToIterator': 'toIterator'
});

/** Used to track function dependencies. */
exports.funcDep = new Hash({

  // Dependencies of variables.
  'metaMap': ['WeakMap'],

  // Dependencies of built-ins.
  'DataView': ['getNative'],
  'Map': ['getNative'],
  'Promise': ['getNative'],
  'Set': ['getNative'],
  'Symbol': [],
  'Uint8Array': [],
  'WeakMap': ['getNative'],

  // Dependencies of lodash properties.
  'templateSettings': ['escape'],

  // Dependencies of the main module.
  'main': ['lodash', 'Symbol'],

  // Dependencies of `Hash` functions.
  'Hash': ['hashClear', 'hashDelete', 'hashGet', 'hashHas', 'hashSet'],
  'hashClear': ['nativeCreate'],
  'hashDelete': [],
  'hashGet': ['nativeCreate'],
  'hashHas': ['nativeCreate'],
  'hashSet': ['nativeCreate'],

  // Dependencies of `LazyWrapper` functions.
  'LazyWrapper': ['baseCreate', 'baseLodash'],
  'lazyClone': ['copyArray', 'LazyWrapper'],
  'lazyReverse': ['LazyWrapper'],
  'lazyValue': ['baseWrapperValue', 'getView', 'isArray'],

  // Dependencies of `LodashWrapper` functions.
  'LodashWrapper': ['baseCreate', 'baseLodash'],
  'wrapperAt': ['baseAt', 'flatRest', 'isIndex', 'LazyWrapper', 'LodashWrapper', 'thru'],
  'wrapperChain': ['chain'],
  'wrapperClone': ['copyArray', 'LazyWrapper', 'LodashWrapper'],
  'wrapperCommit': ['LodashWrapper'],
  'wrapperNext': ['toArray'],
  'wrapperPlant': ['baseLodash', 'wrapperClone'],
  'wrapperReverse': ['LazyWrapper', 'LodashWrapper', 'reverse', 'thru'],
  'wrapperToIterator': [],
  'wrapperValue': ['baseWrapperValue'],

  // Dependencies of `ListCache` functions.
  'ListCache': ['listCacheClear', 'listCacheDelete', 'listCacheGet', 'listCacheHas', 'listCacheSet'],
  'listCacheClear': [],
  'listCacheDelete': ['assocIndexOf'],
  'listCacheGet': ['assocIndexOf'],
  'listCacheHas': ['assocIndexOf'],
  'listCacheSet': ['assocIndexOf'],

  // Dependencies of `MapCache` functions.
  'MapCache': ['mapCacheClear', 'mapCacheDelete', 'mapCacheGet', 'mapCacheHas', 'mapCacheSet'],
  'mapCacheClear': ['Hash', 'ListCache', 'Map'],
  'mapCacheDelete': ['getMapData'],
  'mapCacheGet': ['getMapData'],
  'mapCacheHas': ['getMapData'],
  'mapCacheSet': ['getMapData'],

  // Dependencies of `SetCache` functions.
  'SetCache': ['MapCache', 'setCacheAdd', 'setCacheHas'],
  'setCacheAdd': [],
  'setCacheHas': [],

  // Dependencies of `Stack` functions.
  'Stack': ['ListCache', 'stackClear', 'stackDelete', 'stackGet', 'stackHas', 'stackSet'],
  'stackClear': ['ListCache'],
  'stackDelete': [],
  'stackGet': [],
  'stackHas': [],
  'stackSet': ['ListCache', 'Map', 'MapCache'],

  // Dependencies of lodash methods.
  'add': ['createMathOperation'],
  'after': ['toInteger'],
  'ary': ['createWrap'],
  'assign': ['assignValue', 'copyObject', 'createAssigner', 'isArrayLike', 'isPrototype', 'keys'],
  'assignIn': ['copyObject', 'createAssigner', 'keysIn'],
  'assignInWith': ['copyObject', 'createAssigner', 'keysIn'],
  'assignWith': ['copyObject', 'createAssigner', 'keys'],
  'at': ['baseAt', 'flatRest'],
  'attempt': ['apply', 'baseRest', 'isError'],
  'before': ['toInteger'],
  'bind': ['baseRest', 'createWrap', 'getHolder', 'replaceHolders'],
  'bindAll': ['arrayEach', 'baseAssignValue', 'bind', 'flatRest', 'toKey'],
  'bindKey': ['baseRest', 'createWrap', 'getHolder', 'replaceHolders'],
  'camelCase': ['capitalize', 'createCompounder'],
  'capitalize': ['toString', 'upperFirst'],
  'castArray': ['isArray'],
  'ceil': ['createRound'],
  'chain': ['lodash'],
  'chunk': ['baseSlice', 'isIterateeCall', 'toInteger'],
  'clamp': ['baseClamp', 'toNumber'],
  'clone': ['baseClone'],
  'cloneDeep': ['baseClone'],
  'cloneDeepWith': ['baseClone'],
  'cloneWith': ['baseClone'],
  'compact': [],
  'concat': ['arrayPush', 'baseFlatten', 'copyArray', 'isArray'],
  'cond': ['apply', 'arrayMap', 'baseRest', 'getIteratee'],
  'conforms': ['baseClone', 'baseConforms'],
  'conformsTo': ['baseConformsTo', 'keys'],
  'constant': [],
  'countBy': ['baseAssignValue', 'createAggregator'],
  'create': ['baseAssign', 'baseCreate'],
  'curry': ['createWrap'],
  'curryRight': ['createWrap'],
  'debounce': ['clearTimeout', 'isObject', 'now', 'setTimeout', 'toNumber'],
  'deburr': ['deburrLetter', 'toString'],
  'defaults': ['baseRest', 'eq', 'isIterateeCall', 'keysIn'],
  'defaultsDeep': ['apply', 'baseRest', 'customDefaultsMerge', 'mergeWith'],
  'defaultTo': [],
  'defer': ['baseDelay', 'baseRest'],
  'delay': ['baseDelay', 'baseRest', 'toNumber'],
  'difference': ['baseDifference', 'baseFlatten', 'baseRest', 'isArrayLikeObject'],
  'differenceBy': ['baseDifference', 'baseFlatten', 'baseRest', 'getIteratee', 'isArrayLikeObject', 'last'],
  'differenceWith': ['baseDifference', 'baseFlatten', 'baseRest', 'isArrayLikeObject', 'last'],
  'divide': ['createMathOperation'],
  'drop': ['baseSlice', 'toInteger'],
  'dropRight': ['baseSlice', 'toInteger'],
  'dropRightWhile': ['baseWhile', 'getIteratee'],
  'dropWhile': ['baseWhile', 'getIteratee'],
  'endsWith': ['baseClamp', 'baseToString', 'toInteger', 'toString'],
  'eq': [],
  'escape': ['escapeHtmlChar', 'toString'],
  'escapeRegExp': ['toString'],
  'every': ['arrayEvery', 'baseEvery', 'getIteratee', 'isArray', 'isIterateeCall'],
  'fill': ['baseFill', 'isIterateeCall'],
  'filter': ['arrayFilter', 'baseFilter', 'getIteratee', 'isArray'],
  'find': ['createFind', 'findIndex'],
  'findIndex': ['baseFindIndex', 'getIteratee', 'toInteger'],
  'findKey': ['baseFindKey', 'baseForOwn', 'getIteratee'],
  'findLast': ['createFind', 'findLastIndex'],
  'findLastIndex': ['baseFindIndex', 'getIteratee', 'toInteger'],
  'findLastKey': ['baseFindKey', 'baseForOwnRight', 'getIteratee'],
  'flatMap': ['baseFlatten', 'map'],
  'flatMapDeep': ['baseFlatten', 'map'],
  'flatMapDepth': ['baseFlatten', 'map', 'toInteger'],
  'flatten': ['baseFlatten'],
  'flattenDeep': ['baseFlatten'],
  'flattenDepth': ['baseFlatten', 'toInteger'],
  'flip': ['createWrap'],
  'floor': ['createRound'],
  'flow': ['createFlow'],
  'flowRight': ['createFlow'],
  'forEach': ['arrayEach', 'baseEach', 'getIteratee', 'isArray'],
  'forEachRight': ['arrayEachRight', 'baseEachRight', 'getIteratee', 'isArray'],
  'forIn': ['baseFor', 'getIteratee', 'keysIn'],
  'forInRight': ['baseForRight', 'getIteratee', 'keysIn'],
  'forOwn': ['baseForOwn', 'getIteratee'],
  'forOwnRight': ['baseForOwnRight', 'getIteratee'],
  'fromPairs': [],
  'functions': ['baseFunctions', 'keys'],
  'functionsIn': ['baseFunctions', 'keysIn'],
  'get': ['baseGet'],
  'groupBy': ['baseAssignValue', 'createAggregator'],
  'gt': ['baseGt', 'createRelationalOperation'],
  'gte': ['createRelationalOperation'],
  'has': ['baseHas', 'hasPath'],
  'hasIn': ['baseHasIn', 'hasPath'],
  'head': [],
  'identity': [],
  'includes': ['baseIndexOf', 'isArrayLike', 'isString', 'toInteger', 'values'],
  'indexOf': ['baseIndexOf', 'toInteger'],
  'initial': ['baseSlice'],
  'inRange': ['baseInRange', 'toFinite', 'toNumber'],
  'intersection': ['arrayMap', 'baseIntersection', 'baseRest', 'castArrayLikeObject'],
  'intersectionBy': ['arrayMap', 'baseIntersection', 'baseRest', 'castArrayLikeObject', 'getIteratee', 'last'],
  'intersectionWith': ['arrayMap', 'baseIntersection', 'last', 'baseRest', 'castArrayLikeObject'],
  'invert': ['constant', 'createInverter', 'identity'],
  'invertBy': ['createInverter', 'getIteratee'],
  'invokeMap': ['apply', 'baseEach', 'baseInvoke', 'baseRest', 'isArrayLike'],
  'invoke': ['baseInvoke', 'baseRest'],
  'isArguments': ['baseIsArguments', 'isObjectLike'],
  'isArray': [],
  'isArrayBuffer': ['baseIsArrayBuffer', 'baseUnary'],
  'isArrayLike': ['isFunction', 'isLength'],
  'isArrayLikeObject': ['isArrayLike', 'isObjectLike'],
  'isBoolean': ['baseGetTag', 'isObjectLike'],
  'isBuffer': ['stubFalse'],
  'isDate': ['baseIsDate', 'baseUnary'],
  'isElement': ['isObjectLike', 'isPlainObject'],
  'isEmpty': ['baseKeys', 'getTag', 'isArguments', 'isArray', 'isArrayLike', 'isBuffer', 'isPrototype', 'isTypedArray'],
  'isEqual': ['baseIsEqual'],
  'isEqualWith': ['baseIsEqual'],
  'isError': ['baseGetTag', 'isObjectLike', 'isPlainObject'],
  'isFinite': [],
  'isFunction': ['baseGetTag', 'isObject'],
  'isInteger': ['toInteger'],
  'isLength': [],
  'isMap': ['baseIsMap', 'baseUnary'],
  'isMatch': ['baseIsMatch', 'getMatchData'],
  'isMatchWith': ['baseIsMatch', 'getMatchData'],
  'isNaN': ['isNumber'],
  'isNative': ['baseIsNative', 'isMaskable'],
  'isNil': [],
  'isNull': [],
  'isNumber': ['baseGetTag', 'isObjectLike'],
  'isObject': [],
  'isObjectLike': [],
  'isPlainObject': ['baseGetTag', 'getPrototype', 'isObjectLike'],
  'isRegExp': ['baseIsRegExp', 'baseUnary'],
  'isSafeInteger': ['isInteger'],
  'isSet': ['baseIsSet', 'baseUnary'],
  'isString': ['baseGetTag', 'isArray', 'isObjectLike'],
  'isSymbol': ['baseGetTag', 'isObjectLike'],
  'isTypedArray': ['baseIsTypedArray', 'baseUnary'],
  'isUndefined': [],
  'isWeakMap': ['getTag', 'isObjectLike'],
  'isWeakSet': ['baseGetTag', 'isObjectLike'],
  'iteratee': ['baseClone', 'baseIteratee'],
  'join': [],
  'kebabCase': ['createCompounder'],
  'keyBy': ['baseAssignValue', 'createAggregator'],
  'keys': ['arrayLikeKeys', 'baseKeys', 'isArrayLike'],
  'keysIn': ['arrayLikeKeys', 'baseKeysIn', 'isArrayLike'],
  'last': [],
  'lastIndexOf': ['baseFindIndex', 'baseIsNaN', 'strictLastIndexOf', 'toInteger'],
  'lodash': ['baseLodash', 'isArray', 'isObjectLike', 'LazyWrapper', 'LodashWrapper', 'wrapperClone'],
  'lowerCase': ['createCompounder'],
  'lowerFirst': ['createCaseFirst'],
  'lt': ['baseLt', 'createRelationalOperation'],
  'lte': ['createRelationalOperation'],
  'map': ['arrayMap', 'baseMap', 'getIteratee', 'isArray'],
  'mapKeys': ['baseAssignValue', 'baseForOwn', 'getIteratee'],
  'mapValues': ['baseAssignValue', 'baseForOwn', 'getIteratee'],
  'matches': ['baseClone', 'baseMatches'],
  'matchesProperty': ['baseClone', 'baseMatchesProperty'],
  'method': ['baseInvoke', 'baseRest'],
  'methodOf': ['baseInvoke', 'baseRest'],
  'max': ['baseExtremum', 'baseGt', 'identity'],
  'maxBy': ['baseExtremum', 'baseGt', 'getIteratee'],
  'mean': ['baseMean', 'identity'],
  'meanBy': ['baseMean', 'getIteratee'],
  'memoize': ['MapCache'],
  'merge': ['baseMerge', 'createAssigner'],
  'mergeWith': ['baseMerge', 'createAssigner'],
  'min': ['baseExtremum', 'baseLt', 'identity'],
  'minBy': ['baseExtremum', 'baseLt', 'getIteratee'],
  'mixin': ['arrayEach', 'arrayPush', 'baseFunctions', 'copyArray', 'isFunction', 'isObject', 'keys'],
  'multiply': ['createMathOperation'],
  'negate': [],
  'noConflict': [],
  'noop': [],
  'now': [],
  'nth': ['baseNth', 'toInteger'],
  'nthArg': ['baseNth', 'baseRest', 'toInteger'],
  'omit': ['arrayMap', 'baseClone', 'baseUnset', 'castPath', 'copyObject', 'customOmitClone', 'flatRest', 'getAllKeysIn'],
  'omitBy': ['negate', 'pickBy', 'getIteratee'],
  'once': ['before'],
  'orderBy': ['baseOrderBy', 'isArray'],
  'over': ['arrayMap', 'createOver'],
  'overArgs': ['apply', 'arrayMap', 'baseFlatten', 'baseRest', 'baseUnary', 'castRest', 'getIteratee', 'isArray'],
  'overEvery': ['arrayEvery', 'createOver'],
  'overSome': ['arraySome', 'createOver'],
  'pad': ['createPadding', 'stringSize', 'toInteger', 'toString'],
  'padEnd': ['createPadding', 'stringSize', 'toInteger', 'toString'],
  'padStart': ['createPadding', 'stringSize', 'toInteger', 'toString'],
  'parseInt': ['toString'],
  'partial': ['baseRest', 'createWrap', 'getHolder', 'replaceHolders'],
  'partialRight': ['baseRest', 'createWrap', 'getHolder', 'replaceHolders'],
  'partition': ['createAggregator'],
  'pick': ['basePick', 'flatRest'],
  'pickBy': ['arrayMap', 'basePickBy', 'getAllKeysIn', 'getIteratee'],
  'property': ['baseProperty', 'basePropertyDeep', 'isKey', 'toKey'],
  'propertyOf': ['baseGet'],
  'pull': ['baseRest', 'pullAll'],
  'pullAll': ['basePullAll'],
  'pullAllBy': ['basePullAll', 'getIteratee'],
  'pullAllWith': ['basePullAll'],
  'pullAt': ['arrayMap', 'baseAt', 'basePullAt', 'compareAscending', 'flatRest', 'isIndex'],
  'random': ['baseRandom', 'isIterateeCall', 'toFinite'],
  'range': ['createRange'],
  'rangeRight': ['createRange'],
  'rearg': ['createWrap', 'flatRest'],
  'reduce': ['arrayReduce', 'baseEach', 'baseReduce', 'getIteratee', 'isArray'],
  'reduceRight': ['arrayReduceRight', 'baseEachRight', 'baseReduce', 'getIteratee', 'isArray'],
  'reject': ['arrayFilter', 'baseFilter', 'getIteratee', 'isArray', 'negate'],
  'remove': ['basePullAt', 'getIteratee'],
  'repeat': ['baseRepeat', 'isIterateeCall', 'toInteger', 'toString'],
  'replace': ['toString'],
  'rest': ['baseRest', 'toInteger'],
  'result': ['castPath', 'isFunction', 'toKey'],
  'reverse': [],
  'round': ['createRound'],
  'runInContext': ['defaults', 'pick'],
  'sample': ['arraySample', 'baseSample', 'isArray'],
  'sampleSize': ['arraySampleSize', 'baseSampleSize', 'isArray', 'isIterateeCall', 'toInteger'],
  'set': ['baseSet'],
  'setWith': ['baseSet'],
  'shuffle': ['arrayShuffle', 'baseShuffle', 'isArray'],
  'size': ['baseKeys', 'isArrayLike', 'isString', 'getTag', 'stringSize'],
  'slice': ['baseSlice', 'isIterateeCall', 'toInteger'],
  'snakeCase': ['createCompounder'],
  'some': ['arraySome', 'baseSome', 'getIteratee', 'isArray', 'isIterateeCall'],
  'sortBy': ['baseFlatten', 'baseOrderBy', 'baseRest', 'isIterateeCall'],
  'sortedIndex': ['baseSortedIndex'],
  'sortedIndexBy': ['baseSortedIndexBy', 'getIteratee'],
  'sortedIndexOf': ['baseSortedIndex', 'eq'],
  'sortedLastIndex': ['baseSortedIndex'],
  'sortedLastIndexBy': ['baseSortedIndexBy', 'getIteratee'],
  'sortedLastIndexOf': ['baseSortedIndex', 'eq'],
  'sortedUniq': ['baseSortedUniq'],
  'sortedUniqBy': ['baseSortedUniq', 'getIteratee'],
  'split': ['baseToString', 'castSlice', 'hasUnicode', 'isIterateeCall', 'isRegExp', 'stringToArray', 'toString'],
  'spread': ['apply', 'arrayPush', 'baseRest', 'castSlice', 'toInteger'],
  'startCase': ['createCompounder', 'upperFirst'],
  'startsWith': ['baseClamp', 'baseToString', 'toInteger', 'toString'],
  'stubArray': [],
  'stubFalse': [],
  'stubObject': [],
  'stubString': [],
  'stubTrue': [],
  'subtract': ['createMathOperation'],
  'sum': ['baseSum', 'identity'],
  'sumBy': ['baseSum', 'getIteratee'],
  'tail': ['baseSlice'],
  'take': ['baseSlice', 'toInteger'],
  'takeRight': ['baseSlice', 'toInteger'],
  'takeRightWhile': ['baseWhile', 'getIteratee'],
  'takeWhile': ['baseWhile', 'getIteratee'],
  'tap': [],
  'template': ['customDefaultsAssignIn', 'assignInWith', 'attempt', 'baseValues', 'escapeStringChar', 'isError', 'isIterateeCall', 'keys', 'toString'],
  'throttle': ['debounce', 'isObject'],
  'thru': [],
  'times': ['baseTimes', 'getIteratee', 'toInteger'],
  'toArray': ['copyArray', 'getTag', 'isArrayLike', 'isString', 'iteratorToArray', 'mapToArray', 'setToArray', 'stringToArray', 'Symbol', 'values'],
  'toFinite': ['toNumber'],
  'toInteger': ['toFinite'],
  'toLength': ['baseClamp', 'toInteger'],
  'toLower': ['toString'],
  'toNumber': ['isObject', 'isSymbol'],
  'toPairs': ['createToPairs', 'keys'],
  'toPairsIn': ['createToPairs', 'keysIn'],
  'toPath': ['arrayMap', 'copyArray', 'isArray', 'isSymbol', 'stringToPath', 'toKey', 'toString'],
  'toPlainObject': ['copyObject', 'keysIn'],
  'toSafeInteger': ['baseClamp', 'toInteger'],
  'toString': ['baseToString'],
  'toUpper': ['toString'],
  'transform': ['arrayEach', 'baseCreate', 'baseForOwn', 'getIteratee', 'getPrototype', 'isArray', 'isBuffer', 'isFunction', 'isObject', 'isTypedArray'],
  'trim': ['baseToString', 'castSlice', 'charsEndIndex', 'charsStartIndex', 'stringToArray', 'toString'],
  'trimEnd': ['baseToString', 'castSlice', 'charsEndIndex', 'stringToArray', 'toString'],
  'trimStart': ['baseToString', 'castSlice', 'charsStartIndex', 'stringToArray', 'toString'],
  'truncate': ['baseToString', 'castSlice', 'hasUnicode', 'isObject', 'isRegExp', 'stringSize', 'stringToArray', 'toInteger', 'toString'],
  'unary': ['ary'],
  'unescape': ['toString', 'unescapeHtmlChar'],
  'union': ['baseFlatten', 'baseRest', 'baseUniq', 'isArrayLikeObject'],
  'unionBy': ['baseFlatten', 'baseRest', 'baseUniq', 'getIteratee', 'isArrayLikeObject', 'last'],
  'unionWith': ['baseFlatten', 'baseRest', 'baseUniq', 'isArrayLikeObject', 'last'],
  'uniq': ['baseUniq'],
  'uniqBy': ['baseUniq', 'getIteratee'],
  'uniqWith': ['baseUniq'],
  'uniqueId': ['toString'],
  'unset': ['baseUnset'],
  'unzip': ['arrayMap', 'arrayFilter', 'baseProperty', 'baseTimes', 'isArrayLikeObject'],
  'unzipWith': ['apply', 'arrayMap', 'unzip'],
  'update': ['castFunction', 'baseUpdate'],
  'updateWith': ['castFunction', 'baseUpdate'],
  'upperCase': ['createCompounder'],
  'upperFirst': ['createCaseFirst'],
  'values': ['baseValues', 'keys'],
  'valuesIn': ['baseValues', 'keysIn'],
  'without': ['baseDifference', 'baseRest', 'isArrayLikeObject'],
  'words': ['asciiWords', 'hasUnicodeWord', 'toString', 'unicodeWords'],
  'wrap': ['castFunction', 'partial'],
  'xor': ['arrayFilter', 'baseRest', 'baseXor', 'isArrayLikeObject'],
  'xorBy': ['arrayFilter', 'baseRest', 'baseXor', 'getIteratee', 'isArrayLikeObject', 'last'],
  'xorWith': ['arrayFilter', 'baseRest', 'baseXor', 'isArrayLikeObject', 'last'],
  'zip': ['baseRest', 'unzip'],
  'zipObject': ['assignValue', 'baseZipObject'],
  'zipObjectDeep': ['baseSet', 'baseZipObject'],
  'zipWith': ['baseRest', 'unzipWith'],

  // Dependencies of private functions.
  'apply': [],
  'arrayAggregator': [],
  'arrayEach': [],
  'arrayEachRight': [],
  'arrayEvery': [],
  'arrayFilter': [],
  'arrayIncludes': ['baseIndexOf'],
  'arrayIncludesWith': [],
  'arrayLikeKeys': ['baseTimes', 'isArguments', 'isArray', 'isBuffer', 'isIndex', 'isTypedArray'],
  'arrayMap': [],
  'arrayPush': [],
  'arrayReduce': [],
  'arrayReduceRight': [],
  'arraySample': ['baseRandom'],
  'arraySampleSize': ['baseClamp', 'copyArray', 'shuffleSelf'],
  'arrayShuffle': ['copyArray', 'shuffleSelf'],
  'arraySome': [],
  'asciiSize': ['baseProperty'],
  'asciiToArray': [],
  'asciiWords': [],
  'assignMergeValue': ['baseAssignValue', 'eq'],
  'assignValue': ['baseAssignValue', 'eq'],
  'assocIndexOf': ['eq'],
  'baseAggregator': ['baseEach'],
  'baseAssign': ['copyObject', 'keys'],
  'baseAssignIn': ['copyObject', 'keysIn'],
  'baseAssignValue': ['defineProperty'],
  'baseAt': ['get'],
  'baseClamp': [],
  'baseClone': ['arrayEach', 'assignValue', 'baseAssign', 'baseAssignIn', 'cloneBuffer', 'copyArray', 'copySymbols', 'copySymbolsIn', 'getAllKeys', 'getAllKeysIn', 'getTag', 'initCloneArray', 'initCloneByTag', 'initCloneObject', 'isArray', 'isBuffer', 'isMap', 'isObject', 'isSet', 'keys', 'Stack'],
  'baseConforms': ['baseConformsTo', 'keys'],
  'baseConformsTo': [],
  'baseCreate': ['isObject'],
  'baseDelay': ['setTimeout'],
  'baseDifference': ['arrayIncludes', 'arrayIncludesWith', 'arrayMap', 'baseUnary', 'cacheHas', 'SetCache'],
  'baseEach': ['baseForOwn', 'createBaseEach'],
  'baseEachRight': ['baseForOwnRight', 'createBaseEach'],
  'baseEvery': ['baseEach'],
  'baseExtremum': ['isSymbol'],
  'baseFill': ['toInteger', 'toLength'],
  'baseFilter': ['baseEach'],
  'baseFindIndex': [],
  'baseFindKey': [],
  'baseFlatten': ['arrayPush', 'isFlattenable'],
  'baseFor': ['createBaseFor'],
  'baseForOwn': ['baseFor', 'keys'],
  'baseForOwnRight': ['baseForRight', 'keys'],
  'baseForRight': ['createBaseFor'],
  'baseFunctions': ['arrayFilter', 'isFunction'],
  'baseGet': ['castPath', 'toKey'],
  'baseGetAllKeys': ['arrayPush', 'isArray'],
  'baseGetTag': ['getRawTag', 'objectToString', 'Symbol'],
  'baseGt': [],
  'baseHas': [],
  'baseHasIn': [],
  'baseIndexOf': ['baseFindIndex', 'baseIsNaN', 'strictIndexOf'],
  'baseIndexOfWith': [],
  'baseInRange': [],
  'baseIntersection': ['arrayIncludes', 'arrayIncludesWith', 'arrayMap', 'baseUnary', 'cacheHas', 'SetCache'],
  'baseInverter':['baseForOwn'],
  'baseInvoke': ['apply', 'castPath', 'last', 'parent', 'toKey'],
  'baseIsArguments': ['baseGetTag', 'isObjectLike'],
  'baseIsArrayBuffer': ['baseGetTag', 'isObjectLike'],
  'baseIsDate': ['baseGetTag', 'isObjectLike'],
  'baseIsEqual': ['baseIsEqualDeep', 'isObjectLike'],
  'baseIsEqualDeep': ['equalArrays', 'equalByTag', 'equalObjects', 'getTag', 'isArray', 'isBuffer', 'isTypedArray', 'Stack'],
  'baseIsFunction': ['baseGetTag'],
  'baseIsMap': ['getTag', 'isObjectLike'],
  'baseIsMatch': ['baseIsEqual', 'Stack'],
  'baseIsNaN': [],
  'baseIsNative': ['isFunction', 'isMasked', 'isObject', 'toSource'],
  'baseIsRegExp': ['baseGetTag', 'isObjectLike'],
  'baseIsSet': ['getTag', 'isObjectLike'],
  'baseIsTypedArray': ['baseGetTag', 'isLength', 'isObjectLike'],
  'baseIteratee': ['baseMatches', 'baseMatchesProperty', 'identity', 'isArray', 'property'],
  'baseKeys': ['isPrototype', 'nativeKeys'],
  'baseKeysIn': ['isObject', 'isPrototype', 'nativeKeysIn'],
  'baseLodash': [],
  'baseLt': [],
  'baseMap': ['baseEach', 'isArrayLike'],
  'baseMatches': ['baseIsMatch', 'getMatchData', 'matchesStrictComparable'],
  'baseMatchesProperty': ['baseIsEqual', 'hasIn', 'get', 'isKey', 'isStrictComparable', 'matchesStrictComparable', 'toKey'],
  'baseMean': ['baseSum'],
  'baseMerge': ['assignMergeValue', 'baseFor', 'baseMergeDeep', 'isObject', 'keysIn', 'safeGet', 'Stack'],
  'baseMergeDeep': ['assignMergeValue', 'cloneBuffer', 'cloneTypedArray', 'copyArray', 'initCloneObject', 'isArguments', 'isArray', 'isArrayLikeObject', 'isBuffer', 'isFunction', 'isObject', 'isPlainObject', 'isTypedArray', 'safeGet', 'toPlainObject'],
  'baseNth': ['isIndex'],
  'baseOrderBy': ['arrayMap', 'baseMap', 'baseSortBy', 'baseUnary', 'compareMultiple', 'getIteratee', 'identity'],
  'basePick': ['basePickBy', 'hasIn'],
  'basePickBy': ['baseGet', 'baseSet', 'castPath'],
  'baseProperty': [],
  'basePropertyOf': [],
  'basePropertyDeep': ['baseGet'],
  'basePullAll': ['arrayMap', 'baseIndexOf', 'baseIndexOfWith', 'baseUnary', 'copyArray'],
  'basePullAt': ['baseUnset', 'isIndex'],
  'baseRandom': [],
  'baseRange': [],
  'baseReduce': [],
  'baseRepeat': [],
  'baseRest': ['identity', 'overRest', 'setToString'],
  'baseSample': ['arraySample', 'values'],
  'baseSampleSize': ['baseClamp', 'shuffleSelf', 'values'],
  'baseSet': ['assignValue', 'castPath', 'isIndex', 'isObject', 'toKey'],
  'baseSetData': ['identity'],
  'baseSetToString': ['constant', 'defineProperty', 'identity'],
  'baseShuffle': ['shuffleSelf', 'values'],
  'baseSlice': [],
  'baseSome': ['baseEach'],
  'baseSortBy': [],
  'baseSortedIndex': ['baseSortedIndexBy', 'identity', 'isSymbol'],
  'baseSortedIndexBy': ['isSymbol'],
  'baseSortedUniq': ['eq'],
  'baseSum': [],
  'baseTimes': [],
  'baseToPairs': ['arrayMap'],
  'baseToNumber': ['isSymbol'],
  'baseToString': ['arrayMap', 'isArray', 'isSymbol', 'Symbol'],
  'baseUnary': [],
  'baseUniq': ['arrayIncludes', 'arrayIncludesWith', 'cacheHas', 'createSet', 'SetCache', 'setToArray'],
  'baseUnset': ['castPath', 'last', 'parent', 'toKey'],
  'baseUpdate': ['baseGet', 'baseSet'],
  'baseValues': ['arrayMap'],
  'baseWhile': ['baseSlice'],
  'baseWrapperValue': ['arrayPush', 'arrayReduce', 'LazyWrapper'],
  'baseXor': ['baseDifference', 'baseFlatten', 'baseUniq'],
  'baseZipObject': [],
  'cacheHas': [],
  'castArrayLikeObject': ['isArrayLikeObject'],
  'castFunction': ['identity'],
  'castPath': ['isArray', 'isKey', 'stringToPath', 'toString'],
  'castRest': ['baseRest'],
  'castSlice': ['baseSlice'],
  'charAtCallback': [],
  'charsStartIndex': ['baseIndexOf'],
  'charsEndIndex': ['baseIndexOf'],
  'clearTimeout': [],
  'cloneArrayBuffer': ['Uint8Array'],
  'cloneBuffer': [],
  'cloneDataView': ['cloneArrayBuffer'],
  'cloneRegExp': [],
  'cloneSymbol': ['Symbol'],
  'cloneTypedArray': ['cloneArrayBuffer'],
  'compareAscending': ['isSymbol'],
  'compareMultiple': ['compareAscending'],
  'composeArgs': [],
  'composeArgsRight': [],
  'copyArray': [],
  'copyObject': ['assignValue', 'baseAssignValue'],
  'copySymbols': ['copyObject', 'getSymbols'],
  'copySymbolsIn': ['copyObject', 'getSymbolsIn'],
  'countHolders': [],
  'createAggregator': ['arrayAggregator', 'baseAggregator', 'getIteratee', 'isArray'],
  'createAssigner': ['baseRest', 'isIterateeCall'],
  'createBaseEach': ['isArrayLike'],
  'createBaseFor': [],
  'createBind': ['createCtor'],
  'createCaseFirst': ['castSlice', 'hasUnicode', 'stringToArray', 'toString'],
  'createCompounder': ['arrayReduce', 'deburr', 'words'],
  'createCtor': ['baseCreate', 'isObject'],
  'createCurry': ['apply', 'createCtor', 'createHybrid', 'createRecurry', 'getHolder', 'replaceHolders'],
  'createFind': ['getIteratee', 'isArrayLike', 'keys'],
  'createFlow': ['flatRest', 'getData', 'getFuncName', 'isArray', 'isLaziable', 'LodashWrapper'],
  'createHybrid': ['composeArgs', 'composeArgsRight', 'countHolders', 'createCtor', 'createRecurry', 'getHolder', 'reorder', 'replaceHolders'],
  'createInverter': ['baseInverter'],
  'createMathOperation': ['baseToNumber', 'baseToString'],
  'createOver': ['apply', 'arrayMap', 'baseRest', 'baseUnary', 'flatRest', 'getIteratee'],
  'createPadding': ['baseRepeat', 'baseToString', 'castSlice', 'hasUnicode', 'stringSize', 'stringToArray'],
  'createPartial': ['apply', 'createCtor'],
  'createRange': ['baseRange', 'isIterateeCall', 'toFinite'],
  'createRecurry': ['isLaziable', 'setData', 'setWrapToString'],
  'createRelationalOperation': ['toNumber'],
  'createRound': ['toInteger', 'toNumber', 'toString'],
  'createSet': ['noop', 'Set', 'setToArray'],
  'createToPairs': ['baseToPairs', 'getTag', 'mapToArray', 'setToPairs'],
  'createWrap': ['baseSetData', 'createBind', 'createCurry', 'createHybrid', 'createPartial', 'getData', 'mergeData', 'setData', 'setWrapToString', 'toInteger'],
  'customDefaultsAssignIn': ['eq'],
  'customDefaultsMerge': ['baseMerge', 'isObject'],
  'customOmitClone': ['isPlainObject'],
  'deburrLetter': ['basePropertyOf'],
  'defineProperty': ['getNative'],
  'escapeHtmlChar': ['basePropertyOf'],
  'escapeStringChar': [],
  'equalArrays': ['arraySome', 'cacheHas', 'SetCache'],
  'equalByTag': ['eq', 'equalArrays', 'mapToArray', 'setToArray', 'Symbol', 'Uint8Array'],
  'equalObjects': ['getAllKeys'],
  'extremumBy': ['baseEach'],
  'flatRest': ['flatten', 'overRest', 'setToString'],
  'getAllKeys': ['baseGetAllKeys', 'getSymbols', 'keys'],
  'getAllKeysIn': ['baseGetAllKeys', 'getSymbolsIn', 'keysIn'],
  'getData': ['noop'],
  'getFuncName': [],
  'getHolder': ['lodash'],
  'getIteratee': ['baseIteratee', 'iteratee'],
  'getMapData': ['isKeyable'],
  'getMatchData': ['isStrictComparable', 'keys'],
  'getNative': ['baseIsNative', 'getValue'],
  'getPrototype': ['overArg'],
  'getRawTag': ['Symbol'],
  'getSymbols': ['arrayFilter', 'stubArray'],
  'getSymbolsIn': ['arrayPush', 'getPrototype', 'getSymbols', 'stubArray'],
  'getTag': ['baseGetTag', 'DataView', 'Map', 'Promise', 'Set', 'toSource', 'WeakMap'],
  'getValue': [],
  'getView': [],
  'getWrapDetails': [],
  'hasPath': ['castPath', 'isArguments', 'isArray', 'isIndex', 'isLength', 'toKey'],
  'hasUnicode': [],
  'hasUnicodeWord': [],
  'initCloneArray': [],
  'initCloneByTag': ['cloneArrayBuffer', 'cloneDataView', 'cloneRegExp', 'cloneSymbol', 'cloneTypedArray'],
  'initCloneObject': ['baseCreate', 'getPrototype', 'isPrototype'],
  'insertWrapDetails': [],
  'isFlattenable': ['isArguments', 'isArray', 'Symbol'],
  'isIndex': [],
  'isIterateeCall': ['eq', 'isArrayLike', 'isIndex', 'isObject'],
  'isKey': ['isArray', 'isSymbol'],
  'isKeyable': [],
  'isLaziable': ['getData', 'getFuncName', 'LazyWrapper', 'lodash'],
  'isMaskable': ['isFunction', 'stubFalse'],
  'isMasked': [],
  'isPrototype': [],
  'isStrictComparable': ['isObject'],
  'iteratorToArray': [],
  'mapToArray': [],
  'matchesStrictComparable': [],
  'memoizeCapped': ['memoize'],
  'mergeData': ['composeArgs', 'composeArgsRight', 'replaceHolders'],
  'nativeCreate': ['getNative'],
  'nativeKeys': ['overArg'],
  'nativeKeysIn': [],
  'objectToString': [],
  'overArg': [],
  'overRest': ['apply'],
  'parent': ['baseGet', 'baseSlice'],
  'reorder': ['copyArray', 'isIndex'],
  'replaceHolders': [],
  'safeGet': [],
  'setData': ['baseSetData', 'shortOut'],
  'setTimeout': [],
  'setToArray': [],
  'setToPairs': [],
  'setToString': ['baseSetToString', 'shortOut'],
  'setWrapToString': ['getWrapDetails', 'insertWrapDetails', 'setToString', 'updateWrapDetails'],
  'shimKeys': ['isArguments', 'isArray', 'isIndex', 'isLength', 'isString', 'keysIn'],
  'shortOut': [],
  'shuffleSelf': ['baseRandom'],
  'strictIndexOf': [],
  'strictLastIndexOf': [],
  'stringSize': ['asciiSize', 'hasUnicode', 'unicodeSize'],
  'stringToArray': ['asciiToArray', 'hasUnicode', 'unicodeToArray'],
  'stringToPath': ['memoizeCapped'],
  'toKey': ['isSymbol'],
  'toSource': [],
  'unescapeHtmlChar': ['basePropertyOf'],
  'unicodeSize': [],
  'unicodeToArray': [],
  'unicodeWords': [],
  'updateWrapDetails': ['arrayEach', 'arrayIncludes']
});

/** Used to map real names to their aliases. */
exports.realToAlias = new Hash(_.invertBy(exports.aliasToReal));

/* Used to track dependencies for sequences. */
exports.seqDep = new Hash({
  'funcDep': [
    'arrayEach', 'arrayPush', 'baseForOwn', 'baseInvoke', 'baseRest', 'chain',
    'createHybrid', 'getIteratee', 'identity', 'isArray', 'last', 'lazyClone',
    'lazyReverse', 'lazyValue', 'LazyWrapper', 'LodashWrapper', 'mixin', 'negate',
    'tap', 'thru', 'toInteger', 'wrapperAt', 'wrapperChain', 'wrapperCommit',
    'wrapperNext', 'wrapperPlant', 'wrapperReverse', 'wrapperToIterator',
    'wrapperValue'
  ],
  'varDep': ['realNames']
});

/* Used to rename sequence wrapper modules. */
exports.wrapperToReal = new Hash({
  'wrapperAt': 'at',
  'wrapperCommit': 'commit',
  'wrapperLodash': 'lodash',
  'wrapperNext': 'next',
  'wrapperPlant': 'plant',
  'wrapperReverse': 'reverse',
  'wrapperToIterator': 'toIterator',
  'wrapperValue': 'value'
});

/** Used to track variable dependencies of identifiers. */
exports.varDep = new Hash({

  // Dependencies of variables.
  'coreJsData': ['root'],
  'nodeUtil': ['freeGlobal'],
  'root': ['freeGlobal'],

  // Dependencies of built-ins.
  'DataView': ['root'],
  'Map': ['root'],
  'Promise': ['root'],
  'Set': ['root'],
  'Symbol': ['root'],
  'Uint8Array': ['root'],
  'WeakMap': ['root'],

  // Dependencies of lodash properties.
  'templateSettings': ['reEscape', 'reEvaluate', 'reInterpolate'],

  // Dependencies of the main module.
  'main': ['realNames'],

  // Dependencies of lodash methods.
  'isArrayBuffer': ['nodeUtil'],
  'isBuffer': ['root'],
  'isDate': ['nodeUtil'],
  'isFinite': ['root'],
  'isMap': ['nodeUtil'],
  'isRegExp': ['nodeUtil'],
  'isSet': ['nodeUtil'],
  'isTypedArray': ['nodeUtil'],
  'noConflict': ['root'],
  'now': ['root'],
  'parseInt': ['root'],
  'template': ['reInterpolate', 'templateSettings'],

  // Dependencies of private functions.
  'baseSetData': ['metaMap'],
  'clearTimeout': ['root'],
  'cloneBuffer': ['root'],
  'createBind': ['root'],
  'createCurry': ['root'],
  'createHybrid': ['root'],
  'createPartial': ['root'],
  'getData': ['metaMap'],
  'getFuncName': ['realNames'],
  'isMasked': ['coreJsData'],
  'isMaskable': ['coreJsData'],
  'setTimeout': ['root']
});
