docs: function XError(/*code, message, data, privateData, cause*/) {
  	if (Error.captureStackTrace) Error.captureStackTrace(this, this);
  	else this.stack = new Error().stack;
  
  	var code, message, data, cause, privateData;
  
  	for(var i = 0; i < arguments.length; i++) {
  		var arg = arguments[i];
  		if(XError.isXError(arg) || arg instanceof Error) {
  			if(cause !== undefined) {
  				data = cause;
  			}
  			cause = arg;
  		} else if(typeof arg === 'string' || typeof arg === 'number') {
  			if(typeof arg !== 'string') arg = '' + arg;
  			if(code === undefined && arg.indexOf(' ') == -1) code = arg;
  			else if(message === undefined) message = arg;
  			else if(data === undefined) data = arg;
  			else if(privateData === undefined) privateData = arg;
  			else if(cause === undefined) cause = new Error(arg);
  		} else if(arg === null || arg === undefined) {
  			if(code === undefined) code = null;
  			else if(message === undefined) message = null;
  			else if(data === undefined) data = null;
  			else if(privateData === undefined) privateData = null;
  			else if(cause === undefined) cause = null;
  		} else {
  			if(data === undefined) data = arg;
  			else if(privateData === undefined) privateData = arg;
  		}
  	}
  
  	code = code || (cause && cause.code) || XError.INTERNAL_ERROR;
  	message = message || (cause && cause.message);
  
  	if(code) {
  		var errorCodeInfo = registry.getErrorCode(code);
  		if(errorCodeInfo) {
  			if(errorCodeInfo.code) code = errorCodeInfo.code;	// in case of aliased error codes
  			if(!message && errorCodeInfo.message) message = errorCodeInfo.message;
  		}
  	}
  
  	this.code = code;
  	this.message = message || 'An error occurred';
  	this.data = data;
  	this.privateData = privateData;
  	this.cause = cause;
  	this.name = 'XError';
  	Object.defineProperty(this, '_isXError', { configurable: false, enumerable: false, writable: false, value: true });
  }