call(actionName, params, opts = {}) {
		if (params === undefined) params = {}; // Backward compatibility

		// Create context
		let ctx;
		if (opts.ctx != null) {
			const endpoint = this.findNextActionEndpoint(actionName, opts, opts.ctx);
			if (endpoint instanceof Error) {
				return this.Promise.reject(endpoint).catch(err =>
					this.errorHandler(err, { actionName, params, opts })
				);
			}

			// Reused context
			ctx = opts.ctx;
			ctx.endpoint = endpoint;
			ctx.nodeID = endpoint.id;
			ctx.action = endpoint.action;
			ctx.service = endpoint.action.service;
		} else {
			// New root context
			ctx = this.ContextFactory.create(this, null, params, opts);

			const endpoint = this.findNextActionEndpoint(actionName, opts, ctx);
			if (endpoint instanceof Error) {
				return this.Promise.reject(endpoint).catch(err =>
					this.errorHandler(err, { actionName, params, opts })
				);
			}

			ctx.setEndpoint(endpoint);
		}

		if (ctx.endpoint.local)
			this.logger.debug("Call action locally.", {
				action: ctx.action.name,
				requestID: ctx.requestID
			});
		else
			this.logger.debug("Call action on remote node.", {
				action: ctx.action.name,
				nodeID: ctx.nodeID,
				requestID: ctx.requestID
			});

		//this.setCurrentContext(ctx);

		let p = ctx.endpoint.action.handler(ctx);

		// Pointer to Context
		p.ctx = ctx;

		return p;
	}
Call an action

@param {String} actionName	name of action
@param {Object?} params		params of action
@param {Object?} opts		options of call (optional)
@returns {Promise}

@performance-critical
@memberof ServiceBroker