docs: function facet() {
    var args = mlutil.asArray.apply(null, arguments);
    var argLen = args.length;
    if (argLen < 1) {
      throw new Error('facet must at a minimum identify the index');
    }
  
    var isConstraintIndex = {
      collection:               true,
      element:                  true,
      field:                    true,
      'geo-attr-pair':          true,
      'geo-elem':               true,
      'geo-elem-pair':          true,
      'geo-json-property':      true,
      'geo-json-property-pair': true,
      'geo-path':               true,
      'json-property':          true,
      'path-index':             true
    };
    var isGeoLocationIndex = {
      'geo-attr-pair':          true,
      'geo-elem':               true,
      'geo-elem-pair':          true,
      'geo-json-property':      true,
      'geo-json-property-pair': true,
      'geo-path':               true
    };
  
    var constraintName = null;
    var constraintIndex = null;
    var firstKey = null;
    var datatype;
    var collation;
    var facetOptions;
    var calculateFunction;
    var buckets = null;
    var computedBuckets = null;
    var heatmap = null;
  
    var arg = null;
    for (var i=0; i < argLen; i++) {
      arg = args[i];
      switch(i) {
      case 0:
        if (typeof arg === 'string' || arg instanceof String) {
          constraintName = arg;
        } else {
          constraintIndex = arg;
        }
        continue;
      case 1:
        if ((arg['start-facet'] != null) &&
            (arg['finish-facet'] != null)) {
          calculateFunction = arg;
          continue;
        }
        if (constraintIndex === null) {
          if (typeof arg === 'string' || arg instanceof String) {
            constraintIndex = property(arg);
            continue;
          }
          firstKey = Object.keys(arg)[0];
          if (isConstraintIndex[firstKey]) {
            constraintIndex = arg;
            continue;
          }
        }
      }
      if (datatype === undefined) {
        datatype = arg.datatype;
        if (datatype !== undefined) {
          collation = arg.collation;
          continue;
        }
      }
      if (facetOptions === undefined) {
        facetOptions = arg['facet-option'];
        if (facetOptions !== undefined) {
          continue;
        }
      }
      if (calculateFunction === undefined &&
          (arg['start-facet'] != null) &&
          (arg['finish-facet'] != null)) {
        calculateFunction = arg;
        continue;
      }
      if (heatmap === null) {
        heatmap = arg.heatmap;
        if (heatmap != null) {
          continue;
        }
      }
      if (arg instanceof BucketDef) {
        if (buckets === null) {
          buckets = [arg];
        } else {
          buckets.push(arg);
        }
        continue;
      }
      if (arg instanceof ComputedBucketDef) {
        if (computedBuckets === null) {
          computedBuckets = [arg];
        } else {
          computedBuckets.push(arg);
        }
        continue;
      }
      if (Array.isArray(arg) && arg.length > 0) {
        if (arg[0] instanceof BucketDef) {
          if (buckets === null) {
            buckets = arg;
          } else {
            Array.prototype.push.apply(buckets, arg);
          }
          continue;
        }
        if (arg[0] instanceof ComputedBucketDef) {
          if (computedBuckets === null) {
            computedBuckets = arg;
          } else {
            Array.prototype.push.apply(computedBuckets, arg);
          }
          continue;
        }
      }
      throw new Error('unknown facet argument: '+mlutil.identify(arg, true));
    }
    if (constraintIndex === null) {
      constraintIndex = property(constraintName);
    } else if (constraintName === null) {
      constraintName = defaultConstraintName(constraintIndex);
      if (constraintName === null) {
        throw new Error('could not default constraint name from '+
            Object.keys(constraintIndex).join(', ') + ' index'
            );
      }
    }
  
    var facetWrapper = {name: constraintName};
    var constraint = {facet: true};
    if (constraintIndex.collection !== undefined) {
      facetWrapper.collection = constraint;
    } else if (calculateFunction !== undefined) {
      constraint['start-facet']  = calculateFunction['start-facet'];
      constraint['finish-facet'] = calculateFunction['finish-facet'];
      facetWrapper.custom = constraint;
    } else if (isGeoLocationIndex[firstKey]) {
      facetWrapper[firstKey] = constraintIndex[firstKey];
      if (heatmap !== null) {
        facetWrapper[firstKey].heatmap = heatmap;
      }
    } else {
      facetWrapper.range = constraint;
      if (datatype != null) {
        constraint.type = datatype;
        if (collation != null) {
          constraint.collation = collation;
        }
      }
      var constraintKeys = Object.keys(constraintIndex);
      var constraintKeyLen = constraintKeys.length;
      for (var j=0; j < constraintKeyLen; j++) {
        var key = constraintKeys[j];
        constraint[key] = constraintIndex[key];
      }
      if (buckets !== null) {
        constraint.bucket = buckets;
      }
      if (computedBuckets !== null) {
        constraint['computed-bucket'] = computedBuckets;
      }
    }
    if (facetOptions !== undefined) {
      constraint['facet-option'] = facetOptions;
    }
  
    return facetWrapper;
  }