public async Task TradeGoodsForCurrencyTest()
        {
            var e1 = GrainFactory.GetGrain <IEmployee>(Guid.NewGuid());
            var e2 = GrainFactory.GetGrain <IEmployee>(Guid.NewGuid());
            await e1.AddCurrency(5);

            await e2.AddGoods(5);

            var transaction = new TransactionHelper <EmployeeStateTransfer>();

            transaction.Add(e1, new EmployeeStateTransfer()
            {
                Currency = -5, Goods = 5
            });
            transaction.Add(e2, new EmployeeStateTransfer()
            {
                Currency = 5, Goods = -5
            });

            // Executing transaction to trade 5 currency for 5 goods
            Assert.IsTrue(await transaction.Execute());
            Assert.AreEqual(5, await e1.GetGoods());
            Assert.AreEqual(0, await e1.GetCurrency());
            Assert.AreEqual(5, await e2.GetCurrency());
            Assert.AreEqual(0, await e2.GetGoods());
        }
        static async Task DoClientWork()
        {
            // basic configuration
            var clientconfig = new Orleans.Runtime.Configuration.ClientConfiguration();

            clientconfig.Gateways.Add(new IPEndPoint(IPAddress.Loopback, 30000));

            GrainClient.Initialize(clientconfig);

            var idE1 = "5ad92744-a0b1-487b-a9e7-e6b91e9a9826";
            var idE2 = "2eef0ac5-540f-4421-b9a9-79d89400f7ab";
            var e1   = GrainClient.GrainFactory.GetGrain <IEmployee>(Guid.Parse(idE1));
            var e2   = GrainClient.GrainFactory.GetGrain <IEmployee>(Guid.Parse(idE2));

            Console.WriteLine("Current State:");
            await e1.Print();

            await e2.Print();

            if (!await e1.SpendCurrency(10))
            {
                Console.WriteLine("Employee {0} does not have 10 currency to spend", idE1);
            }

            if (!await e2.SpendCurrency(10))
            {
                Console.WriteLine("Employee {0} does not have 10 currency to spend", idE2);
            }

            await e1.AddCurrency(20);

            await e2.AddGoods(10);

            await e1.Print();

            await e2.Print();

            var transaction = new TransactionHelper <EmployeeStateTransfer>();

            transaction.Add(e1, new EmployeeStateTransfer()
            {
                Currency = -5, Goods = 5
            });
            transaction.Add(e2, new EmployeeStateTransfer()
            {
                Currency = 5, Goods = -5
            });
            Console.WriteLine("Executing transaction to trade 5 currency for 5 goods... ");
            await transaction.Execute();

            Console.WriteLine("Transaction complete.");

            await e1.Print();

            await e2.Print();

            Console.WriteLine("Done!");
        }
        public async Task InsufficientGoodsTest()
        {
            var e1 = GrainFactory.GetGrain<IEmployee>(Guid.NewGuid());
            var e2 = GrainFactory.GetGrain<IEmployee>(Guid.NewGuid());
            await e1.AddCurrency(5);
            await e2.AddGoods(1);

            var transaction = new TransactionHelper<EmployeeStateTransfer>();
            transaction.Add(e1, new EmployeeStateTransfer() { Currency = -5, Goods = 5 });
            transaction.Add(e2, new EmployeeStateTransfer() { Currency = 5, Goods = -5 });

            // Executing transaction to trade 5 currency for 5 goods, but 5 Goods is not available...
            Assert.IsFalse(await transaction.Execute());
            Assert.AreEqual(5, await e1.GetCurrency());
            Assert.AreEqual(1, await e2.GetGoods());
        }
        static async Task DoClientWork()
        {
            // basic configuration
            var clientconfig = new Orleans.Runtime.Configuration.ClientConfiguration();
            clientconfig.Gateways.Add(new IPEndPoint(IPAddress.Loopback, 30000));

            GrainClient.Initialize(clientconfig);

            var idE1 = "5ad92744-a0b1-487b-a9e7-e6b91e9a9826";
            var idE2 = "2eef0ac5-540f-4421-b9a9-79d89400f7ab";
            var e1 = GrainClient.GrainFactory.GetGrain<IEmployee>(Guid.Parse(idE1));
            var e2 = GrainClient.GrainFactory.GetGrain<IEmployee>(Guid.Parse(idE2));

            Console.WriteLine("Current State:");
            await e1.Print();
            await e2.Print();

            if (!await e1.SpendCurrency(10))
            {
                Console.WriteLine("Employee {0} does not have 10 currency to spend", idE1);
            }

            if (!await e2.SpendCurrency(10))
            {
                Console.WriteLine("Employee {0} does not have 10 currency to spend", idE2);
            }

            await e1.AddCurrency(20);
            await e2.AddGoods(10);

            await e1.Print();
            await e2.Print();

            var transaction = new TransactionHelper<EmployeeStateTransfer>();
            transaction.Add(e1, new EmployeeStateTransfer() { Currency = -5, Goods = 5 });
            transaction.Add(e2, new EmployeeStateTransfer() { Currency = 5, Goods = -5 });
            Console.WriteLine("Executing transaction to trade 5 currency for 5 goods... ");
            await transaction.Execute();
            Console.WriteLine("Transaction complete.");

            await e1.Print();
            await e2.Print();

            Console.WriteLine("Done!");
        }
        public async Task TradeGoodsForCurrencyTest()
        {
            var e1 = GrainFactory.GetGrain<IEmployee>(Guid.NewGuid());
            var e2 = GrainFactory.GetGrain<IEmployee>(Guid.NewGuid());
            await e1.AddCurrency(5);
            await e2.AddGoods(5);

            var transaction = new TransactionHelper<EmployeeStateTransfer>();
            transaction.Add(e1, new EmployeeStateTransfer() { Currency = -5, Goods = 5 });
            transaction.Add(e2, new EmployeeStateTransfer() { Currency = 5, Goods = -5 });
            
            // Executing transaction to trade 5 currency for 5 goods
            Assert.IsTrue(await transaction.Execute());
            Assert.AreEqual(5, await e1.GetGoods());
            Assert.AreEqual(0, await e1.GetCurrency());
            Assert.AreEqual(5, await e2.GetCurrency());
            Assert.AreEqual(0, await e2.GetGoods());
        }
        public async Task LessThanTwoTransactionItemsTest()
        {
            var e1 = GrainFactory.GetGrain<IEmployee>(Guid.NewGuid());
            await e1.AddCurrency(5);

            var transaction = new TransactionHelper<EmployeeStateTransfer>();
            transaction.Add(e1, new EmployeeStateTransfer() { Currency = -5, Goods = 5 });

            // Executing transaction with only one item, two or more are required.
            Assert.IsFalse(await transaction.Execute());
            Assert.AreEqual(5, await e1.GetCurrency());
            Assert.AreEqual(0, await e1.GetGoods());
        }
        public async Task InsufficientGoodsTest()
        {
            var e1 = GrainFactory.GetGrain <IEmployee>(Guid.NewGuid());
            var e2 = GrainFactory.GetGrain <IEmployee>(Guid.NewGuid());
            await e1.AddCurrency(5);

            await e2.AddGoods(1);

            var transaction = new TransactionHelper <EmployeeStateTransfer>();

            transaction.Add(e1, new EmployeeStateTransfer()
            {
                Currency = -5, Goods = 5
            });
            transaction.Add(e2, new EmployeeStateTransfer()
            {
                Currency = 5, Goods = -5
            });

            // Executing transaction to trade 5 currency for 5 goods, but 5 Goods is not available...
            Assert.IsFalse(await transaction.Execute());
            Assert.AreEqual(5, await e1.GetCurrency());
            Assert.AreEqual(1, await e2.GetGoods());
        }
        public async Task LessThanTwoTransactionItemsTest()
        {
            var e1 = GrainFactory.GetGrain <IEmployee>(Guid.NewGuid());
            await e1.AddCurrency(5);

            var transaction = new TransactionHelper <EmployeeStateTransfer>();

            transaction.Add(e1, new EmployeeStateTransfer()
            {
                Currency = -5, Goods = 5
            });

            // Executing transaction with only one item, two or more are required.
            Assert.IsFalse(await transaction.Execute());
            Assert.AreEqual(5, await e1.GetCurrency());
            Assert.AreEqual(0, await e1.GetGoods());
        }