/// <summary>
        /// Main routine
        /// </summary>
        /// <param name="args">Command line arguments</param>
        public static void Main(string[] args)
        {
            if (ParseInputArgs(args) == false)
            {
                return;
            }

            // Get all Physical machines
            OdataJsonRequest request = new OdataJsonRequest(HttpVerbGet, uri.ToString() + "/PhysicalMachines", GetCredentials(uri));
            request.SendReceive();
            if (request.ResponseStatus == HttpStatusCode.OK)
            {
                Console.WriteLine("\nReceived all physical machines");
            }
            else
            {
                Console.WriteLine("\nFailed to get physical machines. Http Status Code " + request.ResponseStatus + "\n Response message: " + request.ResponseBody);
                return;
            }

            List<PhysicalMachineResource> physicalMachines = new List<PhysicalMachineResource>();

            foreach (dynamic machine in request.Response.d.results)
            {
                PhysicalMachineResource physicalMachine = new PhysicalMachineResource();
                physicalMachine.Name = machine.Name;

                Console.WriteLine("Physical machine name: " + physicalMachine.Name);

                physicalMachines.Add(physicalMachine);
            }

            // Get Physical machines with associated VMs
            request = new OdataJsonRequest(HttpVerbGet, uri.ToString() + "/PhysicalMachines?$expand=VMs", GetCredentials(uri));
            request.SendReceive();
            if (request.ResponseStatus == HttpStatusCode.OK)
            {
                Console.WriteLine("\nReceived all physical machine details with all VMs");
            }
            else
            {
                Console.WriteLine("\nFailed to get physical machine with all VMs details. Http Status Code " + request.ResponseStatus + "\n Response message: " + request.ResponseBody);
                return;
            }

            physicalMachines = new List<PhysicalMachineResource>();

            foreach (dynamic machine in request.Response.d.results)
            {
                PhysicalMachineResource physicalMachine = new PhysicalMachineResource();
                physicalMachine.Name = machine.Name;
                foreach (dynamic vm in machine.VMs.results)
                {
                    VmResource resource = new VmResource();
                    resource.Id = Guid.Parse(vm.Id);
                    resource.MachineName = vm.MachineName;
                    resource.OS = vm.OS;

                    physicalMachine.VMs.Add(resource);
                }
                
                Console.WriteLine("Physical machine name: " + physicalMachine.Name);
                foreach (VmResource vm in physicalMachine.VMs)
                {
                    Console.WriteLine("Associated virtual machine: Id " + vm.Id + " Machine Name " + vm.MachineName);
                }

                physicalMachines.Add(physicalMachine);
            }
            
            // Get list of Systems
            request = new OdataJsonRequest(HttpVerbGet, uri.ToString() + "/Systems?$expand=VMs", GetCredentials(uri));
            request.SendReceive();
            if (request.ResponseStatus == HttpStatusCode.OK)
            {
                Console.WriteLine("\nReceived all systems details");
            }
            else
            {
                Console.WriteLine("\nFailed to get systems details. Http Status Code " + request.ResponseStatus + "\n Response message: " + request.ResponseBody);
                return;
            }

            List<SystemResource> systems = new List<SystemResource>();
            foreach (dynamic sys in request.Response.d.results)
            {
                SystemResource system = new SystemResource();
                system.Id = Guid.Parse(sys.Id);
                system.Name = sys.Name;

                foreach (dynamic vm in sys.VMs.results)
                {
                    VmResource resource = new VmResource();
                    resource.Id = Guid.Parse(vm.Id);
                    resource.MachineName = vm.MachineName;
                    resource.OS = vm.OS;

                    system.VMs.Add(resource);
                }

                Console.WriteLine("System Id: " + system.Name + " Name: " + system.Name);
                foreach (VmResource vm in system.VMs)
                {
                    Console.WriteLine("Associated virtual machine: Id " + vm.Id + " Machine Name " + vm.MachineName);
                }

                systems.Add(system);
            }

            string firstSystemUri = request.Response.d.results[0].__metadata.uri;

            // Create a new Virtual machine
            request = new OdataJsonRequest(HttpVerbPost, uri.ToString() + "/VirtualMachines", GetCredentials(uri));
            request.RequestBody += "{";
            request.RequestBody += OdataJsonRequest.EncodeJsonElement("MachineName", physicalMachines[0].Name);
            request.RequestBody += ",";
            request.RequestBody += OdataJsonRequest.EncodeJsonElement("OS", "win8");
            request.RequestBody += "}";

            request.SendReceive();
            if (request.ResponseStatus == HttpStatusCode.Created)
            {
                Console.WriteLine("\nCreated a new VM " + request.Response.d.__metadata.uri);
            }
            else
            {
                Console.WriteLine("\nFailed to create a new VM. Http Status Code " + request.ResponseStatus + "\n Response message: " + request.ResponseBody);
                return;
            }

            string newVMUri = request.Response.d.__metadata.uri;

            // Get new VM resource
            request = new OdataJsonRequest(HttpVerbGet, newVMUri, GetCredentials(uri));
            request.SendReceive();
            if (request.ResponseStatus == HttpStatusCode.OK)
            {
                Console.WriteLine("\nnReceived a new VM instance " + request.Response.d.__metadata.uri);
            }
            else
            {
                Console.WriteLine("\nFailed to get new VM " + request.Response.d.__metadata.uri + "instance. Http Status Code " + request.ResponseStatus + "\n Response message: " + request.ResponseBody);
                return;
            }

            VmResource newVM = new VmResource();
            dynamic tempVm = request.Response.d;
            newVM.Id = Guid.Parse(tempVm.Id);
            newVM.MachineName = tempVm.MachineName;
            newVM.OS = tempVm.OS;
            
            // Add Virtual Machine in first system 
            request = new OdataJsonRequest(HttpVerbPost, firstSystemUri + "/$links/VMs", GetCredentials(uri));
            request.RequestBody += "{";
            request.RequestBody += OdataJsonRequest.EncodeJsonElement("uri", newVMUri);
            request.RequestBody += "}";
            request.SendReceive();
            if (request.ResponseStatus == HttpStatusCode.NoContent)
            {
                Console.WriteLine("\nAdded VM " + newVMUri + " to the System " + firstSystemUri);
            }
            else
            {
                Console.WriteLine("\nFailed to add VM " + newVMUri + " to the system " + firstSystemUri + ". Http Status Code " + request.ResponseStatus + "\n Response message: " + request.ResponseBody);
                return;
            }

            // Get list of Virtual Machines for the System
            request = new OdataJsonRequest(HttpVerbGet, firstSystemUri + "/$links/VMs", GetCredentials(uri));
            request.SendReceive();
            if (request.ResponseStatus == HttpStatusCode.OK)
            {
                Console.WriteLine("\nReceived all VMs for the system " + firstSystemUri);
            }
            else
            {
                Console.WriteLine("\nFailed to get all VMs for the system " + firstSystemUri + ". Http Status Code " + request.ResponseStatus + "\n Response message: " + request.ResponseBody);
                return;
            }

            List<string> links = new List<string>();
            foreach (dynamic d in request.Response.d.results)
            {
                links.Add(d.uri);
            }

            if (links.Contains(newVMUri))
            {
                Console.WriteLine("VM " + newVMUri + " is present in the list of VMs associated with the system " + firstSystemUri);
            }
            else
            {
                Console.WriteLine("Error: VM " + newVMUri + " is not present in the list of VMs associated with the system " + firstSystemUri);
                return;
            }

            // Remove Virtual Machine from System
            request = new OdataJsonRequest(HttpVerbDelete, firstSystemUri + "/$links/VMs(Id=guid'" + newVM.Id + "',MachineName='" + newVM.MachineName + "')", GetCredentials(uri));
            request.SendReceive();
            if (request.ResponseStatus == HttpStatusCode.NoContent)
            {
                Console.WriteLine("\nRemoved VM " + newVMUri + " from the system " + firstSystemUri);
            }
            else
            {
                Console.WriteLine("\nFailed to remove VM " + newVMUri + " from the system " + firstSystemUri + ". Http Status Code " + request.ResponseStatus + "\n Response message: " + request.ResponseBody);
                return;
            }

            // Get list of Virtual Machines for the System
            request = new OdataJsonRequest(HttpVerbGet, firstSystemUri + "/$links/VMs", GetCredentials(uri));
            request.SendReceive();
            if (request.ResponseStatus == HttpStatusCode.OK)
            {
                Console.WriteLine("\nReceived all VMs for the system " + firstSystemUri);
            }
            else
            {
                Console.WriteLine("\nFailed to get all VMs for the system " + firstSystemUri + ". Http Status Code " + request.ResponseStatus + "\n Response message: " + request.ResponseBody);
                return;
            }

            links = new List<string>();
            foreach (dynamic d in request.Response.d.results)
            {
                links.Add(d.uri);
            }

            if (links.Contains(newVMUri))
            {
                Console.WriteLine("Error: VM " + newVMUri + " is associated with the system " + firstSystemUri);
            }
            else
            {
                Console.WriteLine("VM " + newVMUri + " is not associated with the system " + firstSystemUri);
            }

            // Delete the VM
            request = new OdataJsonRequest(HttpVerbDelete, newVMUri, GetCredentials(uri));
            request.SendReceive();
            if (request.ResponseStatus == HttpStatusCode.NoContent)
            {
                Console.WriteLine("\nRemoved VM " + newVMUri);
            }
            else
            {
                Console.WriteLine("\nFailed to removed VM " + newVMUri + ". Http Status Code " + request.ResponseStatus + "\n Response message: " + request.ResponseBody);
                return;
            }

            // Get all VMs
            request = new OdataJsonRequest(HttpVerbGet, uri.ToString() + "/VirtualMachines", GetCredentials(uri));
            request.SendReceive();
            if (request.ResponseStatus == HttpStatusCode.OK)
            {
                Console.WriteLine("\nReceived all VMs ");
            }
            else
            {
                Console.WriteLine("\nFailed to receive all VMs. Http Status Code " + request.ResponseStatus + "\n Response message: " + request.ResponseBody);
                return;
            }

            List<string> allVmLinks = new List<string>();

            foreach (dynamic d in request.Response.d.Results)
            {
                allVmLinks.Add(d.__metadata.uri);
            }

            if (allVmLinks.Contains(newVMUri))
            {
                Console.WriteLine("Error: VM " + newVMUri + " is present");
            }
            else
            {
                Console.WriteLine("VM " + newVMUri + " is not present");
            }
        }
        /// <summary>
        /// Main routine
        /// </summary>
        /// <param name="args">Command line arguments</param>
        public static void Main(string[] args)
        {
            if (ParseInputArgs(args) == false)
            {
                return;
            }

            // Get all Physical machines
            OdataJsonRequest request = new OdataJsonRequest(HttpVerbGet, uri.ToString() + "/PhysicalMachines", GetCredentials(uri));

            request.SendReceive();
            if (request.ResponseStatus == HttpStatusCode.OK)
            {
                Console.WriteLine("\nReceived all physical machines");
            }
            else
            {
                Console.WriteLine("\nFailed to get physical machines. Http Status Code " + request.ResponseStatus + "\n Response message: " + request.ResponseBody);
                return;
            }

            List <PhysicalMachineResource> physicalMachines = new List <PhysicalMachineResource>();

            foreach (dynamic machine in request.Response.d.results)
            {
                PhysicalMachineResource physicalMachine = new PhysicalMachineResource();
                physicalMachine.Name = machine.Name;

                Console.WriteLine("Physical machine name: " + physicalMachine.Name);

                physicalMachines.Add(physicalMachine);
            }

            // Get Physical machines with associated VMs
            request = new OdataJsonRequest(HttpVerbGet, uri.ToString() + "/PhysicalMachines?$expand=VMs", GetCredentials(uri));
            request.SendReceive();
            if (request.ResponseStatus == HttpStatusCode.OK)
            {
                Console.WriteLine("\nReceived all physical machine details with all VMs");
            }
            else
            {
                Console.WriteLine("\nFailed to get physical machine with all VMs details. Http Status Code " + request.ResponseStatus + "\n Response message: " + request.ResponseBody);
                return;
            }

            physicalMachines = new List <PhysicalMachineResource>();

            foreach (dynamic machine in request.Response.d.results)
            {
                PhysicalMachineResource physicalMachine = new PhysicalMachineResource();
                physicalMachine.Name = machine.Name;
                foreach (dynamic vm in machine.VMs.results)
                {
                    VmResource resource = new VmResource();
                    resource.Id          = Guid.Parse(vm.Id);
                    resource.MachineName = vm.MachineName;
                    resource.OS          = vm.OS;

                    physicalMachine.VMs.Add(resource);
                }

                Console.WriteLine("Physical machine name: " + physicalMachine.Name);
                foreach (VmResource vm in physicalMachine.VMs)
                {
                    Console.WriteLine("Associated virtual machine: Id " + vm.Id + " Machine Name " + vm.MachineName);
                }

                physicalMachines.Add(physicalMachine);
            }

            // Get list of Systems
            request = new OdataJsonRequest(HttpVerbGet, uri.ToString() + "/Systems?$expand=VMs", GetCredentials(uri));
            request.SendReceive();
            if (request.ResponseStatus == HttpStatusCode.OK)
            {
                Console.WriteLine("\nReceived all systems details");
            }
            else
            {
                Console.WriteLine("\nFailed to get systems details. Http Status Code " + request.ResponseStatus + "\n Response message: " + request.ResponseBody);
                return;
            }

            List <SystemResource> systems = new List <SystemResource>();

            foreach (dynamic sys in request.Response.d.results)
            {
                SystemResource system = new SystemResource();
                system.Id   = Guid.Parse(sys.Id);
                system.Name = sys.Name;

                foreach (dynamic vm in sys.VMs.results)
                {
                    VmResource resource = new VmResource();
                    resource.Id          = Guid.Parse(vm.Id);
                    resource.MachineName = vm.MachineName;
                    resource.OS          = vm.OS;

                    system.VMs.Add(resource);
                }

                Console.WriteLine("System Id: " + system.Name + " Name: " + system.Name);
                foreach (VmResource vm in system.VMs)
                {
                    Console.WriteLine("Associated virtual machine: Id " + vm.Id + " Machine Name " + vm.MachineName);
                }

                systems.Add(system);
            }

            string firstSystemUri = request.Response.d.results[0].__metadata.uri;

            // Create a new Virtual machine
            request              = new OdataJsonRequest(HttpVerbPost, uri.ToString() + "/VirtualMachines", GetCredentials(uri));
            request.RequestBody += "{";
            request.RequestBody += OdataJsonRequest.EncodeJsonElement("MachineName", physicalMachines[0].Name);
            request.RequestBody += ",";
            request.RequestBody += OdataJsonRequest.EncodeJsonElement("OS", "win8");
            request.RequestBody += "}";

            request.SendReceive();
            if (request.ResponseStatus == HttpStatusCode.Created)
            {
                Console.WriteLine("\nCreated a new VM " + request.Response.d.__metadata.uri);
            }
            else
            {
                Console.WriteLine("\nFailed to create a new VM. Http Status Code " + request.ResponseStatus + "\n Response message: " + request.ResponseBody);
                return;
            }

            string newVMUri = request.Response.d.__metadata.uri;

            // Get new VM resource
            request = new OdataJsonRequest(HttpVerbGet, newVMUri, GetCredentials(uri));
            request.SendReceive();
            if (request.ResponseStatus == HttpStatusCode.OK)
            {
                Console.WriteLine("\nnReceived a new VM instance " + request.Response.d.__metadata.uri);
            }
            else
            {
                Console.WriteLine("\nFailed to get new VM " + request.Response.d.__metadata.uri + "instance. Http Status Code " + request.ResponseStatus + "\n Response message: " + request.ResponseBody);
                return;
            }

            VmResource newVM  = new VmResource();
            dynamic    tempVm = request.Response.d;

            newVM.Id          = Guid.Parse(tempVm.Id);
            newVM.MachineName = tempVm.MachineName;
            newVM.OS          = tempVm.OS;

            // Add Virtual Machine in first system
            request              = new OdataJsonRequest(HttpVerbPost, firstSystemUri + "/$links/VMs", GetCredentials(uri));
            request.RequestBody += "{";
            request.RequestBody += OdataJsonRequest.EncodeJsonElement("uri", newVMUri);
            request.RequestBody += "}";
            request.SendReceive();
            if (request.ResponseStatus == HttpStatusCode.NoContent)
            {
                Console.WriteLine("\nAdded VM " + newVMUri + " to the System " + firstSystemUri);
            }
            else
            {
                Console.WriteLine("\nFailed to add VM " + newVMUri + " to the system " + firstSystemUri + ". Http Status Code " + request.ResponseStatus + "\n Response message: " + request.ResponseBody);
                return;
            }

            // Get list of Virtual Machines for the System
            request = new OdataJsonRequest(HttpVerbGet, firstSystemUri + "/$links/VMs", GetCredentials(uri));
            request.SendReceive();
            if (request.ResponseStatus == HttpStatusCode.OK)
            {
                Console.WriteLine("\nReceived all VMs for the system " + firstSystemUri);
            }
            else
            {
                Console.WriteLine("\nFailed to get all VMs for the system " + firstSystemUri + ". Http Status Code " + request.ResponseStatus + "\n Response message: " + request.ResponseBody);
                return;
            }

            List <string> links = new List <string>();

            foreach (dynamic d in request.Response.d.results)
            {
                links.Add(d.uri);
            }

            if (links.Contains(newVMUri))
            {
                Console.WriteLine("VM " + newVMUri + " is present in the list of VMs associated with the system " + firstSystemUri);
            }
            else
            {
                Console.WriteLine("Error: VM " + newVMUri + " is not present in the list of VMs associated with the system " + firstSystemUri);
                return;
            }

            // Remove Virtual Machine from System
            request = new OdataJsonRequest(HttpVerbDelete, firstSystemUri + "/$links/VMs(Id=guid'" + newVM.Id + "',MachineName='" + newVM.MachineName + "')", GetCredentials(uri));
            request.SendReceive();
            if (request.ResponseStatus == HttpStatusCode.NoContent)
            {
                Console.WriteLine("\nRemoved VM " + newVMUri + " from the system " + firstSystemUri);
            }
            else
            {
                Console.WriteLine("\nFailed to remove VM " + newVMUri + " from the system " + firstSystemUri + ". Http Status Code " + request.ResponseStatus + "\n Response message: " + request.ResponseBody);
                return;
            }

            // Get list of Virtual Machines for the System
            request = new OdataJsonRequest(HttpVerbGet, firstSystemUri + "/$links/VMs", GetCredentials(uri));
            request.SendReceive();
            if (request.ResponseStatus == HttpStatusCode.OK)
            {
                Console.WriteLine("\nReceived all VMs for the system " + firstSystemUri);
            }
            else
            {
                Console.WriteLine("\nFailed to get all VMs for the system " + firstSystemUri + ". Http Status Code " + request.ResponseStatus + "\n Response message: " + request.ResponseBody);
                return;
            }

            links = new List <string>();
            foreach (dynamic d in request.Response.d.results)
            {
                links.Add(d.uri);
            }

            if (links.Contains(newVMUri))
            {
                Console.WriteLine("Error: VM " + newVMUri + " is associated with the system " + firstSystemUri);
            }
            else
            {
                Console.WriteLine("VM " + newVMUri + " is not associated with the system " + firstSystemUri);
            }

            // Delete the VM
            request = new OdataJsonRequest(HttpVerbDelete, newVMUri, GetCredentials(uri));
            request.SendReceive();
            if (request.ResponseStatus == HttpStatusCode.NoContent)
            {
                Console.WriteLine("\nRemoved VM " + newVMUri);
            }
            else
            {
                Console.WriteLine("\nFailed to removed VM " + newVMUri + ". Http Status Code " + request.ResponseStatus + "\n Response message: " + request.ResponseBody);
                return;
            }

            // Get all VMs
            request = new OdataJsonRequest(HttpVerbGet, uri.ToString() + "/VirtualMachines", GetCredentials(uri));
            request.SendReceive();
            if (request.ResponseStatus == HttpStatusCode.OK)
            {
                Console.WriteLine("\nReceived all VMs ");
            }
            else
            {
                Console.WriteLine("\nFailed to receive all VMs. Http Status Code " + request.ResponseStatus + "\n Response message: " + request.ResponseBody);
                return;
            }

            List <string> allVmLinks = new List <string>();

            foreach (dynamic d in request.Response.d.Results)
            {
                allVmLinks.Add(d.__metadata.uri);
            }

            if (allVmLinks.Contains(newVMUri))
            {
                Console.WriteLine("Error: VM " + newVMUri + " is present");
            }
            else
            {
                Console.WriteLine("VM " + newVMUri + " is not present");
            }
        }