|  | @@ -42,7 +42,9 @@ var _ = require('lodash');
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  var grpc = require('bindings')('grpc.node');
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -var common = require('./common.js');
 | 
	
		
			
				|  |  | +var common = require('./common');
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +var Metadata = require('./metadata');
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  var EventEmitter = require('events').EventEmitter;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -254,8 +256,7 @@ function makeUnaryRequestFunction(method, serialize, deserialize) {
 | 
	
		
			
				|  |  |     *     serialize
 | 
	
		
			
				|  |  |     * @param {function(?Error, value=)} callback The callback to for when the
 | 
	
		
			
				|  |  |     *     response is received
 | 
	
		
			
				|  |  | -   * @param {array=} metadata Array of metadata key/value pairs to add to the
 | 
	
		
			
				|  |  | -   *     call
 | 
	
		
			
				|  |  | +   * @param {Metadata=} metadata Metadata to add to the call
 | 
	
		
			
				|  |  |     * @param {Object=} options Options map
 | 
	
		
			
				|  |  |     * @return {EventEmitter} An event emitter for stream related events
 | 
	
		
			
				|  |  |     */
 | 
	
	
		
			
				|  | @@ -264,7 +265,9 @@ function makeUnaryRequestFunction(method, serialize, deserialize) {
 | 
	
		
			
				|  |  |      var emitter = new EventEmitter();
 | 
	
		
			
				|  |  |      var call = getCall(this.channel, method, options);
 | 
	
		
			
				|  |  |      if (metadata === null || metadata === undefined) {
 | 
	
		
			
				|  |  | -      metadata = {};
 | 
	
		
			
				|  |  | +      metadata = new Metadata();
 | 
	
		
			
				|  |  | +    } else {
 | 
	
		
			
				|  |  | +      metadata = metadata.clone();
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      emitter.cancel = function cancel() {
 | 
	
		
			
				|  |  |        call.cancel();
 | 
	
	
		
			
				|  | @@ -281,7 +284,8 @@ function makeUnaryRequestFunction(method, serialize, deserialize) {
 | 
	
		
			
				|  |  |        var client_batch = {};
 | 
	
		
			
				|  |  |        var message = serialize(argument);
 | 
	
		
			
				|  |  |        message.grpcWriteFlags = options.flags;
 | 
	
		
			
				|  |  | -      client_batch[grpc.opType.SEND_INITIAL_METADATA] = metadata;
 | 
	
		
			
				|  |  | +      client_batch[grpc.opType.SEND_INITIAL_METADATA] =
 | 
	
		
			
				|  |  | +          metadata._getCoreRepresentation();
 | 
	
		
			
				|  |  |        client_batch[grpc.opType.SEND_MESSAGE] = message;
 | 
	
		
			
				|  |  |        client_batch[grpc.opType.SEND_CLOSE_FROM_CLIENT] = true;
 | 
	
		
			
				|  |  |        client_batch[grpc.opType.RECV_INITIAL_METADATA] = true;
 | 
	
	
		
			
				|  | @@ -292,7 +296,8 @@ function makeUnaryRequestFunction(method, serialize, deserialize) {
 | 
	
		
			
				|  |  |          if (response.status.code !== grpc.status.OK) {
 | 
	
		
			
				|  |  |            var error = new Error(response.status.details);
 | 
	
		
			
				|  |  |            error.code = response.status.code;
 | 
	
		
			
				|  |  | -          error.metadata = response.status.metadata;
 | 
	
		
			
				|  |  | +          error.metadata = Metadata._fromCoreRepresentation(
 | 
	
		
			
				|  |  | +              response.status.metadata);
 | 
	
		
			
				|  |  |            callback(error);
 | 
	
		
			
				|  |  |            return;
 | 
	
		
			
				|  |  |          } else {
 | 
	
	
		
			
				|  | @@ -302,7 +307,8 @@ function makeUnaryRequestFunction(method, serialize, deserialize) {
 | 
	
		
			
				|  |  |              return;
 | 
	
		
			
				|  |  |            }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        emitter.emit('metadata', response.metadata);
 | 
	
		
			
				|  |  | +        emitter.emit('metadata', Metadata._fromCoreRepresentation(
 | 
	
		
			
				|  |  | +            response.metadata));
 | 
	
		
			
				|  |  |          callback(null, deserialize(response.read));
 | 
	
		
			
				|  |  |        });
 | 
	
		
			
				|  |  |      });
 | 
	
	
		
			
				|  | @@ -326,7 +332,7 @@ function makeClientStreamRequestFunction(method, serialize, deserialize) {
 | 
	
		
			
				|  |  |     * @this {Client} Client object. Must have a channel member.
 | 
	
		
			
				|  |  |     * @param {function(?Error, value=)} callback The callback to for when the
 | 
	
		
			
				|  |  |     *     response is received
 | 
	
		
			
				|  |  | -   * @param {array=} metadata Array of metadata key/value pairs to add to the
 | 
	
		
			
				|  |  | +   * @param {Metadata=} metadata Array of metadata key/value pairs to add to the
 | 
	
		
			
				|  |  |     *     call
 | 
	
		
			
				|  |  |     * @param {Object=} options Options map
 | 
	
		
			
				|  |  |     * @return {EventEmitter} An event emitter for stream related events
 | 
	
	
		
			
				|  | @@ -335,7 +341,9 @@ function makeClientStreamRequestFunction(method, serialize, deserialize) {
 | 
	
		
			
				|  |  |      /* jshint validthis: true */
 | 
	
		
			
				|  |  |      var call = getCall(this.channel, method, options);
 | 
	
		
			
				|  |  |      if (metadata === null || metadata === undefined) {
 | 
	
		
			
				|  |  | -      metadata = {};
 | 
	
		
			
				|  |  | +      metadata = new Metadata();
 | 
	
		
			
				|  |  | +    } else {
 | 
	
		
			
				|  |  | +      metadata = metadata.clone();
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      var stream = new ClientWritableStream(call, serialize);
 | 
	
		
			
				|  |  |      this.updateMetadata(this.auth_uri, metadata, function(error, metadata) {
 | 
	
	
		
			
				|  | @@ -345,7 +353,8 @@ function makeClientStreamRequestFunction(method, serialize, deserialize) {
 | 
	
		
			
				|  |  |          return;
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |        var metadata_batch = {};
 | 
	
		
			
				|  |  | -      metadata_batch[grpc.opType.SEND_INITIAL_METADATA] = metadata;
 | 
	
		
			
				|  |  | +      metadata_batch[grpc.opType.SEND_INITIAL_METADATA] =
 | 
	
		
			
				|  |  | +          metadata._getCoreRepresentation();
 | 
	
		
			
				|  |  |        metadata_batch[grpc.opType.RECV_INITIAL_METADATA] = true;
 | 
	
		
			
				|  |  |        call.startBatch(metadata_batch, function(err, response) {
 | 
	
		
			
				|  |  |          if (err) {
 | 
	
	
		
			
				|  | @@ -353,7 +362,8 @@ function makeClientStreamRequestFunction(method, serialize, deserialize) {
 | 
	
		
			
				|  |  |            // in the other batch.
 | 
	
		
			
				|  |  |            return;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        stream.emit('metadata', response.metadata);
 | 
	
		
			
				|  |  | +        stream.emit('metadata', Metadata._fromCoreRepresentation(
 | 
	
		
			
				|  |  | +            response.metadata));
 | 
	
		
			
				|  |  |        });
 | 
	
		
			
				|  |  |        var client_batch = {};
 | 
	
		
			
				|  |  |        client_batch[grpc.opType.RECV_MESSAGE] = true;
 | 
	
	
		
			
				|  | @@ -363,7 +373,8 @@ function makeClientStreamRequestFunction(method, serialize, deserialize) {
 | 
	
		
			
				|  |  |          if (response.status.code !== grpc.status.OK) {
 | 
	
		
			
				|  |  |            var error = new Error(response.status.details);
 | 
	
		
			
				|  |  |            error.code = response.status.code;
 | 
	
		
			
				|  |  | -          error.metadata = response.status.metadata;
 | 
	
		
			
				|  |  | +          error.metadata = Metadata._fromCoreRepresentation(
 | 
	
		
			
				|  |  | +              response.status.metadata);
 | 
	
		
			
				|  |  |            callback(error);
 | 
	
		
			
				|  |  |            return;
 | 
	
		
			
				|  |  |          } else {
 | 
	
	
		
			
				|  | @@ -396,7 +407,7 @@ function makeServerStreamRequestFunction(method, serialize, deserialize) {
 | 
	
		
			
				|  |  |     * @this {SurfaceClient} Client object. Must have a channel member.
 | 
	
		
			
				|  |  |     * @param {*} argument The argument to the call. Should be serializable with
 | 
	
		
			
				|  |  |     *     serialize
 | 
	
		
			
				|  |  | -   * @param {array=} metadata Array of metadata key/value pairs to add to the
 | 
	
		
			
				|  |  | +   * @param {Metadata=} metadata Array of metadata key/value pairs to add to the
 | 
	
		
			
				|  |  |     *     call
 | 
	
		
			
				|  |  |     * @param {Object} options Options map
 | 
	
		
			
				|  |  |     * @return {EventEmitter} An event emitter for stream related events
 | 
	
	
		
			
				|  | @@ -405,7 +416,9 @@ function makeServerStreamRequestFunction(method, serialize, deserialize) {
 | 
	
		
			
				|  |  |      /* jshint validthis: true */
 | 
	
		
			
				|  |  |      var call = getCall(this.channel, method, options);
 | 
	
		
			
				|  |  |      if (metadata === null || metadata === undefined) {
 | 
	
		
			
				|  |  | -      metadata = {};
 | 
	
		
			
				|  |  | +      metadata = new Metadata();
 | 
	
		
			
				|  |  | +    } else {
 | 
	
		
			
				|  |  | +      metadata = metadata.clone();
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      var stream = new ClientReadableStream(call, deserialize);
 | 
	
		
			
				|  |  |      this.updateMetadata(this.auth_uri, metadata, function(error, metadata) {
 | 
	
	
		
			
				|  | @@ -417,7 +430,8 @@ function makeServerStreamRequestFunction(method, serialize, deserialize) {
 | 
	
		
			
				|  |  |        var start_batch = {};
 | 
	
		
			
				|  |  |        var message = serialize(argument);
 | 
	
		
			
				|  |  |        message.grpcWriteFlags = options.flags;
 | 
	
		
			
				|  |  | -      start_batch[grpc.opType.SEND_INITIAL_METADATA] = metadata;
 | 
	
		
			
				|  |  | +      start_batch[grpc.opType.SEND_INITIAL_METADATA] =
 | 
	
		
			
				|  |  | +          metadata._getCoreRepresentation();
 | 
	
		
			
				|  |  |        start_batch[grpc.opType.RECV_INITIAL_METADATA] = true;
 | 
	
		
			
				|  |  |        start_batch[grpc.opType.SEND_MESSAGE] = message;
 | 
	
		
			
				|  |  |        start_batch[grpc.opType.SEND_CLOSE_FROM_CLIENT] = true;
 | 
	
	
		
			
				|  | @@ -427,7 +441,8 @@ function makeServerStreamRequestFunction(method, serialize, deserialize) {
 | 
	
		
			
				|  |  |            // in the other batch.
 | 
	
		
			
				|  |  |            return;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        stream.emit('metadata', response.metadata);
 | 
	
		
			
				|  |  | +        stream.emit('metadata', Metadata._fromCoreRepresentation(
 | 
	
		
			
				|  |  | +            response.metadata));
 | 
	
		
			
				|  |  |        });
 | 
	
		
			
				|  |  |        var status_batch = {};
 | 
	
		
			
				|  |  |        status_batch[grpc.opType.RECV_STATUS_ON_CLIENT] = true;
 | 
	
	
		
			
				|  | @@ -436,7 +451,8 @@ function makeServerStreamRequestFunction(method, serialize, deserialize) {
 | 
	
		
			
				|  |  |          if (response.status.code !== grpc.status.OK) {
 | 
	
		
			
				|  |  |            var error = new Error(response.status.details);
 | 
	
		
			
				|  |  |            error.code = response.status.code;
 | 
	
		
			
				|  |  | -          error.metadata = response.status.metadata;
 | 
	
		
			
				|  |  | +          error.metadata = Metadata._fromCoreRepresentation(
 | 
	
		
			
				|  |  | +              response.status.metadata);
 | 
	
		
			
				|  |  |            stream.emit('error', error);
 | 
	
		
			
				|  |  |            return;
 | 
	
		
			
				|  |  |          } else {
 | 
	
	
		
			
				|  | @@ -466,7 +482,7 @@ function makeBidiStreamRequestFunction(method, serialize, deserialize) {
 | 
	
		
			
				|  |  |    /**
 | 
	
		
			
				|  |  |     * Make a bidirectional stream request with this method on the given channel.
 | 
	
		
			
				|  |  |     * @this {SurfaceClient} Client object. Must have a channel member.
 | 
	
		
			
				|  |  | -   * @param {array=} metadata Array of metadata key/value pairs to add to the
 | 
	
		
			
				|  |  | +   * @param {Metadata=} metadata Array of metadata key/value pairs to add to the
 | 
	
		
			
				|  |  |     *     call
 | 
	
		
			
				|  |  |     * @param {Options} options Options map
 | 
	
		
			
				|  |  |     * @return {EventEmitter} An event emitter for stream related events
 | 
	
	
		
			
				|  | @@ -475,7 +491,9 @@ function makeBidiStreamRequestFunction(method, serialize, deserialize) {
 | 
	
		
			
				|  |  |      /* jshint validthis: true */
 | 
	
		
			
				|  |  |      var call = getCall(this.channel, method, options);
 | 
	
		
			
				|  |  |      if (metadata === null || metadata === undefined) {
 | 
	
		
			
				|  |  | -      metadata = {};
 | 
	
		
			
				|  |  | +      metadata = new Metadata();
 | 
	
		
			
				|  |  | +    } else {
 | 
	
		
			
				|  |  | +      metadata = metadata.clone();
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      var stream = new ClientDuplexStream(call, serialize, deserialize);
 | 
	
		
			
				|  |  |      this.updateMetadata(this.auth_uri, metadata, function(error, metadata) {
 | 
	
	
		
			
				|  | @@ -485,7 +503,8 @@ function makeBidiStreamRequestFunction(method, serialize, deserialize) {
 | 
	
		
			
				|  |  |          return;
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |        var start_batch = {};
 | 
	
		
			
				|  |  | -      start_batch[grpc.opType.SEND_INITIAL_METADATA] = metadata;
 | 
	
		
			
				|  |  | +      start_batch[grpc.opType.SEND_INITIAL_METADATA] =
 | 
	
		
			
				|  |  | +          metadata._getCoreRepresentation();
 | 
	
		
			
				|  |  |        start_batch[grpc.opType.RECV_INITIAL_METADATA] = true;
 | 
	
		
			
				|  |  |        call.startBatch(start_batch, function(err, response) {
 | 
	
		
			
				|  |  |          if (err) {
 | 
	
	
		
			
				|  | @@ -493,7 +512,8 @@ function makeBidiStreamRequestFunction(method, serialize, deserialize) {
 | 
	
		
			
				|  |  |            // in the other batch.
 | 
	
		
			
				|  |  |            return;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        stream.emit('metadata', response.metadata);
 | 
	
		
			
				|  |  | +        stream.emit('metadata', Metadata._fromCoreRepresentation(
 | 
	
		
			
				|  |  | +            response.metadata));
 | 
	
		
			
				|  |  |        });
 | 
	
		
			
				|  |  |        var status_batch = {};
 | 
	
		
			
				|  |  |        status_batch[grpc.opType.RECV_STATUS_ON_CLIENT] = true;
 | 
	
	
		
			
				|  | @@ -502,7 +522,8 @@ function makeBidiStreamRequestFunction(method, serialize, deserialize) {
 | 
	
		
			
				|  |  |          if (response.status.code !== grpc.status.OK) {
 | 
	
		
			
				|  |  |            var error = new Error(response.status.details);
 | 
	
		
			
				|  |  |            error.code = response.status.code;
 | 
	
		
			
				|  |  | -          error.metadata = response.status.metadata;
 | 
	
		
			
				|  |  | +          error.metadata = Metadata._fromCoreRepresentation(
 | 
	
		
			
				|  |  | +              response.status.metadata);
 | 
	
		
			
				|  |  |            stream.emit('error', error);
 | 
	
		
			
				|  |  |            return;
 | 
	
		
			
				|  |  |          } else {
 |