todo make it so the client can be customised to publish/subscribe
        Creates an instance of eventhub service
547196
def create_eventhub(self, **kwargs):
        
        eventhub = predix.admin.eventhub.EventHub(**kwargs)
        eventhub.create()
        eventhub.add_to_manifest(self)
        eventhub.grant_client(client_id=self.get_client_id(), **kwargs)
        eventhub.add_to_manifest(self)
        return eventhub
490491
public void subscribeToEvent(EventListener eventListener, Class<? extends AbstractTaskEvent> eventType) {
		this.outputGate.subscribeToEvent(eventListener, eventType);
	}
264647
function publishChanges (eventName, stateId) {
      var subscriptions = instanceSubscriptions[instanceId];

      if(!subscriptions) return;

      subscriptions.forEach(function (response) {
        response.write('event: ' + eventName +'\n');
        response.write('data: ' + stateId + '\n\n');
      });
    }
282655
function(self, eventType, content) {
    return self.client.sendEvent(self.roomId, eventType, content);
}
967124
def create_event(self, timestamp, event_type, hostname, fields, tags=None):
        
        # Agent6 expects a specific set of fields, so we need to place all
        # extra fields in the msg_title and let the Datadog backend separate them
        # Any remaining fields that aren't a part of the datadog-agent payload
        # specification will be dropped.
        event_payload = fields._asdict()

        msg_text = {
            'event_type': event_payload.pop('event_type', None),
            'event_soft_hard': event_payload.pop('event_soft_hard', None),
            'check_name': event_payload.pop('check_name', None),
            'event_state': event_payload.pop('event_state', None),
            'payload': event_payload.pop('payload', None),
            'ack_author': event_payload.pop('ack_author', None),
        }

        msg_text = json.dumps(msg_text)
        self.log.info("Nagios Event pack: {}".format(msg_text))

        event_payload.update(
            {
                'timestamp': timestamp,
                'event_type': event_type,
                'msg_text': msg_text,
                'source_type_name': SOURCE_TYPE_NAME,
                'tags': tags,
            }
        )

        # if host is localhost, turn that into the internal host name
        host = event_payload.get('host', None)
        if host == "localhost":
            event_payload["host"] = hostname
        return event_payload
631039
function createEvent (type, data) {
  let event = document.createEvent(specialEvents[type] || 'Event')
  event.initEvent(type, true, true)
  data && (event.data = data)
  return event
}
458261
function produce(model) {
	//console.log("model is " + JSON.stringify(model, null, 4));
	let thing = {
		properties: {},
		actions: {},
		events: {},
		clients: {},	// stream ID -> stream
		sockets: [],	// list of web sockets
		model: model
	};
	
	let name,
		properties = model.properties,
		actions = model.actions,
		events = model.events;
		
	thing.id = model.id;
	thing.name = model.name;
	model.platform = "https://github.com/draggett/arena-webhub";
	
	thing.emitEvent = function (name, json) {
		if (thing.events.hasOwnProperty(name)) {
			// note that event: is no longer supported for SSE
			// so use an object wrapper to convey event name
			if (json === undefined)
				json = {"event":name};
			else
				json = {"event":name,"data":json};
				
			let message = JSON.stringify(json);
			message = "data: "+ message.replace(/\n/g, '\ndata: ') + "\n\n";

			// clients for server-sent event stream
			let clients = thing.clients;
		
			for (let id in clients) {
				if (clients.hasOwnProperty(id)) {
					let client = clients[id];
					client.response.write(message);
				}
			}
			
			let sockets = thing.sockets;
			
			for (let i = 0; i < sockets.length; ++i) {
				ws_send(sockets[i], JSON.stringify(json));
			}
		} else {
			console.log('unknown event: ' + name + ' on ' + thing.name);
		}
	};
	
	thing.emitValue = function (name, value) {
		// note that event: is no longer supported for SSE
		// so use an object wrapper to convey event name
		if (thing.properties.hasOwnProperty(name)) {
			// be safe as stringify throws exception on undefined
			if (value === undefined)
				value = {"property":name};
			else
				value = {"property":name,"data":value};
				
			let message = JSON.stringify(value);
			message = "data: "+ message.replace(/\n/g, '\ndata: ') + "\n\n";
			let clients = thing.clients;

			if (clients !== undefined) {
				for (var id in clients) {
					if (clients.hasOwnProperty(id)) {
						let client = clients[id];
						client.response.write(message);
					}
				}
			}

			let sockets = thing.sockets;
			if (sockets !== undefined ) {
				//console.log('there are ' + sockets.length + ' socket clients');
				for (let i = 0; i < sockets.length; ++i) {
					ws_send(sockets[i], JSON.stringify(value));
				}
				
				//console.log('sent data to sockets');
			}
		} else {
			console.log('unknown property: ' + name + ' on ' + thing.name);
		}
	};
	
	thing.emitState = function (properties) {
		// note that event: is no longer supported for SSE
		// so use an object wrapper to convey event name
		let obj = {};
		
		if (properties === undefined)
			properties = thing.properties;
			
		for (var name in properties) {
			if (properties.hasOwnProperty(name)) {
				let value =  properties[name].value;
				
				if (value !== undefined)
					obj[name] = value;
			}
		}
		
		let json = JSON.stringify({"state":obj});
		
		// for server-sent event stream
		message = "data: "+ message.replace(/\n/g, '\ndata: ') + "\n\n";
		let clients = thing.clients;

		for (var id in clients) {
			if (clients.hasOwnProperty(id)) {
				let client = clients[id];
				client.response.write(message);
			}
		}

		let sockets = thing.sockets;
		
		for (let i = 0; i < sockets.length; ++i) {
			ws_send(sockets[i], JSON.stringify(json));
		}
	};
	
	for (name in properties) {
		if (properties.hasOwnProperty(name)) {
			thing.properties[name] = new ThingProperty(thing, name, properties[name]);
		}
	}
	
	for (name in actions) {
		if (actions.hasOwnProperty(name)) {
			thing.actions[name] = new ThingAction(thing, name, actions[name]);
		}
	}
	
	for (name in events) {
		if (events.hasOwnProperty(name)) {
			thing.events[name] = new ThingEvent(thing, name, events[name]);
		}
	}
				
	thing.setActionHandler = function (name, handler) {
		if (thing.actions[name])
			thing.actions[name].handler = handler;
	};
	
	thing.setWriteHandler = function (name, handler) {
		if (thing.properties[name])
			thing.properties[name].handler = handler;
	};
	
	thing.receive = function (socket, message) {
		// handle incoming web socket message
		
		// be safe against zero length messages
		if (message.length === 0)
			return;
			
		let fail = (id, status, description) => {
			if (typeof id !== "string")
				id = "unknown";
				
			console.log('fail: ' + id + ' ' + status + ' ' + description);
			let json = {
				id: id,
				status: status
			};
			
			if (description !== undefined)
				json.description = description;
				
			ws_send(socket, JSON.stringify(json));
		};
		
		let succeed = (id, json) => {
			if (json) {
				json.id = id;
				json.status = 200;
			} else {
				console.log('succeed with no data to return');
				json = {
					id: id,
					status: 200
				};
			}

			ws_send(socket, JSON.stringify(json));
		};
		
		try {
			let json = JSON.parse(message);
			
			if (json.property) {
				let property = thing.properties[json.property];
				
				if (property !== undefined) {
					try {
						property.write(json.data);
						console.log("write succeeded");
						succeed(json.id);
					} catch (err) {
						console.log("couldn't write " + json.data + ' to ' + property.name);
						fail(json.id, 400, "bad request");
					}
				} else {
					console.log("message with undefined property");
					fail(json.id, 400, "bad request");
				}
			} else if (json.state !== undefined) {
				let obj = json.state;
				let properties = thing.properties;
				
				for (name in obj) {
					if (obj.hasOwnProperty(name) && properties.hasOwnProperty(name)) {
						try {
							properties[name].write(obj[name]);
						} catch (err) {
							console.log("couldn't write " + obj[name] + ' to ' + name);
							return fail(json.id, 400, "bad request");
						}
					}
				}
				succeed(json.id);
			} else if (json.action !== undefined) {
				let action = thing.actions[json.action];
				
				if (action !== undefined) {
					action.invoke(json.input)
						.then(output => {
							console.log('output is ' + JSON.stringify(output));
							if (output !== undefined)
								succeed(json.id, {'output':output});
							else
								succeed(json.id);
						}).catch(err => {
							fail(json.id, 500, "action failed");
						});
				} else {
					fail(json.id, 400, "bad request");
				}
			} else {
				fail(json.id, 400, "bad request");
			}
			
		} catch (err) {
			console.log('badly formed client message: ' + message);
			fail(socket, 444, "badly formed client message");
		}
	};
	
	// used to attach a new web socket
	thing.addSocket = function(socket) {
		thing.sockets.push(socket);
		//.log('addSocket: there are ' + thing.sockets.length + ' sockets');
		
		socket.on('close', () => {
			// drop socket from thing.sockets
			let sockets = thing.sockets;
			const index = sockets.indexOf(socket);

			if (index !== -1) {
				sockets.splice(index, 1);
			};
		});
		
		// send state of all properties to sync new client
		let state = {};
		let properties = thing.properties;
		
		for (let name in properties) {
			if (properties.hasOwnProperty(name)) {
				state[name] = properties[name].value;
			}
		}
		
		ws_send(socket, JSON.stringify({state: state}));
	};
	
	// why isn't this capability on the action itself?
	thing.addActionHandler = (name, handler) => {
		if (thing.actions.hasOwnProperty(name))
			thing.actions[name].handler = handler;
	};
	
	// sent text string to all clients via web sockets
	
	thing.send = function (data) {
		let sockets = thing.sockets;
		
		for (let i = 0; i < sockets.length; ++i) {
			ws_send(sockets[i], data);
		}
	};
	
	thing.expose = function () {
		let publish = (resolve, reject) => {
			things[thing.model.name] = thing;
			resolve(model);
		}
		
		return new Promise(function (resolve, reject) {
			publish(resolve, reject);
		});
	};
	
	//things[model.name] = thing;
	
	return thing;
}
574263
public void publish(Event event) {
        logger.debug("Dispatching event: " + event.getClass().toString());
        final ArrayList<Class<? extends Subscriber>> subscriberClasses = subscriptionMap.get(event.getClass());
        if (subscriberClasses == null) {
            logger.debug("No subscribers to inform from event: " + event.getClass().getName());
            return;
        }
        for (Class<? extends Subscriber> clazz: subscriberClasses) {
            logger.debug("Alerting subscriber " + clazz.getName());

            if (event instanceof ChainableEvent) {
                addTrackedEvent((ChainableEvent)event);
            }

            // Check to see if the Event is Unblocked. If so, use a separate executor pool from normal events
            final ExecutorService executorService = event instanceof UnblockedEvent  ? dynamicExecutor : executor;

            executorService.execute(() -> {
                try (AlpineQueryManager qm = new AlpineQueryManager()) {
                    final EventServiceLog eventServiceLog = qm.createEventServiceLog(clazz);
                    final Subscriber subscriber = clazz.getDeclaredConstructor().newInstance();
                    subscriber.inform(event);
                    qm.updateEventServiceLog(eventServiceLog);
                    if (event instanceof ChainableEvent) {
                        ChainableEvent chainableEvent = (ChainableEvent)event;
                        logger.debug("Calling onSuccess");
                        for (ChainLink chainLink: chainableEvent.onSuccess()) {
                            if (chainLink.getSuccessEventService() != null) {
                                Method method = chainLink.getSuccessEventService().getMethod("getInstance");
                                IEventService es = (IEventService) method.invoke(chainLink.getSuccessEventService(), new Object[0]);
                                es.publish(chainLink.getSuccessEvent());
                            } else {
                                Event.dispatch(chainLink.getSuccessEvent());
                            }
                        }
                    }
                } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException | SecurityException e) {
                    logger.error("An error occurred while informing subscriber: " + e);
                    if (event instanceof ChainableEvent) {
                        ChainableEvent chainableEvent = (ChainableEvent)event;
                        logger.debug("Calling onFailure");
                        for (ChainLink chainLink: chainableEvent.onFailure()) {
                            if (chainLink.getFailureEventService() != null) {
                                try {
                                    Method method = chainLink.getFailureEventService().getMethod("getInstance");
                                    IEventService es = (IEventService) method.invoke(chainLink.getFailureEventService(), new Object[0]);
                                    es.publish(chainLink.getFailureEvent());
                                } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ex) {
                                    logger.error("Exception while calling onFailure callback", ex);
                                }
                            } else {
                                Event.dispatch(chainLink.getFailureEvent());
                            }
                        }
                    }
                }

                if (event instanceof ChainableEvent) {
                    removeTrackedEvent((ChainableEvent)event);
                }

            });
        }
    }
1188806
function() {

		// Create an object which inherits its parent as the prototype and constructs a new event chain.
		var _this = this;
		var utils = _this.utils;
		var error = utils.error;
		var promise = utils.Promise();

		// Get parameters
		var p = utils.args({network: 's', options: 'o', callback: 'f'}, arguments);

		// Local vars
		var url;

		// Get all the custom options and store to be appended to the querystring
		var qs = utils.diffKey(p.options, _this.settings);

		// Merge/override options with app defaults
		var opts = p.options = utils.merge(_this.settings, p.options || {});

		// Merge/override options with app defaults
		opts.popup = utils.merge(_this.settings.popup, p.options.popup || {});

		// Network
		p.network = p.network || _this.settings.default_service;

		// Bind callback to both reject and fulfill states
		promise.proxy.then(p.callback, p.callback);

		// Trigger an event on the global listener
		function emit(s, value) {
			hello.emit(s, value);
		}

		promise.proxy.then(emit.bind(this, 'auth.login auth'), emit.bind(this, 'auth.failed auth'));

		// Is our service valid?
		if (typeof (p.network) !== 'string' || !(p.network in _this.services)) {
			// Trigger the default login.
			// Ahh we dont have one.
			return promise.reject(error('invalid_network', 'The provided network was not recognized'));
		}

		var provider = _this.services[p.network];

		// Create a global listener to capture events triggered out of scope
		var callbackId = utils.globalEvent(function(obj) {

			// The responseHandler returns a string, lets save this locally
			if (obj) {
				if (typeof (obj) == 'string') {
					obj = JSON.parse(obj);
				}
			}
			else {
				obj = error('cancelled', 'The authentication was not completed');
			}

			// Handle these response using the local
			// Trigger on the parent
			if (!obj.error) {

				// Save on the parent window the new credentials
				// This fixes an IE10 bug i think... atleast it does for me.
				utils.store(obj.network, obj);

				// Fulfill a successful login
				promise.fulfill({
					network: obj.network,
					authResponse: obj
				});
			}
			else {
				// Reject a successful login
				promise.reject(obj);
			}
		});

		var redirectUri = utils.url(opts.redirect_uri).href;

		// May be a space-delimited list of multiple, complementary types
		var responseType = provider.oauth.response_type || opts.response_type;

		// Fallback to token if the module hasn't defined a grant url
		if (/\bcode\b/.test(responseType) && !provider.oauth.grant) {
			responseType = responseType.replace(/\bcode\b/, 'token');
		}

		// Query string parameters, we may pass our own arguments to form the querystring
		p.qs = utils.merge(qs, {
			client_id: encodeURIComponent(provider.id),
			response_type: encodeURIComponent(responseType),
			redirect_uri: encodeURIComponent(redirectUri),
			state: {
				client_id: provider.id,
				network: p.network,
				display: opts.display,
				callback: callbackId,
				state: opts.state,
				redirect_uri: redirectUri
			}
		});

		// Get current session for merging scopes, and for quick auth response
		var session = utils.store(p.network);

		// Scopes (authentication permisions)
		// Ensure this is a string - IE has a problem moving Arrays between windows
		// Append the setup scope
		var SCOPE_SPLIT = /[,\s]+/;

		// Include default scope settings (cloned).
		var scope = _this.settings.scope ? [_this.settings.scope.toString()] : [];

		// Extend the providers scope list with the default
		var scopeMap = utils.merge(_this.settings.scope_map, provider.scope || {});

		// Add user defined scopes...
		if (opts.scope) {
			scope.push(opts.scope.toString());
		}

		// Append scopes from a previous session.
		// This helps keep app credentials constant,
		// Avoiding having to keep tabs on what scopes are authorized
		if (session && 'scope' in session && session.scope instanceof String) {
			scope.push(session.scope);
		}

		// Join and Split again
		scope = scope.join(',').split(SCOPE_SPLIT);

		// Format remove duplicates and empty values
		scope = utils.unique(scope).filter(filterEmpty);

		// Save the the scopes to the state with the names that they were requested with.
		p.qs.state.scope = scope.join(',');

		// Map scopes to the providers naming convention
		scope = scope.map(function(item) {
			// Does this have a mapping?
			return (item in scopeMap) ? scopeMap[item] : item;
		});

		// Stringify and Arrayify so that double mapped scopes are given the chance to be formatted
		scope = scope.join(',').split(SCOPE_SPLIT);

		// Again...
		// Format remove duplicates and empty values
		scope = utils.unique(scope).filter(filterEmpty);

		// Join with the expected scope delimiter into a string
		p.qs.scope = scope.join(provider.scope_delim || ',');

		// Is the user already signed in with the appropriate scopes, valid access_token?
		if (opts.force === false) {

			if (session && 'access_token' in session && session.access_token && 'expires' in session && session.expires > ((new Date()).getTime() / 1e3)) {
				// What is different about the scopes in the session vs the scopes in the new login?
				var diff = utils.diff((session.scope || '').split(SCOPE_SPLIT), (p.qs.state.scope || '').split(SCOPE_SPLIT));
				if (diff.length === 0) {

					// OK trigger the callback
					promise.fulfill({
						unchanged: true,
						network: p.network,
						authResponse: session
					});

					// Nothing has changed
					return promise;
				}
			}
		}

		// Page URL
		if (opts.display === 'page' && opts.page_uri) {
			// Add a page location, place to endup after session has authenticated
			p.qs.state.page_uri = utils.url(opts.page_uri).href;
		}

		// Bespoke
		// Override login querystrings from auth_options
		if ('login' in provider && typeof (provider.login) === 'function') {
			// Format the paramaters according to the providers formatting function
			provider.login(p);
		}

		// Add OAuth to state
		// Where the service is going to take advantage of the oauth_proxy
		if (!/\btoken\b/.test(responseType) ||
		parseInt(provider.oauth.version, 10) < 2 ||
		(opts.display === 'none' && provider.oauth.grant && session && session.refresh_token)) {

			// Add the oauth endpoints
			p.qs.state.oauth = provider.oauth;

			// Add the proxy url
			p.qs.state.oauth_proxy = opts.oauth_proxy;

		}

		// Convert state to a string
		p.qs.state = encodeURIComponent(JSON.stringify(p.qs.state));

		// URL
		if (parseInt(provider.oauth.version, 10) === 1) {

			// Turn the request to the OAuth Proxy for 3-legged auth
			url = utils.qs(opts.oauth_proxy, p.qs, encodeFunction);
		}

		// Refresh token
		else if (opts.display === 'none' && provider.oauth.grant && session && session.refresh_token) {

			// Add the refresh_token to the request
			p.qs.refresh_token = session.refresh_token;

			// Define the request path
			url = utils.qs(opts.oauth_proxy, p.qs, encodeFunction);
		}
		else {
			url = utils.qs(provider.oauth.auth, p.qs, encodeFunction);
		}

		// Broadcast this event as an auth:init
		emit('auth.init', p);

		// Execute
		// Trigger how we want self displayed
		if (opts.display === 'none') {
			// Sign-in in the background, iframe
			utils.iframe(url, redirectUri);
		}

		// Triggering popup?
		else if (opts.display === 'popup') {

			var popup = utils.popup(url, redirectUri, opts.popup);

			var timer = setInterval(function() {
				if (!popup || popup.closed) {
					clearInterval(timer);
					if (!promise.state) {

						var response = error('cancelled', 'Login has been cancelled');

						if (!popup) {
							response = error('blocked', 'Popup was blocked');
						}

						response.network = p.network;

						promise.reject(response);
					}
				}
			}, 100);
		}

		else {
			window.location = url;
		}

		return promise.proxy;

		function encodeFunction(s) {return s;}

		function filterEmpty(s) {return !!s;}
	}
702705
function CustomEvent(type, params) {
  const e = document.createEvent('CustomEvent');

  if (params) {
    e.initCustomEvent(type, params.bubbles, params.cancelable, params.detail);
  } else {
    e.initCustomEvent(type, false, false, undefined);
  }

  return e;
}
572764
function Client(options) {
  events.EventEmitter.call(this);
  //Unlimited amount of listeners for internal event queues by default
  this.setMaxListeners(0);
  this.options = utils.extend({}, optionsDefault, options);
  //current connection index
  this.connectionIndex = 0;
  //current connection index for prepared queries
  this.prepareConnectionIndex = 0;
  this.preparedQueries = {};
  
  this._createPool();
}
1256400
function MediaObject(){
  MediaObject.super_.call(this);


  var self = this;


  //
  // Define object properties
  //

  /**
   * Unique identifier of this object
   *
   * @public
   * @readonly
   * @member {external:Number} id
   */
  this.once('_id', function(error, id)
  {
    if(error)
      return Object.defineProperties(this,
      {
        '_createError': {value: error},
        'id': {value: null, enumerable: true}
      });

    Object.defineProperty(this, 'id',
    {
      configurable: true,
      enumerable: true,
      value: id
    });
  })

  //
  // Subscribe and unsubscribe events on the server when adding and removing
  // event listeners on this MediaObject
  //

  var subscriptions = {};

  this.on('removeListener', function(event, listener)
  {
    // Blacklisted events
    if(event[0] == '_'
    || event == 'release'
    || event == 'newListener')
      return;

    var count = EventEmitter.listenerCount(this, event);
    if(count) return;

    var token = subscriptions[event];

    var params =
    {
      object: this,
      subscription: token
    };

    this.emit('_rpc', undefined, 'unsubscribe', params, function(error)
    {
      if(error) return self.emit('error', error);

      delete subscriptions[event];
    });
  });

  this.on('newListener', function(event, listener)
  {
    // Blacklisted events
    if(event[0] == '_'
    || event == 'release')
      return;

    var constructor = this.constructor;

    if(constructor.events.indexOf(event) < 0)
      throw new SyntaxError(constructor.name+" doesn't accept events of type '"+event+"'")

    var count = EventEmitter.listenerCount(this, event);
    if(count) return;

    var params =
    {
      object: this,
      type: event
    };

    this.emit('_rpc', undefined, 'subscribe', params, function(error, token)
    {
      if(error) return self.emit('error', error);

      subscriptions[event] = token;
    });
  });
}
107313
public static ServerSentEvent withEventIdAndType(ByteBuf eventId, ByteBuf eventType, ByteBuf data) {
        return new ServerSentEvent(eventId, eventType, data);
    }
1176738
protected void publishWanEvent(String mapName, ReplicationEventObject event) {
        MapContainer mapContainer = mapServiceContext.getMapContainer(mapName);
        WanReplicationPublisher wanReplicationPublisher = mapContainer.getWanReplicationPublisher();
        if (isOwnedPartition(event.getKey())) {
            wanReplicationPublisher.publishReplicationEvent(SERVICE_NAME, event);
        } else {
            wanReplicationPublisher.publishReplicationEventBackup(SERVICE_NAME, event);
        }
    }
937882
public void publishEvent(@Observes Object event) throws IOException {
        Class<?> eventType = event.getClass();
        LOGGER.debug("Receiving event of type {}", eventType.getSimpleName());
        if (! publisherConfigurations.containsKey(eventType)) {
            LOGGER.debug("No publisher configured for event of type {}", eventType.getSimpleName());
            return;
        }
        PublisherConfiguration publisherConfiguration = publisherConfigurations.get(eventType);
        MessagePublisher publisher = providePublisher(publisherConfiguration.reliability, eventType);
        Message message = buildMessage(publisherConfiguration, event);
        try {
            LOGGER.info("Publishing event of type {}", eventType.getSimpleName());
            publisher.publish(message, publisherConfiguration.deliveryOptions);
            LOGGER.info("Successfully published event of type {}", eventType.getSimpleName());
        } catch (IOException e) {
            LOGGER.error("Failed to publish event {}", eventType.getSimpleName(), e);
            throw e;
        }
    }
1045597
private void publishEvent(WSJobInstance objectToPublish, String eventToPublishTo, String correlationId) {
        if (eventsPublisher != null) {
            eventsPublisher.publishJobInstanceEvent(objectToPublish, eventToPublishTo, correlationId);
        }
    }
323381
function subscribeToEvents() {
    const socket = _socket.get(this);

    function onEventApiError(error) {
        dbg('Event API connection error: ' + JSON.stringify(error));
    }

    socket.on('pong', (latency) => {
        dbg(`Event API latency: ${latency} ms`);
    });
    socket.on('connect_error', onEventApiError);
    socket.on('error', onEventApiError);
    socket.on('disconnect', onEventApiError);
    socket.on('reconnect_error', onEventApiError);
    socket.on('reconnect_failed', () => {
        onEventApiError('Reconnecting to the Event API failed');
    });

    socket.on('new_receipt', receiptJSON => {
        const receipt = Receipt.from(receiptJSON, _provider.get(this));
        _eventEmitter.get(this).emit(EventNames.newReceipt, receipt);
    });
}