docs: function ko(fn, isParamHandler) {
  	// handlers and middlewares may have safeguard properties to be skipped
  	if ('$$koified' in fn) {
  		return fn;
  	}
  
  	let handler = function (req, res, next) {
  		let argsLength = arguments.length;
  		let args = new Array(argsLength);
  
  		for (let i = 0; i < argsLength; i++) {
  			args[i] = arguments[i];
  		}
  
  		return ko.ifyHandler(fn, args);
  	};
  
  	let errHandler = function (err, req, res, next) {
  		let argsLength = arguments.length;
  		let args = new Array(argsLength);
  
  		for (let i = 0; i < argsLength; i++) {
  			args[i] = arguments[i];
  		}
  
  		return ko.ifyHandler(fn, args, true);
  	};
  
  	let paramHandler = function (req, res, next, val) {
  		let argsLength = arguments.length;
  		let args = new Array(argsLength);
  
  		for (let i = 0; i < argsLength; i++) {
  			args[i] = arguments[i];
  		}
  
  		return ko.ifyHandler(fn, args);
  	};
  
  	let wrapper;
  
  	// the way Express distinguishes error handlers from regular ones
  	if (fn.length === 4) {
  		wrapper = isParamHandler ? paramHandler : errHandler;
  	} else {
  		wrapper = handler;
  	}
  
  	// safeguard
  	Object.defineProperty(wrapper, '$$koified', {
  		configurable: true,
  		writable: true,
  		value: true
  	});
  
  	return wrapper;
  }