The base implementation of `_.flatten` without support for callback
shorthands or `thisArg` binding.

@private
@param {Array} array The array to flatten.
@param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
@param {boolean} [isArgArrays=false] A flag to restrict flattening to arrays and `arguments` objects.
@param {number} [fromIndex=0] The index to start from.
@returns {Array} Returns a new flattened array.
function baseFlatten(array, isShallow, isArgArrays, fromIndex) {
      var index = (fromIndex || 0) - 1,
          length = array ? array.length : 0,
          result = [];

      while (++index < length) {
        var value = array[index];

        if (value && typeof value == 'object' && typeof value.length == 'number'
            && (isArray(value) || isArguments(value))) {
          // recursively flatten arrays (susceptible to call stack limits)
          if (!isShallow) {
            value = baseFlatten(value, isShallow, isArgArrays);
          }
          var valIndex = -1,
              valLength = value.length,
              resIndex = result.length;

          result.length += valLength;
          while (++valIndex < valLength) {
            result[resIndex++] = value[valIndex];
          }
        } else if (!isArgArrays) {
          result.push(value);
        }
      }
      return result;
    }