## 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 and should not be edited!
#set($i = $intf.name())

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

namespace $intf.parent().name()
{	
#foreach( $n in $intf.iterator() )
#if ($n.isExtern())
#if ($n.hasImport( $helper ))
#set($x = $n.getImport( $helper ))
#if (!$x.equals("Etch.Util"))
	using $x;
#end
#end
#end
#end

	///<summary> Message to call translator for $i$suffix. </summary>
	
#if ($hasBaseClass)
	public class Stub$i$suffix : Stub$i
#else
	public class Stub$i$suffix : StubBase
#end
	{
		/// <summary>Stub for $i$suffix.</summary>
		/// <param name="src">the delivery service to use.</param>
		/// <param name="obj"> the implementation of $i$suffix responsive to requests.</param>
		/// <param name="queued"> thread pool used to run AsyncReceiverMode.QUEUED methods.</param>
		/// <param name="free"> thread pool used to run AsyncReceiverMode.FREE methods.</param>		
		public Stub$i$suffix( DeliveryService src, object obj, Pool queued, Pool free )
			: base( src, obj, queued, free )
		{	
			// nothing to do.
		}
		
#if (!$hasBaseClass)
		public static void init()
#else
		public static new void init()
#end
		{
			// nothing to do.
		}

		static Stub$i$suffix()
		{
#foreach( $n in $intf.iterator() )
#if( $n.isMixin() )
#set( $m = $n.getModule() )
#set( $z = $m.iterator().next() )
			${m.name()}.Stub${z.name()}${suffix}.init();
#end
#end
#set( $stubHelperCount=0 )
#foreach( $mthd in $intf.iterator() )
#if ($mthd.isMsgDir($mc))
#if (!$mthd.isHidden())
#set($stubHelperCount = $stubHelperCount + 1)
			StubHelperRun helper$stubHelperCount = delegate( DeliveryService _src, object _obj, Who _sender, Message _msg ) 
				{
					try {
#foreach ($param in $mthd.iterator())
							$helper.getTypeName( $param.type() ) $param.name() = 
								($helper.getTypeName( $param.type() ))
								_msg.Get( ValueFactory$i.$param.vname( $helper ) );
#end

#if ($mthd.hasAuth())
#set( $auth = $mthd.getAuth() )
#if ($auth.isMethodFalse())
							if (true)
#else
							if ((bool)!(($i$suffix)_obj).${auth.method()}(
#set( $sep = "" )
#foreach($arg in $auth.args())
#if ($arg.isLiteralConstant())
								($helper.getNativeTypeName( $arg.type() )) $sep$helper.getTypeValue( $arg.type(), $arg.value() )
#elseif ($arg.isParameter( $mthd ))
								$sep$helper.qualifyParameterName( $arg.value() )
#elseif ($arg.isConstant( $intf ))
								$sep$helper.qualifyConstantName( $intf, $arg.value() )
#elseif ($arg.isEnum( $intf ))
								$sep$helper.qualifyEnumName( $intf, $arg.value() )
#else
								${sep}null
#end
#set( $sep = ", " )
#end
							)) 
#end
							throw new _Etch_AuthException( "$mthd.name()" );
#end

#if ($mthd.hasReturn())
							Object _result =
#end
								(($i$suffix)_obj).$mthd.name()(
#set( $sep = "" )
#foreach ($param in $mthd.iterator())
								$sep$param.name()
#set( $sep = ", " )
#end
								);
								
#if (!$mthd.isOneway())
							Message _rmsg = _msg.Reply();
#if ($mthd.hasReturn())
							_rmsg.Add( ValueFactory$i._mf_result, _result );
#end
							_src.TransportMessage( _sender, _rmsg );
#end
						}
						catch ( Exception e )
						{
#if (!$mthd.isOneway())
							Message _rmsg = _msg.Reply();
#else
							Message _rmsg = _msg.Reply( _msg.Vf.get_mt__exception() );
#end
							_rmsg.Add( ValueFactory$i._mf_result, e );
							_src.TransportMessage( _sender, _rmsg );
						}
					};
			ValueFactory$i.${mthd.vname( $helper )}.SetStubHelper( helper$stubHelperCount);		
#end
#end
#end
		}
	}
}

	