func (s *messageReceiver) call(name, method string, value []byte, inParamsType mojom_types.MojomStruct, outParamsType *mojom_types.MojomStruct) ([]byte, error) {
	s.ctx.Infof("server: %s.%s: %#v", name, method, inParamsType)
	inVType, err := transcoder.MojomStructToVDLType(inParamsType, s.header.desc)
	if err != nil {
		return nil, err
	}

	// Decode the vom.RawBytes from the mojom bytes and mojom type.
	target := util.StructSplitTarget()
	if err := transcoder.FromMojo(target, value, inVType); err != nil {
		return nil, fmt.Errorf("transcoder.FromMojo failed: %v", err)
	}

	// inVdlValue is a struct, but we need to send []interface.
	inargs := target.Fields()
	inargsIfc := make([]interface{}, len(inargs))
	for i := range inargs {
		inargsIfc[i] = inargs[i]
	}

	// We know that the v23serverproxy will give us back a bunch of
	// data in []interface{}. so we'll want to decode them into *vom.RawBytes.
	s.ctx.Infof("%s %v", method, outParamsType)
	var numParams int
	if outParamsType != nil {
		numParams = len(outParamsType.Fields)
	}
	outargs := make([]*vom.RawBytes, numParams)
	outptrs := make([]interface{}, len(outargs))
	for i := range outargs {
		outptrs[i] = &outargs[i]
	}

	// Now, run the call without any authorization.
	if err := v23.GetClient(s.ctx).Call(s.ctx, name, method, inargsIfc, outptrs, options.ServerAuthorizer{security.AllowEveryone()}); err != nil {
		return nil, err
	}

	if outParamsType == nil {
		return nil, nil
	}

	outVType, err := transcoder.MojomStructToVDLType(*outParamsType, s.header.desc)
	if err != nil {
		return nil, err
	}

	toMojoTarget := transcoder.ToMojomTarget()
	if err := util.JoinRawBytesAsStruct(toMojoTarget, outVType, outargs); err != nil {
		return nil, err
	}
	return toMojoTarget.Bytes(), nil
}
// callRemoteMethod calls the method remotely in a generic way.
// Produces []*vom.RawBytes at the end for the invoker to return.
func (fs fakeService) callRemoteMethod(ctx *context.T, method string, mi mojom_types.MojomInterface, desc map[string]mojom_types.UserDefinedType, argptrs []interface{}) ([]*vom.RawBytes, error) {
	// We need to parse the signature result to get the method relevant info out.
	found := false
	var ordinal uint32
	for ord, mm := range mi.Methods {
		if *mm.DeclData.ShortName == method {
			ordinal = ord
			found = true
			break
		}
	}

	if !found {
		return nil, fmt.Errorf("callRemoteMethod: method %s does not exist", method)
	}

	mm := mi.Methods[ordinal]

	// A void function must have request id of 0, whereas one with response params
	// should  have a unique request id.
	header := bindings.MessageHeader{
		Type:      ordinal,
		Flags:     bindings.MessageExpectsResponseFlag,
		RequestId: fs.ids.Count(),
	}

	// Now produce the *bindings.Message that we will send to the other side.
	inType, err := transcoder.MojomStructToVDLType(mm.Parameters, desc)
	if err != nil {
		return nil, err
	}
	message, err := encodeMessageFromVom(header, argptrs, inType)
	if err != nil {
		return nil, err
	}

	// Otherwise, make a generic call with the message.
	outMessage, err := fs.callRemoteWithResponse(ctx, message)
	if err != nil {
		return nil, err
	}

	// Decode the *vom.RawBytes from the mojom bytes and mojom type.
	outType, err := transcoder.MojomStructToVDLType(*mm.ResponseParams, desc)
	if err != nil {
		return nil, err
	}
	target := util.StructSplitTarget()
	if err := transcoder.FromMojo(target, outMessage.Payload, outType); err != nil {
		return nil, fmt.Errorf("transcoder.FromMojo failed: %v", err)
	}
	return target.Fields(), nil
}