## Licensed to the Apache Software Foundation (ASF) under one
## or more contributor license agreements. See the NOTICE file
## distributed with this work for additional information
## regarding copyright ownership. The ASF licenses this file
## to you under the Apache License, Version 2.0 (the
## "License"); you may not use this file except in compliance
## with the License. You may obtain a copy of the License at
##
##   http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing,
## software distributed under the License is distributed on an
## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
## KIND, either express or implied. See the License for the
## specific language governing permissions and limitations
## under the License.
// This file automatically generated by:
//   $version
//   $now
// This file is automatically created for your convenience and will not be
// overwritten once it exists! Please edit this file as necessary to implement
// your service logic.
#set($i = $intf.name())
#set($intfname = "$i$suffix")
#set($baseclname = "Base$intfname")
#set($clname = "Impl$intfname")
#if ($helper.isServer($mc))
#set($peer = "mClient")
#set($peerclass = "Remote${i}Client")
#else
#set($peer = "mServer")
#set($peerclass = "Remote${i}Server")
#end

\#include "${clname}.h"

using namespace $namespace;

/**
 * Your custom implementation of $baseclname. Add methods here to provide
 * implementations of messages from the $peer.
 */

  $clname::$clname( $peerclass* $peer )
  {
    this->$peer = $peer;
  }

  // TODO insert methods here to provide implementations of $intfname
  // messages from the $peer.
