context: // **********************************************************************
  //
  // Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
  //
  // This copy of Ice is licensed to you under the terms described in the
  // ICE_LICENSE file included in this distribution.
  //
  // **********************************************************************
  
  using System;
  using System.Collections.Generic;
  using System.Threading;
  using System.Threading.Tasks;
  
  using Test;
  
  public sealed class MyDerivedClassI : Test.MyDerivedClassDisp_
  {
      private static void test(bool b)
      {
          if (!b)
          {
              throw new Exception();
          }
      }
  
      internal class Thread_opVoid : TaskCompletionSource<object>
      {
          public Thread_opVoid()
          {
          }
  
          public void Start()
          {
              lock(this)
              {
                  _thread = new Thread(new ThreadStart(Run));
                  _thread.Start();
              }
          }
  
          public void Run()
          {
              SetResult(null);
          }
  
          public void Join()
          {
              lock(this)
              {
                  _thread.Join();
              }
          }
  
          private Thread _thread;
      }
  
      //
      // Override the Object "pseudo" operations to verify the operation mode.
      //
      public override bool ice_isA(String id, Ice.Current current)
      {
          test(current.mode == Ice.OperationMode.Nonmutating);
          return base.ice_isA(id, current);
      }
  
      public override void ice_ping(Ice.Current current)
      {
          test(current.mode == Ice.OperationMode.Nonmutating);
          base.ice_ping(current);
      }
  
      public override string[] ice_ids(Ice.Current current)
      {
          test(current.mode == Ice.OperationMode.Nonmutating);
          return base.ice_ids(current);
      }
  
      public override string ice_id(Ice.Current current)
      {
          test(current.mode == Ice.OperationMode.Nonmutating);
          return base.ice_id(current);
      }
  
      public override Task shutdownAsync(Ice.Current current)
      {
          while(_opVoidThread != null)
          {
              _opVoidThread.Join();
              _opVoidThread = null;
          }
  
          current.adapter.getCommunicator().shutdown();
          return null;
      }
  
      public override Task opVoidAsync(Ice.Current current)
      {
          test(current.mode == Ice.OperationMode.Normal);
  
          while(_opVoidThread != null)
          {
              _opVoidThread.Join();
              _opVoidThread = null;
          }
  
          _opVoidThread = new Thread_opVoid();
          _opVoidThread.Start();
          return _opVoidThread.Task;
      }
  
      public override Task<MyClass_OpBoolResult> opBoolAsync(bool p1, bool p2, Ice.Current current)
      {
          return Task.FromResult<MyClass_OpBoolResult>(new MyClass_OpBoolResult(p2, p1));
      }
  
      public override Task<MyClass_OpBoolSResult> opBoolSAsync(bool[] p1, bool[] p2, Ice.Current current)
      {
          bool[] p3 = new bool[p1.Length + p2.Length];
          Array.Copy(p1, p3, p1.Length);
          Array.Copy(p2, 0, p3, p1.Length, p2.Length);
  
          bool[] r = new bool[p1.Length];
          for(int i = 0; i < p1.Length; i++)
          {
              r[i] = p1[p1.Length - (i + 1)];
          }
  
          return Task.FromResult<MyClass_OpBoolSResult>(new MyClass_OpBoolSResult(r, p3));
      }
  
      public override Task<MyClass_OpBoolSSResult>
      opBoolSSAsync(bool[][] p1, bool[][] p2, Ice.Current current)
      {
          bool[][] p3 = new bool[p1.Length + p2.Length][];
          Array.Copy(p1, p3, p1.Length);
          Array.Copy(p2, 0, p3, p1.Length, p2.Length);
  
          bool[][] r = new bool[p1.Length][];
          for(int i = 0; i < p1.Length; i++)
          {
              r[i] = p1[p1.Length - (i + 1)];
          }
  
          return Task.FromResult<MyClass_OpBoolSSResult>(new MyClass_OpBoolSSResult(r, p3));
      }
  
      public override Task<MyClass_OpByteResult>
      opByteAsync(byte p1, byte p2, Ice.Current current)
      {
          return Task.FromResult<MyClass_OpByteResult>(new MyClass_OpByteResult(p1, (byte)(p1 ^ p2)));
      }
  
      public override Task<MyClass_OpByteBoolDResult>
      opByteBoolDAsync(Dictionary<byte, bool> p1, Dictionary<byte, bool> p2, Ice.Current current)
      {
          Dictionary<byte, bool> p3 = p1;
          Dictionary<byte, bool> r = new Dictionary<byte, bool>();
          foreach(KeyValuePair<byte, bool> e in p1)
          {
              r[e.Key] = e.Value;
          }
          foreach(KeyValuePair<byte, bool> e in p2)
          {
              r[e.Key] = e.Value;
          }
  
          return Task.FromResult<MyClass_OpByteBoolDResult>(new MyClass_OpByteBoolDResult(r, p3));
      }
  
      public override Task<MyClass_OpByteSResult>
      opByteSAsync(byte[] p1, byte[] p2, Ice.Current current)
      {
          byte[] p3 = new byte[p1.Length];
          for(int i = 0; i < p1.Length; i++)
          {
              p3[i] = p1[p1.Length - (i + 1)];
          }
  
          byte[] r = new byte[p1.Length + p2.Length];
          Array.Copy(p1, r, p1.Length);
          Array.Copy(p2, 0, r, p1.Length, p2.Length);
  
          return Task.FromResult<MyClass_OpByteSResult>(new MyClass_OpByteSResult(r, p3));
      }
  
      public override Task<MyClass_OpByteSSResult>
      opByteSSAsync(byte[][] p1, byte[][] p2, Ice.Current current)
      {
          byte[][] p3 = new byte[p1.Length][];
          for(int i = 0; i < p1.Length; i++)
          {
              p3[i] = p1[p1.Length - (i + 1)];
          }
  
          byte[][] r = new byte[p1.Length + p2.Length][];
          Array.Copy(p1, r, p1.Length);
          Array.Copy(p2, 0, r, p1.Length, p2.Length);
  
          return Task.FromResult<MyClass_OpByteSSResult>(new MyClass_OpByteSSResult(r, p3));
      }
  
      public override Task<MyClass_OpFloatDoubleResult>
      opFloatDoubleAsync(float p1, double p2, Ice.Current current)
      {
          return Task.FromResult<MyClass_OpFloatDoubleResult>(new MyClass_OpFloatDoubleResult(p2, p1, p2));
      }
  
      public override Task<MyClass_OpFloatDoubleSResult>
      opFloatDoubleSAsync(float[] p1, double[] p2, Ice.Current current)
      {
          float[] p3 = p1;
  
          double[] p4 = new double[p2.Length];
          for(int i = 0; i < p2.Length; i++)
          {
              p4[i] = p2[p2.Length - (i + 1)];
          }
  
          double[] r = new double[p2.Length + p1.Length];
          Array.Copy(p2, r, p2.Length);
          for(int i = 0; i < p1.Length; i++)
          {
              r[p2.Length + i] = p1[i];
          }
  
          return Task.FromResult<MyClass_OpFloatDoubleSResult>(new MyClass_OpFloatDoubleSResult(r, p3, p4));
      }
  
      public override Task<MyClass_OpFloatDoubleSSResult>
      opFloatDoubleSSAsync(float[][] p1, double[][] p2, Ice.Current current)
      {
          var p3 = p1;
  
          var p4 = new double[p2.Length][];
          for(int i = 0; i < p2.Length; i++)
          {
              p4[i] = p2[p2.Length - (i + 1)];
          }
  
          var r = new double[p2.Length + p2.Length][];
          Array.Copy(p2, r, p2.Length);
          for(int i = 0; i < p2.Length; i++)
          {
              r[p2.Length + i] = new double[p2[i].Length];
              for(int j = 0; j < p2[i].Length; j++)
              {
                  r[p2.Length + i][j] = p2[i][j];
              }
          }
  
          return Task.FromResult<MyClass_OpFloatDoubleSSResult>(new MyClass_OpFloatDoubleSSResult(r, p3, p4));
      }
  
      public override Task<MyClass_OpLongFloatDResult>
      opLongFloatDAsync(Dictionary<long, float> p1, Dictionary<long, float> p2, Ice.Current current)
      {
          var p3 = p1;
          var r = new Dictionary<long, float>();
          foreach(KeyValuePair<long, float> e in p1)
          {
              r[e.Key] = e.Value;
          }
          foreach(KeyValuePair<long, float> e in p2)
          {
              r[e.Key] = e.Value;
          }
  
          return Task.FromResult<MyClass_OpLongFloatDResult>(new MyClass_OpLongFloatDResult(r, p3));
      }
  
      public override Task<MyClass_OpMyClassResult>
      opMyClassAsync(MyClassPrx p1, Ice.Current current)
      {
          var p2 = p1;
          var p3 = MyClassPrxHelper.uncheckedCast(current.adapter.createProxy(
                                                  Ice.Util.stringToIdentity("noSuchIdentity")));
          return Task.FromResult<MyClass_OpMyClassResult>(new MyClass_OpMyClassResult(
              MyClassPrxHelper.uncheckedCast(current.adapter.createProxy(current.id)), p2, p3));
      }
  
      public override Task<MyClass_OpMyEnumResult>
      opMyEnumAsync(MyEnum p1, Ice.Current current)
      {
          return Task.FromResult<MyClass_OpMyEnumResult>(new MyClass_OpMyEnumResult(MyEnum.enum3, p1));
      }
  
      public override Task<MyClass_OpShortIntDResult>
      opShortIntDAsync(Dictionary<short, int> p1, Dictionary<short, int> p2, Ice.Current current)
      {
          var p3 = p1;
          var r = new Dictionary<short, int>();
          foreach(KeyValuePair<short, int> e in p1)
          {
              r[e.Key] = e.Value;
          }
          foreach(KeyValuePair<short, int> e in p2)
          {
              r[e.Key] = e.Value;
          }
          return Task.FromResult<MyClass_OpShortIntDResult>(new MyClass_OpShortIntDResult(r, p3));
      }
  
      public override Task<MyClass_OpShortIntLongResult>
      opShortIntLongAsync(short p1, int p2, long p3, Ice.Current current)
      {
          return Task.FromResult<MyClass_OpShortIntLongResult>(new MyClass_OpShortIntLongResult(p3, p1, p2, p3));
      }
  
      public override Task<MyClass_OpShortIntLongSResult>
      opShortIntLongSAsync(short[] p1, int[] p2, long[] p3, Ice.Current current)
      {
          var p4 = p1;
          var p5 = new int[p2.Length];
          for(int i = 0; i < p2.Length; i++)
          {
              p5[i] = p2[p2.Length - (i + 1)];
          }
          var p6 = new long[p3.Length + p3.Length];
          Array.Copy(p3, p6, p3.Length);
          Array.Copy(p3, 0, p6, p3.Length, p3.Length);
          return Task.FromResult<MyClass_OpShortIntLongSResult>(new MyClass_OpShortIntLongSResult(p3, p4, p5, p6));
      }
  
      public override Task<MyClass_OpShortIntLongSSResult>
      opShortIntLongSSAsync(short[][] p1, int[][] p2, long[][] p3, Ice.Current current)
      {
          var p4 = p1;
  
          var p5 = new int[p2.Length][];
          for(int i = 0; i < p2.Length; i++)
          {
              p5[i] = p2[p2.Length - (i + 1)];
          }
  
          var p6 = new long[p3.Length + p3.Length][];
          Array.Copy(p3, p6, p3.Length);
          Array.Copy(p3, 0, p6, p3.Length, p3.Length);
          return Task.FromResult<MyClass_OpShortIntLongSSResult>(new MyClass_OpShortIntLongSSResult(p3, p4, p5, p6));
      }
  
      public override Task<MyClass_OpStringResult>
      opStringAsync(string p1, string p2, Ice.Current current)
      {
          return Task.FromResult<MyClass_OpStringResult>(new MyClass_OpStringResult(p1 + " " + p2, p2 + " " + p1));
      }
  
      public override Task<MyClass_OpStringMyEnumDResult>
      opStringMyEnumDAsync(Dictionary<string, MyEnum> p1, Dictionary<string, MyEnum> p2, Ice.Current current)
      {
          var p3 = p1;
          var r = new Dictionary<string, Test.MyEnum>();
          foreach(KeyValuePair<string, Test.MyEnum> e in p1)
          {
              r[e.Key] = e.Value;
          }
          foreach(KeyValuePair<string, Test.MyEnum> e in p2)
          {
              r[e.Key] = e.Value;
          }
          return Task.FromResult<MyClass_OpStringMyEnumDResult>(new MyClass_OpStringMyEnumDResult(r, p3));
      }
  
      public override Task<MyClass_OpMyEnumStringDResult>
      opMyEnumStringDAsync(Dictionary<MyEnum, string> p1, Dictionary<MyEnum, string> p2, Ice.Current current)
      {
          var p3 = p1;
          var r = new Dictionary<MyEnum, string>();
          foreach(var e in p1)
          {
              r[e.Key] = e.Value;
          }
          foreach(KeyValuePair<MyEnum, string> e in p2)
          {
              r[e.Key] = e.Value;
          }
          return Task.FromResult<MyClass_OpMyEnumStringDResult>(new MyClass_OpMyEnumStringDResult(r, p3));
      }
  
      public override Task<MyClass_OpMyStructMyEnumDResult>
      opMyStructMyEnumDAsync(Dictionary<MyStruct, MyEnum> p1,
                             Dictionary<MyStruct, MyEnum> p2, Ice.Current current)
      {
          var p3 = p1;
          var r = new Dictionary<MyStruct, MyEnum>();
          foreach(var e in p1)
          {
              r[e.Key] = e.Value;
          }
          foreach(var e in p2)
          {
              r[e.Key] = e.Value;
          }
          return Task.FromResult<MyClass_OpMyStructMyEnumDResult>(new MyClass_OpMyStructMyEnumDResult(r, p3));
      }
  
      public override Task<MyClass_OpByteBoolDSResult>
      opByteBoolDSAsync(Dictionary<byte, bool>[] p1, Dictionary<byte, bool>[] p2, Ice.Current current)
      {
          var p3 = new Dictionary<byte, bool>[p1.Length + p2.Length];
          Array.Copy(p2, p3, p2.Length);
          Array.Copy(p1, 0, p3, p2.Length, p1.Length);
  
          var r = new Dictionary<byte, bool>[p1.Length];
          for(int i = 0; i < p1.Length; i++)
          {
              r[i] = p1[p1.Length - (i + 1)];
          }
          return Task.FromResult<MyClass_OpByteBoolDSResult>(new MyClass_OpByteBoolDSResult(r, p3));
      }
  
      public override Task<MyClass_OpShortIntDSResult>
      opShortIntDSAsync(Dictionary<short, int>[] p1, Dictionary<short, int>[] p2, Ice.Current current)
      {
          var p3 = new Dictionary<short, int>[p1.Length + p2.Length];
          Array.Copy(p2, p3, p2.Length);
          Array.Copy(p1, 0, p3, p2.Length, p1.Length);
  
          var r = new Dictionary<short, int>[p1.Length];
          for(int i = 0; i < p1.Length; i++)
          {
              r[i] = p1[p1.Length - (i + 1)];
          }
          return Task.FromResult<MyClass_OpShortIntDSResult>(new MyClass_OpShortIntDSResult(r, p3));
      }
  
      public override Task<MyClass_OpLongFloatDSResult>
      opLongFloatDSAsync(Dictionary<long, float>[] p1, Dictionary<long, float>[] p2, Ice.Current current)
      {
          var p3 = new Dictionary<long, float>[p1.Length + p2.Length];
          Array.Copy(p2, p3, p2.Length);
          Array.Copy(p1, 0, p3, p2.Length, p1.Length);
  
          var r = new Dictionary<long, float>[p1.Length];
          for(int i = 0; i < p1.Length; i++)
          {
              r[i] = p1[p1.Length - (i + 1)];
          }
          return Task.FromResult<MyClass_OpLongFloatDSResult>(new MyClass_OpLongFloatDSResult(r, p3));
      }
  
      public override Task<MyClass_OpStringStringDSResult>
      opStringStringDSAsync(Dictionary<string, string>[] p1, Dictionary<string, string>[] p2, Ice.Current current)
      {
          var p3 = new Dictionary<string, string>[p1.Length + p2.Length];
          Array.Copy(p2, p3, p2.Length);
  
gt:         Array.Copy(p1, 0, p3, p2.Length, p1.Length);