function Host(address, protocolVersion, options, metadata) {
  events.EventEmitter.call(this);
  /**
   * Gets ip address and port number of the node separated by `:`.
   * @type {String}
   */
  this.address = address;
  this.setDownAt = 0;

  /**
   * Gets the timestamp of the moment when the Host was marked as UP.
   * @type {Number|null}
   * @ignore
   * @internal
   */
  this.isUpSince = null;

  Object.defineProperty(this, 'options', { value: options, enumerable: false, writable: false});

  /**
   * The host pool.
   * @internal
   * @ignore
   * @type {HostConnectionPool}
   */
  Object.defineProperty(this, 'pool', { value: new HostConnectionPool(this, protocolVersion), enumerable: false});

  const self = this;
  this.pool.on('open', this._onNewConnectionOpen.bind(this));
  this.pool.on('remove', function onConnectionRemovedFromPool() {
    self._checkPoolState();
  });
  /**
   * Gets string containing the Cassandra version.
   * @type {String}
   */
  this.cassandraVersion = null;
  /**
   * Gets data center name of the node.
   * @type {String}
   */
  this.datacenter = null;
  /**
   * Gets rack name of the node.
   * @type {String}
   */
  this.rack = null;
  /**
   * Gets the tokens assigned to the node.
   * @type {Array}
   */
  this.tokens = null;

  /**
   * Gets the id of the host.
   * <p>This identifier is used by the server for internal communication / gossip.</p>
   * @type {Uuid}
   */
  this.hostId = null;

  // the distance as last set using the load balancing policy
  this._distance = types.distance.ignored;
  this._healthResponseCounter = 0;

  // Make some of the private instance variables not enumerable to prevent from showing when inspecting
  Object.defineProperty(this, '_metadata', { value: metadata, enumerable: false });
  Object.defineProperty(this, '_healthResponseCountTimer', { value: null, enumerable: false, writable: true });

  this.reconnectionSchedule = this.options.policies.reconnection.newSchedule();
  this.reconnectionDelay = 0;
}