docs: function createValidators(
  	validatorFuncs, defaultValidators, subjDef, subjDescription) {
  
  	const sets = new Object(defaultValidators);
  
  	if (subjDef.validators) {
  		if (Array.isArray(subjDef.validators)) {
  			if (sets['*'])
  				sets['*'] = sets['*'].concat(subjDef.validators);
  			else
  				sets['*'] = subjDef.validators;
  		} else if ((typeof subjDef.validators) === 'object') {
  			for (let setsSpec in subjDef.validators) {
  				const setValidators = subjDef.validators[setsSpec];
  				if (!Array.isArray(setValidators))
  					throw new common.X2UsageError(
  						'Invalid validators specification on ' +
  							subjDescription + ': expected an array for' +
  							' validation set ' + setsSpec + '.');
  				for (let setId of setsSpec.split(',')) {
  					let set = sets[setId];
  					if (!set)
  						sets[setId] = set = new Array();
  					for (let validatorSpec of setValidators)
  						set.push(validatorSpec);
  				}
  			}
  		} else {
  			throw new common.X2UsageError(
  				'Invalid validators specification on ' + subjDescription +
  					': expected an object or an array.');
  		}
  	}
  
  	if (subjDef.elementValidators) {
  		if (Array.isArray(subjDef.elementValidators)) {
  			if (sets['element:*'])
  				sets['element:*'] = sets['element:*'].concat(
  					subjDef.elementValidators);
  			else
  				sets['element:*'] = subjDef.elementValidators;
  		} else if ((typeof subjDef.elementValidators) === 'object') {
  			for (let setsSpec in subjDef.elementValidators) {
  				const setValidators = subjDef.elementValidators[setsSpec];
  				if (!Array.isArray(setValidators))
  					throw new common.X2UsageError(
  						'Invalid element validators specification on ' +
  							subjDescription + ': expected an array for' +
  							' validation set ' + setsSpec + '.');
  				for (let setId of setsSpec.split(',')) {
  					let set = sets['element:' + setId];
  					if (!set)
  						sets['element:' + setId] = set = new Array();
  					for (let validatorSpec of setValidators)
  						set.push(validatorSpec);
  				}
  			}
  		} else {
  			throw new common.X2UsageError(
  				'Invalid validators specification on ' + subjDescription +
  					': expected an object or an array.');
  		}
  	}
  
  	let numValidators = 0;
  	for (let setId in sets) {
  		let validators = new Array();
  		for (let validatorSpec of sets[setId]) {
  			let validatorFunc, validatorId, params;
  			if ((typeof validatorSpec) === 'string') {
  				validatorId = validatorSpec;
  				if (validatorId.startsWith('-')) {
  					validatorId = validatorId.substring(1);
  					validators = validators.filter(v => (v.id !== validatorId));
  					continue;
  				}
  				validatorFunc = validatorFuncs[validatorId];
  			} else if (Array.isArray(validatorSpec)
  				&& (validatorSpec.length > 0)) {
  				validatorId = validatorSpec[0];
  				if (validatorSpec.length > 1)
  					params = validatorSpec.slice(1);
  				validatorFunc = validatorFuncs[validatorId];
  			} else if ((typeof validatorSpec) === 'function') {
  				validatorId = '---';
  				validatorFunc = validatorSpec;
  			} else {
  				throw new common.X2UsageError(
  					'Invalid validators specification on ' + subjDescription +
  						': each validator must be either a string, a function' +
  						' or a non-empty array.');
  			}
  			if (!validatorFunc)
  				throw new common.X2UsageError(
  					'Invalid validators specification on ' + subjDescription +
  						': unknown validator "' + validatorId + '".');
  			validators.push({
  				id: validatorId,
  				func: validatorFunc.bind(undefined, params)
  			});
  		}
  		if (validators.length > 0) {
  			sets[setId] = validators.map(v => v.func);
  			numValidators += validators.length;
  		}
  	}
  
  	return (numValidators > 0 ? sets : null);
  }