function conditionalHandler(candidates) {
    var isVersioned = false;
    var isContentTyped = false;

    if (!_.isArray(candidates)) {
        candidates = [candidates];
    }

    // Assert
    assert.arrayOfObject(candidates, 'candidates');
    candidates = candidates.map(function map(candidate) {
        // Array of handlers, convert to chain
        if (_.isArray(candidate.handler)) {
            var chain = new Chain();
            candidate.handler.forEach(function forEach(_handler) {
                assert.func(_handler);
                chain.add(_handler);
            });
            candidate.handler = chain.run.bind(chain);
        }

        assert.func(candidate.handler);

        if (_.isString(candidate.version)) {
            candidate.version = [candidate.version];
        }
        if (_.isString(candidate.contentType)) {
            candidate.contentType = [candidate.contentType];
        }

        assert.optionalArrayOfString(candidate.version);
        assert.optionalArrayOfString(candidate.contentType);

        isVersioned = isVersioned || !!candidate.version;
        isContentTyped = isContentTyped || !!candidate.contentType;

        return candidate;
    });

    /**
     * Conditional Handler
     *
     * @private
     * @param  {Request}  req - request
     * @param  {Response} res - response
     * @param  {Function} next - next
     * @returns {undefined} no return value
     */
    return function _conditionalHandlerFactory(req, res, next) {
        var contentType = req.headers.accept || DEF_CT;
        var reqCandidates = candidates;

        // Content Type
        if (isContentTyped) {
            var contentTypes = contentType.split(/\s*,\s*/);
            reqCandidates = candidates.filter(function filter(candidate) {
                var neg = new Negotiator({
                    headers: {
                        accept: candidate.contentType.join(', ')
                    }
                });
                var tmp = neg.preferredMediaType(contentTypes);
                return tmp && tmp.length;
            });

            if (!reqCandidates.length) {
                next(new UnsupportedMediaTypeError(contentType));
                return;
            }
        }

        // Accept Version
        if (isVersioned) {
            var reqVersion = req.version();
            var maxVersion;
            var maxVersionIndex;

            reqCandidates.forEach(function forEach(candidate, idx) {
                var version = semver.maxSatisfying(
                    candidate.version,
                    reqVersion
                );

                if (version) {
                    if (!maxVersion || semver.gt(version, maxVersion)) {
                        maxVersion = version;
                        maxVersionIndex = idx;
                    }
                }
            });

            // No version find
            if (_.isUndefined(maxVersionIndex)) {
                next(
                    new InvalidVersionError(
                        '%s is not supported by %s %s',
                        req.version() || '?',
                        req.method,
                        req.path()
                    )
                );
                return;
            }

            // Add api-version response header
            res.header('api-version', maxVersion);
            // Store matched version on request internal
            req._matchedVersion = maxVersion;
            // Run handler
            reqCandidates[maxVersionIndex].handler(req, res, next);
            return;
        }

        // When not versioned
        reqCandidates[0].handler(req, res, next);
    };
}
Runs first handler that matches to the condition

@public
@function conditionalHandler
@param {Object|Object[]} candidates - candidates
@param {Function|Function[]} candidates.handler - handler(s)
@param {String|String[]} [candidates.version] - '1.1.0', ['1.1.0', '1.2.0']
@param {String} [candidates.contentType] - accepted content type, '*\/json'
@returns  {Function} Handler
@throws {InvalidVersionError}
@throws {UnsupportedMediaTypeError}
@example
server.use(restify.plugins.conditionalHandler({
   contentType: 'application/json',
   version: '1.0.0',
   handler: function (req, res, next) {
       next();
   })
});

server.get('/hello/:name', restify.plugins.conditionalHandler([
  {
     version: '1.0.0',
     handler: function(req, res, next) { res.send('1.x'); }
  },
  {
     version: ['1.5.0', '2.0.0'],
     handler: function(req, res, next) { res.send('1.5.x, 2.x'); }
  },
  {
     version: '3.0.0',
     contentType: ['text/html', 'text/html']
     handler: function(req, res, next) { res.send('3.x, text'); }
  },
  {
     version: '3.0.0',
     contentType: 'application/json'
     handler: function(req, res, next) { res.send('3.x, json'); }
  },
  // Array of handlers
  {
     version: '4.0.0',
     handler: [
         function(req, res, next) { next(); },
         function(req, res, next) { next(); },
         function(req, res, next) { res.send('4.x') }
     ]
  },
]);
// 'accept-version': '^1.1.0' => 1.5.x, 2.x'
// 'accept-version': '3.x', accept: 'application/json' => '3.x, json'