## Copyright 2007-2008 Cisco Systems Inc.
##
## Licensed 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 = "client")
#set($peerclass = "Remote${i}Client")
#else
#set($peer = "server")
#set($peerclass = "Remote${i}Server")
#end

using System;
#if ($helper.isServer($mc))

using Org.Apache.Etch.Bindings.Csharp.Support;
using Org.Apache.Etch.Bindings.Csharp.Util;

using ${intf.parent().name()}.types.${i};
#else

using ${intf.parent().name()}.types.${i};
#end 

namespace $intf.parent().name()
{
#if ($helper.isServer($mc))
	///<summary>Main implementation for ${i}Listener.</summary>
#else
	///<summary>Main implementation for $i$suffix.</summary>
#end
#if ($helper.isServer($mc))
	public class Main${i}Listener : ${i}Helper.${i}ServerFactory
#else
	public class Main${i}Client : ${i}Helper.${i}ClientFactory
#end
	{
#if ($helper.isServer($mc))
 		///<summary>Main for ${i}Listener.</summary>
#else
		///<summary>Main for ${i}Client</summary>
#end
		///<param name="args">Command Line Arguments</param>
		public static void Main(String[] args)
		{
			// TODO: Change to correct URI
			string uri = "tcp://localhost:4001";
			
#if ($helper.isServer($mc))
			ServerFactory listener = ${i}Helper.NewListener( uri, null, new Main${i}Listener());
			
			// Start the Listener
			listener.TransportControl( TransportConsts.START_AND_WAIT_UP, 4000 );
#else
			Remote${i}Server server = ${i}Helper.NewServer( uri, null, new Main${i}Client());
		
			// Connect to the service
			server._StartAndWaitUp( 4000 );

			// TODO: Insert Your Code Here

			// Disconnect from the service
			server._StopAndWaitDown( 4000 );			
#end
		}

#if ($helper.isServer($mc))
		///<summary>Return a new instance of ${i}Server.</summary>
		///<param name="client">Reference to remote service</param>
		///<returns>Server Implementation</returns>
		public ${i}Server New${i}Server( Remote${i}Client client )
		{
			return new Impl${i}Server( client );
		}
#else
		///<summary>Return a new instance of ${i}Client.</summary>
		///<param name="server">Reference to remote service</param>
		///<returns>Client Implementation</returns>
		public ${i}Client New${i}Client( Remote${i}Server server )
		{
			return new Impl${i}Client( server );
		}
#end
	}
}