text:
// ----------------------------------------------------------------------------------
//
// Copyright Microsoft Corporation
// 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.
// ----------------------------------------------------------------------------------

using Microsoft.Azure;

namespace Microsoft.WindowsAzure.Commands.ServiceManagement.Network
{
    using Gateway.Model;
    using Hyak.Common;
    using Microsoft.Azure.Common.Authentication;
    using Microsoft.Azure.Common.Authentication.Models;
    using Microsoft.WindowsAzure.Commands.ServiceManagement.Model;
    using Microsoft.WindowsAzure.Management.Compute;
    using NetworkSecurityGroup.Model;
    using Routes.Model;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Management.Automation;
    using System.Security.Cryptography.X509Certificates;
    using WindowsAzure.Commands.Common.Storage;
    using WindowsAzure.Commands.Utilities.Common;
    using WindowsAzure.Management;
    using WindowsAzure.Management.Network;
    using WindowsAzure.Management.Network.Models;
    using ManagementNextHop = WindowsAzure.Management.Network.Models.NextHop;
    using WindowsAzure.Storage.Auth;
    using ComputeModels = Microsoft.WindowsAzure.Management.Compute.Models;
    using PowerShellAppGwModel = ApplicationGateway.Model;

    public class NetworkClient
    {
        private readonly INetworkManagementClient client;
        private readonly IComputeManagementClient computeClient;
        private readonly IManagementClient managementClient;
        private readonly ICommandRuntime commandRuntime;

        public static readonly string WithRoutesDetailLevel = "full";
        public static readonly string WithoutRoutesDetailLevel = "noroutes";

        public NetworkClient(AzureSMProfile profile, AzureSubscription subscription, ICommandRuntime commandRuntime)
            : this(CreateClient<NetworkManagementClient>(profile, subscription),
                   CreateClient<ComputeManagementClient>(profile, subscription),
                   CreateClient<ManagementClient>(profile, subscription),
                   commandRuntime)
        {
        }
        public NetworkClient(INetworkManagementClient client, IComputeManagementClient computeClient, IManagementClient managementClient, ICommandRuntime commandRuntime)
        {
            this.client = client;
            this.computeClient = computeClient;
            this.managementClient = managementClient;
            this.commandRuntime = commandRuntime;
        }

        public PowerShellAppGwModel.ApplicationGateway GetApplicationGateway(string gatewayName)
        {
            ApplicationGatewayGetResponse parameters = client.ApplicationGateways.Get(gatewayName);

            PowerShellAppGwModel.SubnetCollection subnets = new PowerShellAppGwModel.SubnetCollection();
            foreach (string subnet in parameters.Subnets)
            {
                subnets.Add(subnet);
            }

            PowerShellAppGwModel.VirtualIpCollection VirtualIPs = new PowerShellAppGwModel.VirtualIpCollection();
            foreach (string vip in parameters.VirtualIPs)
            {
                VirtualIPs.Add(vip);
            }

            return (new ApplicationGateway.Model.ApplicationGateway
            {
                Name = parameters.Name,
                Description = parameters.Description,
                GatewaySize = parameters.GatewaySize,
                InstanceCount = parameters.InstanceCount,
                VnetName = parameters.VnetName,
                Subnets = subnets,
                State = parameters.State,
                VirtualIPs = VirtualIPs,
                DnsName = parameters.DnsName
            });
        }

        public IEnumerable<PowerShellAppGwModel.ApplicationGateway> ListApplicationGateway()
        {
            ApplicationGatewayListResponse gatewayList = client.ApplicationGateways.List();

            List<ApplicationGateway.Model.ApplicationGateway> psGatewayList = new List<ApplicationGateway.Model.ApplicationGateway>();
            foreach (ApplicationGatewayGetResponse gateway in gatewayList.ApplicationGateways)
            {
                PowerShellAppGwModel.SubnetCollection subnets = new PowerShellAppGwModel.SubnetCollection();
                foreach (string subnet in gateway.Subnets)
                {
                    subnets.Add(subnet);
                }

                PowerShellAppGwModel.VirtualIpCollection VirtualIPs = new PowerShellAppGwModel.VirtualIpCollection();
                foreach (string vip in gateway.VirtualIPs)
                {
                    VirtualIPs.Add(vip);
                }

                psGatewayList.Add(new PowerShellAppGwModel.ApplicationGateway
                {
                    Name = gateway.Name,
                    Description = gateway.Description,
                    GatewaySize = gateway.GatewaySize,
                    InstanceCount = gateway.InstanceCount,
                    VnetName = gateway.VnetName,
                    Subnets = subnets,
                    State = gateway.State,
                    VirtualIPs = VirtualIPs,
                    DnsName = gateway.DnsName
                });
            }
            return psGatewayList;
        }

        public ApplicationGatewayOperationResponse CreateApplicationGateway(string name, string vnetName, List<string> subnets, string description, uint instanceCount, string gatewaySize)
        {
            return client.ApplicationGateways.Create(new CreateApplicationGatewayParameters
            {
                Name = name,
                VnetName = vnetName,
                Subnets = subnets,
                Description = description,
                InstanceCount = instanceCount,
                GatewaySize = gatewaySize
            });
        }
        public ApplicationGatewayOperationResponse UpdateApplicationGateway(string name, string vnetName, List<string> subnets, string description, uint instanceCount, string gatewaySize)
        {
            return client.ApplicationGateways.Update(name,
                new UpdateApplicationGatewayParameters
                {
                    Description = description,
                    GatewaySize = gatewaySize,
                    InstanceCount = instanceCount,
                    Subnets = (((subnets == null) || subnets.Count == 0) ? null : new List<string>(subnets)),
                    VnetName = vnetName
                });
        }
        public ApplicationGatewayOperationResponse RemoveApplicationGateway(string gatewayName)
        {
            return client.ApplicationGateways.Delete(gatewayName);
        }

        public ApplicationGatewayOperationResponse SetApplicationGatewayConfig(string gatewayName, PowerShellAppGwModel.ApplicationGatewayConfiguration config)
        {
            return client.ApplicationGateways.SetConfig(gatewayName, HydraConfigFromPowerShellConfig(config));
        }

        public PowerShellAppGwModel.ApplicationGatewayConfigContext GetApplicationGatewayConfig(string gatewayName)
        {
            ApplicationGatewayGetConfiguration hydraConfig = client.ApplicationGateways.GetConfig(gatewayName);
            PowerShellAppGwModel.ApplicationGatewayConfiguration psConfig = PowerShellConfigFromHydraConfig(hydraConfig);

            return (new PowerShellAppGwModel.ApplicationGatewayConfigContext
            {
                OperationDescription = "Get-ApplicationGatewayConfig",
                OperationId = hydraConfig.RequestId,
                OperationStatus = hydraConfig.StatusCode.ToString(),
                Config = psConfig,
                XMLConfiguration = PowerShellAppGwModel.ApplicationGatewayConfiguration.Print(psConfig)
            });
        }

        public ApplicationGatewayOperationResponse ExecuteApplicationGatewayOperation(string gatewayName, string opName)
        {
            ApplicationGatewayOperation op = new ApplicationGatewayOperation();
            op.OperationType = opName;

            return client.ApplicationGateways.ExecuteOperation(gatewayName, op);
        }

        public ApplicationGatewayOperationResponse AddApplicationGatewayCertificate(string gatewayName, string certificateName, string password, string certificateFile)
        {
            X509Certificate2 cert = new X509Certificate2(certificateFile, password, X509KeyStorageFlags.Exportable);

            ApplicationGatewayCertificate appGwCert = new ApplicationGatewayCertificate()
            {
                Data = Convert.ToBase64String(cert.Export(X509ContentType.Pfx, password)),
                //CertificateFormat = "pfx",
                Password = password
            };

            return client.ApplicationGateways.AddCertificate(gatewayName, certificateName, appGwCert);
        }

        public PowerShellAppGwModel.ApplicationGatewayCertificate GetApplicationGatewayCertificate(string gatewayName, string certificateName)
        {
            ApplicationGatewayGetCertificate certificate = client.ApplicationGateways.GetCertificate(gatewayName, certificateName);
            X509Certificate2 certObject = new X509Certificate2(Convert.FromBase64String(certificate.Data));
            return (new PowerShellAppGwModel.ApplicationGatewayCertificate
            {
                Name = certificate.Name,
                SubjectName = certObject.SubjectName.Name,
                Thumbprint = certObject.Thumbprint,
                ThumbprintAlgo = certObject.SignatureAlgorithm.FriendlyName,
                State = certificate.State
            });
        }

        public List<PowerShellAppGwModel.ApplicationGatewayCertificate> ListApplicationGatewayCertificate(string gatewayName)
        {
            ApplicationGatewayListCertificate hydraCertList = client.ApplicationGateways.ListCertificate(gatewayName);

            List<PowerShellAppGwModel.ApplicationGatewayCertificate> psCertList = new List<PowerShellAppGwModel.ApplicationGatewayCertificate>();
            foreach (ApplicationGatewayGetCertificate certificate in hydraCertList.ApplicationGatewayCertificates)
            {
                X509Certificate2 certObject = new X509Certificate2(Convert.FromBase64String(certificate.Data));
                psCertList.Add(new PowerShellAppGwModel.ApplicationGatewayCertificate
                {
                    Name = certificate.Name,
                    SubjectName = certObject.SubjectName.Name,
                    Thumbprint = certObject.Thumbprint,
                    ThumbprintAlgo = certObject.SignatureAlgorithm.FriendlyName,
                    State = certificate.State
                });
            }
            return psCertList;
        }

        public ApplicationGatewayOperationResponse RemoveApplicationGatewayCertificate(string gatewayName, string certificateName)
        {
            return client.ApplicationGateways.DeleteCertificate(gatewayName, certificateName);
        }

        private ApplicationGatewaySetConfiguration HydraConfigFromPowerShellConfig(PowerShellAppGwModel.ApplicationGatewayConfiguration config)
        {
            ApplicationGatewaySetConfiguration outConfig = new ApplicationGatewaySetConfiguration();

            //Frontend IPs
            outConfig.FrontendIPConfigurations = new List<FrontendIPConfiguration>();

            //Config without Frontend IPs is also valid
            if (null != config.FrontendIPConfigurations)
            {
                foreach (PowerShellAppGwModel.FrontendIPConfiguration fip in config.FrontendIPConfigurations)
                {
                    outConfig.FrontendIPConfigurations.Add(new FrontendIPConfiguration
                    {
                        Name = fip.Name,
                        Type = fip.Type,
                        StaticIPAddress = fip.StaticIPAddress
                    });
                }
            }

            //Frontend Port
            outConfig.FrontendPorts = new List<FrontendPort>();
            foreach (PowerShellAppGwModel.FrontendPort fp in config.FrontendPorts)
            {
                outConfig.FrontendPorts.Add(new FrontendPort
                {
                    Name = fp.Name,
                    Port = fp.Port
                });
            }

            //Backend Address Pools
            outConfig.BackendAddressPools = new List<BackendAddressPool>();
            foreach (PowerShellAppGwModel.BackendAddressPool pool in config.BackendAddressPools)
            {
                List<BackendServer> servers = new List<BackendServer>();
                foreach (string server in pool.BackendServers)
                {
                    servers.Add(new BackendServer
                    {
                        IPAddress = server
                    });
                }

                outConfig.BackendAddressPools.Add(new BackendAddressPool
                {
                    Name = pool.Name,
                    BackendServers = servers
                });
            }

            //Backend Http Settings List
            outConfig.BackendHttpSettingsList = new List<BackendHttpSettings>();
            foreach (PowerShellAppGwModel.BackendHttpSettings setting in config.BackendHttpSettingsList)
            {
                outConfig.BackendHttpSettingsList.Add(new BackendHttpSettings
                {
                    Name = setting.Name,
                    Port = setting.Port,
                    Protocol = (Protocol)setting.Protocol,
                    CookieBasedAffinity = setting.CookieBasedAffinity
                });
            }

            //Http Listeners
            outConfig.HttpListeners = new List<AGHttpListener>();
            foreach (PowerShellAppGwModel.HttpListener listener in config.HttpListeners)
            {
                outConfig.HttpListeners.Add(new AGHttpListener
                {
                    Name = listener.Name,
                    FrontendIP = listener.FrontendIP,
                    FrontendPort = listener.FrontendPort,
                    Protocol = (Protocol)listener.Protocol,
                    SslCert = listener.SslCert
                });
            }

            //Http Load Balancing Rules
            outConfig.HttpLoadBalancingRules = new List<HttpLoadBalancingRule>();
            foreach (PowerShellAppGwModel.HttpLoadBalancingRule rule in config.HttpLoadBalancingRules)
            {
                outConfig.HttpLoadBalancingRules.Add(new HttpLoadBalancingRule
                {
                    Name = rule.Name,
                    Type = rule.Type,
                    BackendHttpSettings = rule.BackendHttpSettings,
                    Listener = rule.Listener,
                    BackendAddressPool = rule.BackendAddressPool
                });
            }

            return outConfig;
        }

        private PowerShellAppGwModel.ApplicationGatewayConfiguration PowerShellConfigFromHydraConfig(ApplicationGatewayGetConfiguration config)
        {
            PowerShellAppGwModel.ApplicationGatewayConfiguration outConfig = new PowerShellAppGwModel.ApplicationGatewayConfiguration();

            //Frontend IPs
            List<PowerShellAppGwModel.FrontendIPConfiguration> fips = new List<PowerShellAppGwModel.FrontendIPConfiguration>();

            //Config without Frontend IPs is also valid
            if (null != config.FrontendIPConfigurations)
            {

                foreach (FrontendIPConfiguration fip in config.FrontendIPConfigurations)
                {

                    fips.Add(new PowerShellAppGwModel.FrontendIPConfiguration
                    {
                        Name = fip.Name,
                        Type = fip.Type,
                        StaticIPAddress = fip.StaticIPAddress
                    });
                }
            }

            //Frontend Port
            List<PowerShellAppGwModel.FrontendPort> fps = new List<PowerShellAppGwModel.FrontendPort>();
            foreach (FrontendPort fp in config.FrontendPorts)
            {

                fps.Add(new PowerShellAppGwModel.FrontendPort
                {
                    Name = fp.Name,
                    Port = fp.Port
                });
            }

            //Backend Address Pools
            List<PowerShellAppGwModel.BackendAddressPool> pools = new List<PowerShellAppGwModel.BackendAddressPool>();
            foreach (BackendAddressPool pool in config.BackendAddressPools)
            {
                PowerShellAppGwModel.BackendServerCollection servers = new PowerShellAppGwModel.BackendServerCollection();
                foreach (BackendServer server in pool.BackendServers)
                {
                    servers.Add(server.IPAddress);
                }

                pools.Add(new PowerShellAppGwModel.BackendAddressPool
                {
                    Name = pool.Name,
                    BackendServers = servers
                });
            }

            //Backend Http Settings List
            List<PowerShellAppGwModel.BackendHttpSettings> settings = new List<PowerShellAppGwModel.BackendHttpSettings>();
            foreach (BackendHttpSettings setting in config.BackendHttpSettingsList)
            {
                settings.Add(new PowerShellAppGwModel.BackendHttpSettings
                {
                    Name = setting.Name,
                    Port = setting.Port,
                    Protocol = (PowerShellAppGwModel.Protocol)setting.Protocol,
                    CookieBasedAffinity = setting.CookieBasedAffinity
                });
            }

            //Http Listeners
            List<PowerShellAppGwModel.HttpListener> listeners = new List<PowerShellAppGwModel.HttpListener>();
            foreach (AGHttpListener listener in config.HttpListeners)
            {
                listeners.Add(new PowerShellAppGwModel.HttpListener
                {
                    Name = listener.Name,
                    FrontendIP = listener.FrontendIP,
                    FrontendPort = listener.FrontendPort,
                    Protocol = (PowerShellAppGwModel.Protocol)listener.Protocol,
                    SslCert = listener.SslCert
                });
            }

            //Http Load Balancing Rules
            List<PowerShellAppGwModel.HttpLoadBalancingRule> rules = new List<PowerShellAppGwModel.HttpLoadBalancingRule>();
            foreach (HttpLoadBalancingRule rule in config.HttpLoadBalancingRules)
            {
                rules.Add(new PowerShellAppGwModel.HttpLoadBalancingRule
                {
                    Name = rule.Name,
                    Type = rule.Type,
                    BackendHttpSettings = rule.BackendHttpSettings,
                    Listener = rule.Listener,
                    BackendAddressPool = rule.BackendAddressPool
                });
            }

            outConfig.FrontendIPConfigurations = fips;
            outConfig.FrontendPorts = fps;
            outConfig.BackendAddressPools = pools;
            outConfig.BackendHttpSettingsList = settings;
            outConfig.HttpListeners = listeners;
            outConfig.HttpLoadBalancingRules = rules;

            return outConfig;
        }
        public VirtualNetworkGatewayContext GetGateway(string vnetName)
        {
            if (string.IsNullOrWhiteSpace(vnetName))
            {
                throw new ArgumentException("vnetName cannot be null or whitespace.", "vnetName");
            }

            GatewayGetResponse response = client.Gateways.Get(vnetName);

            VirtualNetworkGatewayContext gatewayContext = new VirtualNetworkGatewayContext()
            {
                LastEventData = (response.LastEvent != null) ? response.LastEvent.Data : null,
                LastEventMessage = (response.LastEvent != null) ? response.LastEvent.Message : null,
                LastEventID = GetEventId(response.LastEvent),
                LastEventTimeStamp = (response.LastEvent != null) ? (DateTime?)response.LastEvent.Timestamp : null,
                State = (ProvisioningState)Enum.Parse(typeof(ProvisioningState), response.State, true),
                VIPAddress = response.VipAddress,
                DefaultSite = (response.DefaultSite != null ? response.DefaultSite.Name : null),
                GatewaySKU = response.GatewaySKU,
            };
            PopulateOperationContext(response.RequestId, gatewayContext);

            return gatewayContext;
        }

        public IEnumerable<GatewayConnectionContext> ListConnections(string vnetName)
        {
            GatewayListConnectionsResponse response = client.Gateways.ListConnections(vnetName);

            IEnumerable<GatewayConnectionContext> connections = response.Connections.Select(
                (GatewayListConnectionsResponse.GatewayConnection connection) =>
                {
                    return new GatewayConnectionContext()
                    {
                        ConnectivityState         = connection.ConnectivityState.ToString(),
                        EgressBytesTransferred    = (ulong)connection.EgressBytesTransferred,
                        IngressBytesTransferred   = (ulong)connection.IngressBytesTransferred,
                        LastConnectionEstablished = connection.LastConnectionEstablished.ToString(),
                        LastEventID               = connection.LastEvent != null ? connection.LastEvent.Id : null,
                        LastEventMessage          = connection.LastEvent != null ? connection.LastEvent.Message : null,
                        LastEventTimeStamp        = connection.LastEvent != null ? connection.LastEvent.Timestamp.ToString() : null,
                        LocalNetworkSiteName      = connection.LocalNetworkSiteName
                    };
                });
            PopulateOperationContext(response.RequestId, connections);

            return connections;
        }

        public VirtualNetworkDiagnosticsContext GetDiagnostics(string vnetName)
        {
            GatewayDiagnosticsStatus diagnosticsStatus = client.Gateways.GetDiagnostics(vnetName);

            VirtualNetworkDiagnosticsContext diagnosticsContext = new VirtualNetworkDiagnosticsContext()
            {
                DiagnosticsUrl = diagnosticsStatus.DiagnosticsUrl,
                State = diagnosticsStatus.State,
            };
            PopulateOperationContext(diagnosticsStatus.RequestId, diagnosticsContext);

            return diagnosticsContext;
        }

        public SharedKeyContext GetSharedKey(string vnetName, string localNetworkSiteName)
        {
            GatewayGetSharedKeyResponse response = client.Gateways.GetSharedKey(vnetName, localNetworkSiteName);

            SharedKeyContext sharedKeyContext = new SharedKeyContext()
            {
                Value = response.SharedKey
            };
            PopulateOperationContext(response.RequestId, sharedKeyContext);

            return sharedKeyContext;
        }

        public GatewayGetOperationStatusResponse SetSharedKey(string vnetName, string localNetworkSiteName, string sharedKey)
        {
            GatewaySetSharedKeyParameters sharedKeyParameters = new GatewaySetSharedKeyParameters()
            {
                Value = sharedKey,
            };

            return client.Gateways.SetSharedKey(vnetName, localNetworkSiteName, sharedKeyParameters);
        }

        public GatewayGetOperationStatusResponse CreateGateway(string vnetName, string gatewayType, string gatewaySKU)
        {
            GatewayCreateParameters parameters = new GatewayCreateParameters()
            {
                GatewayType = gatewayType,
                GatewaySKU = gatewaySKU,
            };

            return client.Gateways.Create(vnetName, parameters);
        }

        public GatewayGetOperationStatusResponse DeleteGateway(string vnetName)
        {
            return client.Gateways.Delete(vnetName);
        }

        public GatewayGetOperationStatusResponse ResetGateway(string vnetName)
        {
            ResetGatewayParameters parameters = new ResetGatewayParameters();
            return client.Gateways.Reset(vnetName, parameters);
        }

        public GatewayGetOperationStatusResponse ResizeGateway(string vnetName, string gatewaySKU)
        {
            ResizeGatewayParameters parameters = new ResizeGatewayParameters()
            {
                GatewaySKU = gatewaySKU,
            };
            return client.Gateways.Resize(vnetName, parameters);
        }

        public GatewayGetOperationStatusResponse ConnectDisconnectOrTest(string vnetName, string localNetworkSiteName, bool isConnect)
        {
            GatewayConnectDisconnectOrTestParameters connParams = new GatewayConnectDisconnectOrTestParameters()
            {
                Operation = isConnect ? GatewayConnectionUpdateOperation.Connect : GatewayConnectionUpdateOperation.Disconnect
            };

            return client.Gateways.ConnectDisconnectOrTest(vnetName, localNetworkSiteName, connParams);
        }

        public GatewayGetOperationStatusResponse StartDiagnostics(string vnetName, int captureDurationInSeconds, string containerName, AzureStorageContext storageContext)
        {
            StorageCredentials credentials = storageContext.StorageAccount.Credentials;
            string customerStorageKey = credentials.ExportBase64EncodedKey();
            string customerStorageName = credentials.AccountName;
            return StartDiagnostics(vnetName, captureDurationInSeconds, containerName, customerStorageKey, customerStorageName);
        }
        public GatewayGetOperationStatusResponse StartDiagnostics(string vnetName, int captureDurationInSeconds, string containerName, string customerStorageKey, string customerStorageName)
        {
            StartGatewayPublicDiagnosticsParameters parameters = new StartGatewayPublicDiagnosticsParameters()
            {
                CaptureDurationInSeconds = captureDurationInSeconds.ToString(),
                ContainerName = containerName,
                CustomerStorageKey = customerStorageKey,
                CustomerStorageName = customerStorageName,
                Operation = UpdateGatewayPublicDiagnosticsOperation.StartDiagnostics,
            };

            return client.Gateways.StartDiagnostics(vnetName, parameters);
        }

        public GatewayOperationResponse StopDiagnostics(string vnetName)
        {
            StopGatewayPublicDiagnosticsParameters parameters = new StopGatewayPublicDiagnosticsParameters()
            {
                Operation = UpdateGatewayPublicDiagnosticsOperation.StopDiagnostics,
            };

            return client.Gateways.StopDiagnostics(vnetName, parameters);
        }

        public GatewayGetOperationStatusResponse SetDefaultSite(string vnetName, string defaultSiteName)
        {
            GatewaySetDefaultSiteListParameters parameters = new GatewaySetDefaultSiteListParameters()
            {
                DefaultSite = defaultSiteName,
            };

            return client.Gateways.SetDefaultSites(vnetName, parameters);
        }

        public GatewayGetOperationStatusResponse RemoveDefaultSite(string vnetName)
        {
            return client.Gateways.RemoveDefaultSites(vnetName);
        }

        public GatewayGetOperationStatusResponse SetIPsecParameters(string vnetName, string localNetworkName, string encryptionType, string pfsGroup, int saDataSizeKilobytes, int saLifetimeSeconds)
        {
            GatewaySetIPsecParametersParameters parameters = new GatewaySetIPsecParametersParameters()
            {
                Parameters = new IPsecParameters()
                {
                    EncryptionType = encryptionType,
                    PfsGroup = pfsGroup,
                    SADataSizeKilobytes = saDataSizeKilobytes,
                    SALifeTimeSeconds = saLifetimeSeconds,
                },
            };

            return client.Gateways.SetIPsecParameters(vnetName, localNetworkName, parameters);
        }

        public IPsecParameters GetIPsecParameters(string vnetName, string localNetworkName)
        {
            return client.Gateways.GetIPsecParameters(vnetName, localNetworkName).IPsecParameters;
        }

        public IRouteTable GetRouteTable(string routeTableName, bool detailed)
        {
            var getResponse = client.Routes.GetRouteTableWithDetails(routeTableName, detailed ? WithRoutesDetailLevel : WithoutRoutesDetailLevel);
            return detailed
                ? new RouteTableWithRoutes(getResponse.RouteTable)
                : new SimpleRouteTable(getResponse.RouteTable);
        }

        public IEnumerable<IRouteTable> ListRouteTables(bool detailed)
        {
            var routeTableList = client.Routes.ListRouteTables().RouteTables;
            IEnumerable<IRouteTable> result;

            if (detailed)
            {
                // to get the routes, need to specifically call Get for each group
                result = routeTableList.Select(route => GetRouteTable(route.Name, true));
            }

            else
            {
                result = routeTableList.Select(route => new SimpleRouteTable(route.Name, route.Location, route.Label));
            }

            return result;
        }

        public AzureOperationResponse CreateRouteTable(string routeTableName, string label, string location)
        {
            CreateRouteTableParameters parameters = new CreateRouteTableParameters()
            {
                Name = routeTableName,
                Label = label,
                Location = location,
            };

            return client.Routes.CreateRouteTable(parameters);
        }

        public AzureOperationResponse DeleteRouteTable(string routeTableName)
        {
            return client.Routes.DeleteRouteTable(routeTableName);
        }

        public AzureOperationResponse SetRoute(string routeTableName, string routeName, string addressPrefix, string nextHopType, string ipAddress)
        {
            ManagementNextHop nextHop = new ManagementNextHop()
            {
                Type = nextHopType,
                IpAddress = ipAddress
            };
            SetRouteParameters parameters = new SetRouteParameters()
            {
                Name = routeName,
                AddressPrefix = addressPrefix,
                NextHop = nextHop,
            };

            return client.Routes.SetRoute(routeTableName, routeName, parameters);
        }

        public AzureOperationResponse DeleteRoute(string routeTableName, string routeName)
        {
            return client.Routes.DeleteRoute(routeTableName, routeName);
        }

        public SubnetRouteTableContext GetRouteTableForSubnet(string vnetName, string subnetName)
        {
            GetRouteTableForSubnetResponse response = client.Routes.GetRouteTableForSubnet(vnetName, subnetName);
            SubnetRouteTableContext context = new SubnetRouteTableContext()
            {
                RouteTableName = response.RouteTableName,
            };

            return context;
        }

        public AzureOperationResponse AddRouteTableToSubnet(string vnetName, string subnetName, string routeTableName)
        {
            AddRouteTableToSubnetParameters parameters = new AddRouteTableToSubnetParameters()
            {
                RouteTableName = routeTableName,
            };

            return client.Routes.AddRouteTableToSubnet(vnetName, subnetName, parameters);
        }

        public AzureOperationResponse RemoveRouteTableFromSubnet(string vnetName, string subnetName)
        {
            return client.Routes.RemoveRouteTableFromSubnet(vnetName, subnetName);
        }

        private int GetEventId(GatewayEvent gatewayEvent)
        {
            int val = -1;
            if (gatewayEvent != null)
            {
                int.TryParse(gatewayEvent.Id, out val);
            }

            return val;
        }

        private void PopulateOperationContext(string requestId, ManagementOperationContext operationContext)
        {
            OperationStatusResponse operationStatus = managementClient.GetOperationStatus(requestId);
            PopulateOperationContext(operationStatus, operationContext);
        }
        private void PopulateOperationContext(string requestId, IEnumerable<ManagementOperationContext> operationContexts)
        {
            OperationStatusResponse operationStatus = managementClient.GetOperationStatus(requestId);
            foreach (ManagementOperationContext operationContext in operationContexts)
            {
                PopulateOperationContext(operationStatus, operationContext);
            }
        }
        private void PopulateOperationContext(OperationStatusResponse operationStatus, ManagementOperationContext operationContext)
        {
            operationContext.OperationId = operationStatus.Id;
            operationContext.OperationStatus = operationStatus.Status.ToString();
            operationContext.OperationDescription = commandRuntime.ToString();
        }

        private static ClientType CreateClient<ClientType>(AzureSMProfile profile, AzureSubscription subscription) where ClientType : ServiceClient<ClientType>
        {
            return AzureSession.ClientFactory.CreateClient<ClientType>(profile, subscription, AzureEnvironment.Endpoint.ServiceManagement);
        }

        public void CreateNetworkSecurityGroup(string name, string location, string label)
        {
            NetworkSecurityGroupCreateParameters parameters = new NetworkSecurityGroupCreateParameters()
            {
                Location = location,
                Name = name,
                Label = label
            };

            client.NetworkSecurityGroups.Create(parameters);
        }

        public INetworkSecurityGroup GetNetworkSecurityGroup(string name, bool details)
        {
            var getResponse = client.NetworkSecurityGroups.Get(name, details ? "Full" : null);
            return details ? new NetworkSecurityGroupWithRules(getResponse) : new SimpleNetworkSecurityGroup(getResponse);
        }

        public IEnumerable<INetworkSecurityGroup> ListNetworkSecurityGroups(bool details)
        {
            var networkSecurityGroupList = client.NetworkSecurityGroups.List();
            IEnumerable<INetworkSecurityGroup> result;

            if (details)
            {
                // to get the rules, need to specifically call Get for each group
                result = networkSecurityGroupList.Select(nsg => GetNetworkSecurityGroup(nsg.Name, true));
            }

            else
            {
                result = networkSecurityGroupList.Select(nsg => new SimpleNetworkSecurityGroup(nsg.Name, nsg.Location, nsg.Label));
            }

            return result;
        }

        public void SetNetworkSecurityRule(
            string networkSecurityGroupName,
            string ruleName,
            string type,
            int priority,
            string action,
            string sourceAddressPrefix,
            string sourcePortRange,
            string destinationAddressPrefix,
            string destinationPortRange,
            string protocol)
        {
            var setSecurityRuleParameters = new NetworkSecuritySetRuleParameters()
            {
                Type = type,
                Priority = priority,
                Action = action,
                SourceAddressPrefix = sourceAddressPrefix,
                SourcePortRange = sourcePortRange,
                DestinationAddressPrefix = destinationAddressPrefix,
                DestinationPortRange = destinationPortRange,
                Protocol = protocol
            };

            client.NetworkSecurityGroups.SetRule(networkSecurityGroupName, ruleName, setSecurityRuleParameters);
        }

        public void RemoveNetworkSecurityGroup(string name)
        {
            client.NetworkSecurityGroups.Delete(name);
        }

        public void RemoveNetworkSecurityRule(string securityGroupName, string securityRuleName)
        {
            client.NetworkSecurityGroups.DeleteRule(securityGroupName, securityRuleName);
        }

        public NetworkSecurityGroupGetAssociationResponse GetNetworkSecurityGroupForSubnet(string virtualNetworkName, string subnetName)
        {
            return client.NetworkSecurityGroups.GetForSubnet(virtualNetworkName, subnetName);
        }

        public void RemoveNetworkSecurityGroupFromSubnet(string networkSecurityGroupName, string virtualNetworkName, string subnetName)
        {
            client.NetworkSecurityGroups.RemoveFromSubnet(virtualNetworkName, subnetName, networkSecurityGroupName);
        }

        public void SetNetworkSecurityGroupForSubnet(string networkSecurityGroupName, string virtualNetworkName, string subnetName)
        {
            var parameters = new NetworkSecurityGroupAddAssociationParameters()
            {
                Name = networkSecurityGroupName
            };

            client.NetworkSecurityGroups.AddToSubnet(virtualNetworkName, subnetName, parameters);
        }

        public NetworkSecurityGroupGetAssociationResponse GetNetworkSecurityGroupForRole(
            string serviceName,
            string deploymentName,
            string roleName)
        {
            return client.NetworkSecurityGroups.GetForRole(serviceName, deploymentName, roleName);
        }

        public void RemoveNetworkSecurityGroupFromRole(string networkSecurityGroupName, string serviceName, string deploymentName, string roleName)
        {
            client.NetworkSecurityGroups.RemoveFromRole(
                serviceName,
                deploymentName,
                roleName,
                networkSecurityGroupName);
        }

        public void SetNetworkSecurityGroupForRole(string networkSecurityGroupName, string serviceName, string deploymentName, string roleName)
        {
            var parameters = new NetworkSecurityGroupAddAssociationParameters()
            {
                Name = networkSecurityGroupName
            };

            client.NetworkSecurityGroups.AddToRole(serviceName, deploymentName, roleName, parameters);
        }

        public NetworkSecurityGroupGetAssociationResponse GetNetworkSecurityGroupForNetworkInterface(
            string serviceName,
            string deploymentName,
            string roleName,
            string networkInterfaceName)
        {
            return client.NetworkSecurityGroups.GetForNetworkInterface(
                serviceName,
                deploymentName,
                roleName,
                networkInterfaceName);
        }

        public void RemoveNetworkSecurityGroupFromNetworkInterface(
            string networkSecurityGroupName,
            string serviceName,
            string deploymentName,
            string roleName,
            string networkInterfaceName)
        {
            client.NetworkSecurityGroups.RemoveFromNetworkInterface(
                serviceName,
                deploymentName,
                roleName,
                networkInterfaceName,
                networkSecurityGroupName);
        }

        public void SetNetworkSecurityGroupForNetworkInterface(
            string networkSecurityGroupName,
            string serviceName,
            string deploymentName,
            string roleName,
            string networkInterfaceName)
        {
            var parameters = new NetworkSecurityGroupAddAssociationParameters()
            {
                Name = networkSecurityGroupName
            };

            client.NetworkSecurityGroups.AddToNetworkInterface(
                serviceName,
                deploymentName,
                roleName,
                networkInterfaceName,
                parameters);
        }

        public string GetDeploymentBySlot(string serviceName, string slot)
        {
            if (string.IsNullOrEmpty(serviceName))
            {
                throw new ArgumentNullException(serviceName);
            }

            if (string.IsNullOrEmpty(slot))
            {
                throw new ArgumentNullException(slot);
            }

            var slotType = (ComputeModels.DeploymentSlot)Enum.Parse(typeof(ComputeModels.DeploymentSlot), slot, true);

            return this.computeClient.Deployments.GetBySlot(
                        serviceName,
                        slotType).Name;
        }

        public string GetDeploymentName(PersistentVMRoleContext vm, string slot, string serviceName)
        {
            string deploymentName = null;
            if (vm != null)
            {
                deploymentName = vm.DeploymentName;
            }

            if (string.IsNullOrEmpty(slot) && string.IsNullOrEmpty(deploymentName))
            {
                slot = DeploymentSlotType.Production;
            }

            if (string.IsNullOrEmpty(deploymentName))
            {
                deploymentName = this.GetDeploymentBySlot(serviceName, slot);
            }

            return deploymentName;
        }

        public GetEffectiveRouteTableResponse GetEffectiveRouteTableForRoleInstance(
            string serviceName,
            string deploymentName,
            string roleInstanceName)
        {
            return this.client.Routes.GetEffectiveRouteTableForRoleInstance(
                serviceName,
                deploymentName,
                roleInstanceName);
        }

        public GetEffectiveRouteTableResponse GetEffectiveRouteTableForNetworkInterface(
            string serviceName,
            string deploymentName,
            string roleInstanceName,
            string networkInterfaceName)
        {
            return this.client.Routes.GetEffectiveRouteTableForNetworkInterface(
                serviceName,
                deploymentName,
                roleInstanceName,
                networkInterfaceName);
        }

        public void SetIPForwardingForRole(string serviceName, string deploymentName, string roleName, bool ipForwarding)
        {
            var parameters = new IPForwardingSetParameters()
            {
                State = ipForwarding ? "Enabled" : "Disabled"
            };

            client.IPForwarding.SetOnRole(serviceName, deploymentName, roleName, parameters);
        }

        public void SetIPForwardingForNetworkInterface(string serviceName, string deploymentName, string roleName, string networkInterfaceName, bool ipForwarding)
        {
            var parameters = new IPForwardingSetParameters()
            {
                State = ipForwarding ? "Enabled" : "Disabled"
            };

            client.IPForwarding.SetOnNetworkInterface(serviceName, deploymentName, roleName, networkInterfaceName, parameters);
        }

        public string GetIPForwardingForRole(string serviceName, string deploymentName, string roleName)
        {
            IPForwardingGetResponse ipForwardingGetResponse = client.IPForwarding.GetForRole(serviceName, deploymentName, roleName);
            return ipForwardingGetResponse.State;
        }
        public string GetIPForwardingForNetworkInterface(string serviceName, string deploymentName, string roleName, string networkInterfaceName)
        {
            IPForwardingGetResponse ipForwardingGetResponse = client.IPForwarding.GetForNetworkInterface(serviceName, deploymentName, roleName, networkInterfaceName);
            return ipForwardingGetResponse.State;
        }

        public GetVirtualNetworkGatewayContext GetVirtualNetworkGateway(string gatewayId)
        {
            if (string.IsNullOrWhiteSpace(gatewayId))
            {
                throw new ArgumentException("gatewayId cannot be null or whitespace.", "gatewayId");
            }

            VirtualNetworkGatewayGetResponse response = client.Gateways.GetVirtualNetworkGateway(gatewayId);

            GetVirtualNetworkGatewayContext gatewayContext = new GetVirtualNetworkGatewayContext()
            {
                GatewayId = response.GatewayId.ToString(),
                GatewayName = response.GatewayName,
                GatewayType = response.GatewayType,
                LastEventData = (response.LastEvent != null) ? response.LastEvent.Data : null,
                LastEventMessage = (response.LastEvent != null) ? response.LastEvent.Message : null,
                LastEventID = GetEventId(response.LastEvent),
                LastEventTimeStamp = (response.LastEvent != null) ? (DateTime?)response.LastEvent.Timestamp : null,
                State = (ProvisioningState)Enum.Parse(typeof(ProvisioningState), response.State, true),
                VIPAddress = response.VipAddress,
                DefaultSite = (response.DefaultSite != null ? response.DefaultSite.Name : null),
                GatewaySKU = response.GatewaySKU,
                Location = response.Location,
                VnetId = response.VnetId,
                SubnetId = response.SubnetId,
                EnableBgp = response.EnableBgp.ToString(),
            };
            PopulateOperationContext(response.RequestId, gatewayContext);

            return gatewayContext;
        }

        public GetVirtualNetworkGatewayConnectionContext GetVirtualNetworkGatewayConnection(string gatewayId, string connectedentityId)
        {
            if (string.IsNullOrWhiteSpace(gatewayId))
            {
                throw new ArgumentException("gatewayId cannot be null or whitespace.", "gatewayId");
            }
            if (string.IsNullOrWhiteSpace(connectedentityId))
            {
                throw new ArgumentException("connectedentityId cannot be null or whitespace.", "connectedentityId");
            }

            GatewayConnectionGetResponse response = client.Gateways.GetGatewayConnection(gatewayId, connectedentityId);

            GetVirtualNetworkGatewayConnectionContext gatewayContext = new GetVirtualNetworkGatewayConnectionContext()
            {
                GatewayConnectionName = response.GatewayConnectionName.ToString(),
                VirtualNetworkGatewayId = response.VirtualNetworkGatewayId.ToString(),
                ConnectedEntityId = response.ConnectedEntityId,
                GatewayConnectionType = response.GatewayConnectionType,
                RoutingWeight = response.RoutingWeight,
                SharedKey = response.SharedKey,
            };
            PopulateOperationContext(response.RequestId, gatewayContext);

            return gatewayContext;
        }

        public GetLocalNetworkGatewayContext GetLocalNetworkGateway(string gatewayId)
        {
            if (string.IsNullOrWhiteSpace(gatewayId))
            {
                throw new ArgumentException("gatewayId cannot be null or whitespace.", "gatewayId");
            }

            LocalNetworkGatewayGetResponse response = client.Gateways.GetLocalNetworkGateway(gatewayId);

            GetLocalNetworkGatewayContext gatewayContext = new GetLocalNetworkGatewayContext()
            {
                GatewayId = response.Id.ToString(),
                GatewayName = response.GatewayName,
                IpAddress = response.IpAddress,
                AddressSpace = response.AddressSpace.ToList(),
            };
            PopulateOperationContext(response.RequestId, gatewayContext);

            return gatewayContext;
        }
        public IEnumerable<GetVirtualNetworkGatewayConnectionContext> ListVirtualNetworkGatewayConnections()
        {
            GatewayListGatewayConnectionsResponse response = client.Gateways.ListGatewayConnections();

            IEnumerable<GetVirtualNetworkGatewayConnectionContext> connections = response.VirtualNetworkGatewayConnections.Select(
                (GatewayListGatewayConnectionsResponse.VirtualNetworkGatewayConnection connection) =>
                {
                    return new GetVirtualNetworkGatewayConnectionContext()
                    {
                        GatewayConnectionName = connection.GatewayConnectionName,
                        VirtualNetworkGatewayId = connection.VirtualNetworkGatewayId.ToString(),
                        ConnectedEntityId = connection.ConnectedEntityId,
                        GatewayConnectionType = connection.GatewayConnectionType,
                        RoutingWeight = connection.RoutingWeight,
                        SharedKey = connection.SharedKey,
                    };
                });
            PopulateOperationContext(response.RequestId, connections);

            return connections;
        }

        public IEnumerable<GetVirtualNetworkGatewayContext> ListVirtualNetworkGateways()
        {
            ListVirtualNetworkGatewaysResponse response = client.Gateways.ListVirtualNetworkGateways();

            IEnumerable<GetVirtualNetworkGatewayContext> virtualNetworkGateways = response.VirtualNetworkGateways.Select(
                (ListVirtualNetworkGatewaysResponse.VirtualNetworkGateway virtualNetworkGateway) =>
                {
                    return new GetVirtualNetworkGatewayContext()
                    {
                        GatewayId = virtualNetworkGateway.GatewayId.ToString(),
                        GatewayName = virtualNetworkGateway.GatewayName,
                        GatewayType = virtualNetworkGateway.GatewayType,
                        LastEventData = (virtualNetworkGateway.LastEvent != null) ? virtualNetworkGateway.LastEvent.Data : null,
                        LastEventMessage = (virtualNetworkGateway.LastEvent != null) ? virtualNetworkGateway.LastEvent.Message : null,
                        LastEventID = GetEventId(virtualNetworkGateway.LastEvent),
                        LastEventTimeStamp = (virtualNetworkGateway.LastEvent != null) ? (DateTime?)virtualNetworkGateway.LastEvent.Timestamp : null,
                        State = (ProvisioningState)Enum.Parse(typeof(ProvisioningState), virtualNetworkGateway.State, true),
                        VIPAddress = virtualNetworkGateway.VipAddress,
                        DefaultSite = (virtualNetworkGateway.DefaultSite != null ? virtualNetworkGateway.DefaultSite.Name : null),
                        GatewaySKU = virtualNetworkGateway.GatewaySKU,
                        Location = virtualNetworkGateway.Location,
                        VnetId = virtualNetworkGateway.VnetId,
                        SubnetId = virtualNetworkGateway.SubnetId,
                        EnableBgp = virtualNetworkGateway.EnableBgp.ToString(),
                    };
                });
            PopulateOperationContext(response.RequestId, virtualNetworkGateways);

            return virtualNetworkGateways;
        }

        public IEnumerable<GetLocalNetworkGatewayContext> ListLocalNetworkGateways()
        {
            ListLocalNetworkGatewaysResponse response = client.Gateways.ListLocalNetworkGateways();

            IEnumerable<GetLocalNetworkGatewayContext> localNetworkGateways = response.LocalNetworkGateways.Select(
                (ListLocalNetworkGatewaysResponse.LocalNetworkGateway localNetworkGateway) =>
                {
                    return new GetLocalNetworkGatewayContext()
                    {
                        GatewayId = localNetworkGateway.Id.ToString(),
                        GatewayName = localNetworkGateway.GatewayName,
                        IpAddress = localNetworkGateway.IpAddress,
                        AddressSpace = localNetworkGateway.AddressSpace.ToList(),
                    };
                });
            PopulateOperationContext(response.RequestId, localNetworkGateways);

            return localNetworkGateways;
        }

        public VirtualNetworkDiagnosticsContext GetDiagnosticsV2(string gatewayId)
        {
            GatewayDiagnosticsStatus diagnosticsStatus = client.Gateways.GetDiagnosticsV2(gatewayId);

            VirtualNetworkDiagnosticsContext diagnosticsContext = new VirtualNetworkDiagnosticsContext()
            {
                DiagnosticsUrl = diagnosticsStatus.DiagnosticsUrl,
                State = diagnosticsStatus.State,
            };
            PopulateOperationContext(diagnosticsStatus.RequestId, diagnosticsContext);

            return diagnosticsContext;
        }

        public SharedKeyContext GetSharedKeyV2(string gatewayId, string connectedentityId)
        {
            GatewayGetSharedKeyResponse response = client.Gateways.GetSharedKeyV2(gatewayId, connectedentityId);

            SharedKeyContext sharedKeyContext = new SharedKeyContext()
            {
                Value = response.SharedKey
            };
            PopulateOperationContext(response.RequestId, sharedKeyContext);

            return sharedKeyContext;
        }

        public GatewayGetOperationStatusResponse CreateVirtualNetworkGateway(string vnetName, string gatewayName, string gatewayType, string gatewaySKU, string location, string vnetId)
        {
            VirtualNetworkGatewayCreateParameters parameters = new VirtualNetworkGatewayCreateParameters()
            {
                GatewayName = gatewayName,
                GatewaySKU = gatewaySKU,
                GatewayType = gatewayType,
                Location = location,
                VnetId = vnetId,
            };

            return client.Gateways.CreateVirtualNetworkGateway(vnetName, parameters);
        }

        public GatewayGetOperationStatusResponse CreateVirtualNetworkGatewayConnection(string connectedEntityId, string gatewayConnectionName, string gatewayConnectionType,
            int routingWeight, string sharedKey, Guid virtualNetworkGatewayId)
        {
            GatewayConnectionCreateParameters parameters = new GatewayConnectionCreateParameters()
            {
                ConnectedEntityId = connectedEntityId,
                GatewayConnectionName = gatewayConnectionName,
                GatewayConnectionType = gatewayConnectionType,
                VirtualNetworkGatewayId = virtualNetworkGatewayId,
                RoutingWeight = routingWeight,
                SharedKey = sharedKey,
            };

            return client.Gateways.CreateGatewayConnection(parameters);
        }

        public LocalNetworkGatewayCreateResponse CreateLocalNetworkGateway(string gatewayName, string ipAddress, List<string> addressSpace)
        {
            LocalNetworkGatewayCreateParameters parameters = new LocalNetworkGatewayCreateParameters()
            {
                AddressSpace = addressSpace,
                GatewayName = gatewayName,
                IpAddress = ipAddress,
            };

            return client.Gateways.CreateLocalNetworkGateway(parameters);
        }

        public GatewayGetOperationStatusResponse DeleteVirtualNetworkGateway(string gatewayId)
        {
            return client.Gateways.DeleteVirtualNetworkGateway(gatewayId);
        }

        public GatewayGetOperationStatusResponse DeleteVirtualNetworkGatewayConnection(string gatewayId, string connectedentityId)
        {
            return client.Gateways.DeleteGatewayConnection(gatewayId, connectedentityId);
        }

        public AzureOperationResponse DeleteLocalNetworkGateway(string gatewayId)
        {
            return client.Gateways.DeleteLocalNetworkGateway(gatewayId);
        }

        public GatewayGetOperationStatusResponse ResetVirtualNetworkGateway(string gatewayId)
        {
            ResetGatewayParameters parameters = new ResetGatewayParameters();
            return client.Gateways.ResetVirtualNetworkGateway(gatewayId, parameters);
        }

        public GatewayGetOperationStatusResponse SetSharedKeyV2(string gatewayId, string connectedentityId, string sharedKey)
        {
            GatewaySetSharedKeyParameters sharedKeyParameters = new GatewaySetSharedKeyParameters()
            {
                Value = sharedKey,
            };

            return client.Gateways.SetSharedKeyV2(gatewayId, connectedentityId, sharedKeyParameters);
        }

        public GatewayGetOperationStatusResponse ResetSharedKeyV2(string gatewayId, string connectedentityId, int keyLength)
        {
            GatewayResetSharedKeyParameters parameters = new GatewayResetSharedKeyParameters()
            {
                KeyLength = keyLength,
            };
            return client.Gateways.ResetSharedKeyV2(gatewayId, connectedentityId, parameters);
        }

        public GatewayGetOperationStatusResponse ResizeVirtualNetworkGateway(string gatewayId, string gatewaySKU)
        {
            ResizeGatewayParameters parameters = new ResizeGatewayParameters()
            {
                GatewaySKU = gatewaySKU,
            };
            return client.Gateways.ResizeVirtualNetworkGateway(gatewayId, parameters);
        }

        public GatewayGetOperationStatusResponse UpdateVirtualNetworkGatewayConnection(string gatewayId, string connectedentityId, int routingWeight, string sharedKey)
        {
            UpdateGatewayConnectionParameters parameters = new UpdateGatewayConnectionParameters()
            {
                RoutingWeight = routingWeight,
                SharedKey = sharedKey,
            };
            return client.Gateways.UpdateGatewayConnection(gatewayId, connectedentityId, parameters);
        }

        public AzureOperationResponse UpdateLocalNetworkGateway(string gatewayId, List<string> addressSpace)
        {
            UpdateLocalNetworkGatewayParameters parameters = new UpdateLocalNetworkGatewayParameters()
            {
                AddressSpace = addressSpace,
            };

            return client.Gateways.UpdateLocalNetworkGateway(gatewayId, parameters);
        }

        public GatewayGetOperationStatusResponse StartDiagnosticsV2(string gatewayId, int captureDurationInSeconds, string containerName, AzureStorageContext storageContext)
        {
            StorageCredentials credentials = storageContext.StorageAccount.Credentials;
            string customerStorageKey = credentials.ExportBase64EncodedKey();
            string customerStorageName = credentials.AccountName;
            return StartDiagnosticsV2(gatewayId, captureDurationInSeconds, containerName, customerStorageKey, customerStorageName);
        }
        public GatewayGetOperationStatusResponse StartDiagnosticsV2(string gatewayId, int captureDurationInSeconds, string containerName, string customerStorageKey, string customerStorageName)
        {
            StartGatewayPublicDiagnosticsParameters parameters = new StartGatewayPublicDiagnosticsParameters()
            {
                CaptureDurationInSeconds = captureDurationInSeconds.ToString(),
                ContainerName = containerName,
                CustomerStorageKey = customerStorageKey,
                CustomerStorageName = customerStorageName,
                Operation = UpdateGatewayPublicDiagnosticsOperation.StartDiagnostics,
            };

            return client.Gateways.StartDiagnosticsV2(gatewayId, parameters);
        }

        public GatewayOperationResponse StopDiagnosticsV2(string gatewayId)
        {
            StopGatewayPublicDiagnosticsParameters parameters = new StopGatewayPublicDiagnosticsParameters()
            {
                Operation = UpdateGatewayPublicDiagnosticsOperation.StopDiagnostics,
            };

            return client.Gateways.StopDiagnosticsV2(gatewayId, parameters);
        }

        public GatewayGetOperationStatusResponse SetIPsecParametersV2(string gatewayId, string connectedentityId, string encryptionType, string pfsGroup, int saDataSizeKilobytes, int saLifetimeSeconds)
        {
            GatewaySetIPsecParametersParameters parameters = new GatewaySetIPsecParametersParameters()
            {
                Parameters = new IPsecParameters()
                {
                    EncryptionType = encryptionType,
                    PfsGroup = pfsGroup,
                    SADataSizeKilobytes = saDataSizeKilobytes,
                    SALifeTimeSeconds = saLifetimeSeconds,
                },
            };

            return client.Gateways.SetIPsecParametersV2(gatewayId, connectedentityId, parameters);
        }

        public IPsecParameters GetIPsecParametersV2(string gatewayId, string connectedentityId)
        {
            return client.Gateways.GetIPsecParametersV2(gatewayId, connectedentityId).IPsecParameters;
        }

    }
}

redpajama_set_name: RedPajamaGithub


text:
package com.sarahtolsma.divulge.module.events;

/**
 * Represents an event.
 */
public abstract class Event
{
    /**
     * The package this event originated from.
     */
    public String packageName;

    /**
     * The source of the event.
     */
    public String source;

    /**
     * The event type.
     */
    public EventType type;

    /**
     * Initializes a new instance of the Event class.
     */
    protected Event(EventType type, String source)
    {
        this.source = source;
        this.type = type;
    }
}


text:
package com.yjl.spring.service;

/**
 * Created by ziew on 2015/5/24.
 */
public interface MovieRatingService {
    int rateMovie(int userId, int movieId, double rate);
}


text:
import numpy as np
from math import sqrt
from cmath import exp, pi

# Function f takes N and a as parameters and returns a function f_a,N(x) that returns a^x Mod N
def f(N, a):
	return lambda x: pow(a, x, N)

# Now using map we can apply a function f(N, a) to a list of values [x1, ..., xn].
# i. e.: list(map(f(15, 2), [0, 1, 2, 3]))

# We are trying to find the period of a function f(N, a). We are going to define a function that tries to find the period.
# We call period to the smallest r > 0 with a^r Mod N = 1.
# We won't use map because we don't need to store all the results in memory, we only need to check them one by one.
def findPeriod(N, a):
	f_aN = f(N, a)
	for i in range(1, N):
		if f_aN(i) == 1:
			return i
	return None

# Function that returns an array of nth roots of the unity
def nroots(n, rc = 14): # Rounds to 14 decimal places by default
	c = 2j * pi / n
	gen = (exp(k * c) for k in range(n))
	return [round(i.real, rc) + round(i.imag, rc) * 1j for i in gen]

# Function that creates a vandermonde matrix for the given values
def vandermonde(*args):
	return np.array([[pow(arg, i) for i in range(len(args))] for arg in args])

# Function that creates a vandermonde matrix of the given size with the roots of the unity
def vanderomega(size, rc = 14):
	return vandermonde(*nroots(size, rc))

def DFT(size, rc = 14):
	return 1/sqrt(size) * vanderomega(size, rc)


text:
export builddir_name ?= src/third_party/expat/out
.PHONY: all
all:
	$(MAKE) -C ../.. expat


text:
package org.spongepowered.common.profile;

import org.checkerframework.checker.nullness.qual.NonNull;
import org.spongepowered.api.data.persistence.AbstractDataBuilder;
import org.spongepowered.api.data.persistence.DataView;
import org.spongepowered.api.data.persistence.InvalidDataException;
import org.spongepowered.api.data.persistence.Queries;
import org.spongepowered.api.profile.property.ProfileProperty;

import java.util.Optional;

public final class SpongeProfilePropertyDataBuilder extends AbstractDataBuilder<@NonNull ProfileProperty> {

    public SpongeProfilePropertyDataBuilder() {
        super(ProfileProperty.class, 1);
    }

    @Override
    protected Optional<@NonNull ProfileProperty> buildContent(final DataView container) throws InvalidDataException {
        if (!container.contains(Queries.PROPERTY_NAME, Queries.PROPERTY_VALUE)) {
            return Optional.empty();
        }

        return Optional.of(new SpongeProfileProperty(
                container.getString(Queries.PROPERTY_NAME).get(),
                container.getString(Queries.PROPERTY_VALUE).get(),
                container.getString(Queries.PROPERTY_SIGNATURE).orElse(null)));
    }

}


text:
SYNONYM

#### According to
The Catalogue of Life, 3rd January 2011

#### Published in
in de Candolle & Lamarck, Fl. franç. (Paris), Edn 3 6: 41 (1815)

#### Original name
Boletus soloniensis Dubois, 1815

### Remarks
null


text:
![Cuttle](readme-img/cuttle-banner.png)

__NOTE: project discontinued__

Cuttle is a standalone application that aims to be __the simplest way to use
ClojureScript__.  It provides a user-friendly interface, allowing you to build
projects by clicking a button, and to see meaningful warnings and errors at a
glance.  In a way, it provides the "builder" parts of an IDE without making you
leave your favorite editor.

Under the hood, Cuttle is not hiding a lot of magic from you.  It uses standard
ClojureScript workflow tools to perform its operations.  It uses Leiningen with
the lein-cljsbuild plugin listed in your project.clj, and the mies template for
creating new projects.  Thus, it should produce the same expected behavior as
these standard tools.

Cuttle is itself a ClojureScript application :) (running on a Node/Chromium
framework called Atom Shell). We hope this tool encourages you to explore
building ClojureScript apps for the browser, Node, and other JS-targetted
platforms.

## Installation

__Download Cuttle v1.1__:

[ Windows Installer](https://github.com/oakmac/cuttle/releases/download/v1.1/cuttle-v1.1-windows.exe)

[ Mac DMG](https://github.com/oakmac/cuttle/releases/download/v1.1/cuttle-v1.1-mac.dmg)

[ Linux zip](https://github.com/oakmac/cuttle/releases/download/v1.1/cuttle-v1.1-linux-x86_64.tar.gz)

(Please make sure to install a [JRE >= 7](http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html))

__Homebrew Cask__

```
$ brew install caskroom/cask/brew-cask
$ brew cask install cuttle
```

Homebrew-cask provides a friendly homebrew-style CLI workflow for the administration of Mac applications distributed as binaries.

It's implemented as a `homebrew` [external command](https://github.com/Homebrew/homebrew/blob/master/share/doc/homebrew/External-Commands.md) called `cask`.

## User Guide

- When first opening Cuttle, you will be prompted to add an existing project or
  to create a new one.
- __Add Existing Project__: If you are adding an existing project, you must
  navigate the presented dialog to the project's `project.clj` file so that we
  can find your configured builds.
  - (We currently do not support cljsbuild configurations outside of the
    default `:dev` profile).
- __Add New Project__: If you are creating a new project, you will be prompted
  for a name and location for its folder.
  - (The standard `lein new mies` template will be used to create the project.)
- __Build Table__: Once you have loaded a project, you will be presented with a
  table of build configurations available for that project. Current status of
  the build, along with warnings and errors will be displayed here.
- __Build Button__: At the top-right of the build table, you should see a build
  button.  You can first select the dropdown arrow to specifically set which
  builds to compile and whether or not to automatically recompile when files
  change.  Click the button proper to start building.
- __Multiple Projects__: You can add multiple projects to this workspace.  The
  projects are treated with isolated compiler instances and can be built in
  parallel.
- __Project Buttons__: The project buttons at the top-left of the build table
  are also helpful for opening the project folder, re-fetching the build
  configs, and removing the project from the workspace.
- __Notifications__: The settings link at the top-right of the page currently
  holds options for toggling compiler notifications
  - (via Mac native Notifications, Linux `notify-send`, or Growl For Windows).
- __Shutting Down__: When closing the application, all compiler instances that
  happen to still be running are shutdown.  Your configurations are saved and
  reloaded when re-opening the application.

## Future

We welcome your ideas, bug reports, and pull requests!

With the ClojureScript tooling community rapidly growing, we hope to keep
improving the user experience to integrate new workflows, while also keeping
its behavior simple and predictable.  Some ideas we are thinking about:

- [Integration with Figwheel](https://github.com/oakmac/cuttle/issues/53)
- a basic REPL for experimenting
- [a full project-connected REPL](https://github.com/oakmac/cuttle/issues/54)
- an interface for reading/modifying project.clj
- [a test-runner for cljs.test](https://github.com/oakmac/cuttle/issues/28)

## Development Setup

To setup a environment for building Cuttle:

1. Install [Leiningen] and [Node.js].
1. One-time setup. Run from the project directory:

    ```sh
    # linux/mac
    scripts/setup.sh

    # windows
    scripts/setup.bat
    ```

1. Compile LESS and ClojureScript:

    ```sh
    grunt fresh-build
    ```

1. Launch to try it out:

    ```sh
    grunt launch
    ```

1. Assemble a release for your OS:

    ```sh
    grunt release
    ```

## About the Name/Logo

Cuttle is named after the [Cuttlefish] because [Shaun] likes cephalopods.
The logo is modeled after its uniquely shaped [eye].

The first three letters of Cuttle might stand for "ClojureScript User Tool", but
the last three letters don't stand for anything because Cuttle is not an
acronym.

Cuttle should be capitalized like a proper noun when used in a sentence.

## License

All code licensed under the terms of the [MIT
License](https://github.com/oakmac/cuttle/blob/master/LICENSE.md).

[Leiningen]:http://leiningen.org
[Node.js]:http://nodejs.org
[Atom Shell]:https://github.com/atom/atom-shell
[Cuttlefish]:https://flic.kr/p/8oVLuC
[Shaun]:https://github.com/shaunlebron
[eye]:http://mentaldstruction.deviantart.com/art/Baby-Cuttlefish-112140710


text:
/*
Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array.
*/
public class Solution {
    public int missingNumber(int[] nums) {
        // 11:45 - 11:46
        int n = nums.length;
        int sum = 0;
        for(int num : nums) sum += num;
        int noMissingSum = (0 + n) * (n + 1) / 2;
        return noMissingSum - sum;
    }
}


text:
<?php

namespace Omnipay\WechatPay\Message;

use GuzzleHttp\Client;
use Omnipay\Common\Exception\InvalidRequestException;
use Omnipay\Common\Message\ResponseInterface;
use Omnipay\WechatPay\Helper;

/**
 * Class PromotionTransferRequest
 *
 * @package Omnipay\WechatPay\Message
 * @link    https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2
 * @method  PromotionTransferResponse send()
 */
class PromotionTransferRequest extends BaseAbstractRequest
{
    protected $endpoint = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers';

    /**
     * Get the raw data array for this message. The format of this varies from gateway to
     * gateway, but will usually be either an associative array, or a SimpleXMLElement.
     * @return mixed
     * @throws InvalidRequestException
     */
    public function getData()
    {
        $this->validate('app_id', 'mch_id', 'partner_trade_no', 'cert_path', 'key_path');

        $data = array(
            'mch_appid'        => $this->getAppId(),
            'mchid'            => $this->getMchId(),
            'device_info'      => $this->getDeviceInfo(),     // <optional>
            'partner_trade_no' => $this->getPartnerTradeNo(),
            'openid'           => $this->getOpenId(),
            'check_name'       => $this->getCheckName(),      // <NO_CHECK or FORCE_CHECK>
            're_user_name'     => $this->getReUserName(),
            'amount'           => $this->getAmount(),
            'desc'             => $this->getDesc(),
            'spbill_create_ip' => $this->getSpbillCreateIp(),
            'nonce_str'        => md5(uniqid()),
        );

        $data = array_filter($data);

        $data['sign'] = Helper::sign($data, $this->getApiKey());

        return $data;
    }

    /**
     * @return mixed
     */
    public function getDeviceInfo()
    {
        return $this->getParameter('device_Info');
    }

    /**
     * @param mixed $deviceInfo
     */
    public function setDeviceInfo($deviceInfo)
    {
        $this->setParameter('device_Info', $deviceInfo);
    }

    /**
     * @return mixed
     */
    public function getPartnerTradeNo()
    {
        return $this->getParameter('partner_trade_no');
    }

    /**
     * @param mixed $partnerTradeNo
     */
    public function setPartnerTradeNo($partnerTradeNo)
    {
        $this->setParameter('partner_trade_no', $partnerTradeNo);
    }

    /**
     * @return mixed
     */
    public function getOpenId()
    {
        return $this->getParameter('open_id');
    }

    /**
     * @param mixed $openId
     */
    public function setOpenId($openId)
    {
        $this->setParameter('open_id', $openId);
    }

    /**
     * @return mixed
     */
    public function getCheckName()
    {
        return $this->getParameter('check_name');
    }

    /**
     * @param mixed $checkName
     */
    public function setCheckName($checkName)
    {
        $this->setParameter('check_name', $checkName);
    }

    /**
     * @return mixed
     */
    public function getReUserName()
    {
        return $this->getParameter('re_user_name');
    }

    /**
     * @param mixed $reUserNamme
     */
    public function setReUserName($reUserName)
    {
        $this->setParameter('re_user_name', $reUserName);
    }

    /**
     * @return mixed
     */
    public function getAmount()
    {
        return $this->getParameter('amount');
    }

    /**
     * @param mixed $amount
     */
    public function setAmount($amount)
    {
        $this->setParameter('amount', $amount);
    }

    /**
     * @return mixed
     */
    public function getDesc()
    {
        return $this->getParameter('desc');
    }

    /**
     * @param mixed $desc
     */
    public function setDesc($desc)
    {
        $this->setParameter('desc', $desc);
    }

    /**
     * @return mixed
     */
    public function getSpbillCreateIp()
    {
        return $this->getParameter('spbill_create_ip');
    }

    /**
     * @param mixed $spbill_create_ip
     */
    public function setSpbillCreateIp($spbillCreateIp)
    {
        $this->setParameter('spbill_create_ip', $spbillCreateIp);
    }

    /**
     * @return mixed
     */
    public function getCertPath()
    {
        return $this->getParameter('cert_path');
    }

    /**
     * @param mixed $certPath
     */
    public function setCertPath($certPath)
    {
        $this->setParameter('cert_path', $certPath);
    }

    /**
     * @return mixed
     */
    public function getKeyPath()
    {
        return $this->getParameter('key_path');
    }

    /**
     * @param mixed $keyPath
     */
    public function setKeyPath($keyPath)
    {
        $this->setParameter('key_path', $keyPath);
    }

    /**
     * Send the request with specified data
     *
     * @param  mixed $data The data to send
     *
     * @return ResponseInterface
     */
    public function sendData($data)
    {
        $body         = Helper::array2xml($data);
        $client = new Client();

        $options = [
            'body'    => $body,
            'verify'  => true,
            'cert'    => $this->getCertPath(),
            'ssl_key' => $this->getKeyPath(),
        ];
        $response = $client->request('POST', $this->endpoint, $options)->getBody();
        $responseData = Helper::xml2array($response);

        return $this->response = new PromotionTransferResponse($this, $responseData);
    }
}


text:
/*
 * netof - return the net address part of an ip address in a sockaddr_storage structure
 *         (zero out host part)
 */
#include <config.h>
#include <stdio.h>
#include <syslog.h>

#include "ntp_fp.h"
#include "ntp_net.h"
#include "ntp_stdlib.h"
#include "ntp.h"

sockaddr_u *
netof(
	sockaddr_u *hostaddr
	)
{
	static sockaddr_u	netofbuf[8];
	static int		next_netofbuf;
	u_int32			netnum;
	sockaddr_u *		netaddr;

	netaddr = &netofbuf[next_netofbuf];
	next_netofbuf = (next_netofbuf + 1) % COUNTOF(netofbuf);

	memcpy(netaddr, hostaddr, sizeof(*netaddr));

	if (IS_IPV4(netaddr)) {
		netnum = SRCADR(netaddr);

		/*
		 * We live in a modern CIDR world where the basement nets, which
		 * used to be class A, are now probably associated with each
		 * host address. So, for class-A nets, all bits are significant.
		 */
		if (IN_CLASSC(netnum))
			netnum &= IN_CLASSC_NET;
		else if (IN_CLASSB(netnum))
			netnum &= IN_CLASSB_NET;

		SET_ADDR4(netaddr, netnum);

	} else if (IS_IPV6(netaddr))
		/* assume the typical /64 subnet size */
		zero_mem(&NSRCADR6(netaddr)[8], 8);
#ifdef DEBUG
	else {
		msyslog(LOG_ERR, "netof unknown AF %d", AF(netaddr));
		exit(1);
	}
#endif

	return netaddr;
}


text:
package com.acadiasoft.im.simm.model.param;

import com.acadiasoft.im.simm.config.HoldingPeriod;
import com.acadiasoft.im.simm.config.SimmConfig;
import com.acadiasoft.im.simm.model.SensitivityIdentifier;
import com.acadiasoft.im.simm.model.imtree.identifiers.RiskClass;
import com.acadiasoft.im.simm.model.imtree.identifiers.SensitivityClass;
import com.acadiasoft.im.simm.model.imtree.identifiers.WeightingClass;
import com.acadiasoft.im.simm.model.param.cnq.CreditNonQualifyingRiskWeight;
import com.acadiasoft.im.simm.model.param.cnq.CreditNonQualifyingRiskWeight1d;
import com.acadiasoft.im.simm.model.param.commodity.CommodityRiskWeight;
import com.acadiasoft.im.simm.model.param.commodity.CommodityRiskWeight1d;
import com.acadiasoft.im.simm.model.param.cq.CreditQualifyingRiskWeight;
import com.acadiasoft.im.simm.model.param.cq.CreditQualifyingRiskWeight1d;
import com.acadiasoft.im.simm.model.param.equity.EquityRiskWeight;
import com.acadiasoft.im.simm.model.param.equity.EquityRiskWeight1d;
import com.acadiasoft.im.simm.model.param.fx.FXRiskWeight;
import com.acadiasoft.im.simm.model.param.fx.FXRiskWeight1d;
import com.acadiasoft.im.simm.model.param.interestrate.InterestRateRiskWeight;
import com.acadiasoft.im.simm.model.param.interestrate.InterestRateRiskWeight1d;

import java.math.BigDecimal;

public interface SimmRiskWeight {

  static BigDecimal get(SensitivityClass s, WeightingClass weightingClass, SimmConfig config) {
    RiskClass r = weightingClass.getRiskIdentifier();
    if (s.equals(SensitivityClass.DELTA)) {
      if (r.equals(RiskClass.FX) && config.holdingPeriod().equals(HoldingPeriod.TEN_DAY)) {
        return new FXRiskWeight().getDeltaRiskWeight(weightingClass, config.calculationCurrency());
      } else if (r.equals(RiskClass.FX) && config.holdingPeriod().equals(HoldingPeriod.ONE_DAY)) {
        return new FXRiskWeight1d().getDeltaRiskWeight(weightingClass, config.calculationCurrency());
      } else {
        return fromRiskClass(r, config.holdingPeriod()).getDeltaRiskWeight(weightingClass);
      }
    } else if (s.equals(SensitivityClass.VEGA)) {
      if (r.equals(RiskClass.FX) && config.holdingPeriod().equals(HoldingPeriod.TEN_DAY)) {
        return new FXRiskWeight().getVegaRiskWeight(weightingClass, config.calculationCurrency());
      } else if (r.equals(RiskClass.FX) && config.holdingPeriod().equals(HoldingPeriod.ONE_DAY)) {
        return new FXRiskWeight1d().getVegaRiskWeight(weightingClass, config.calculationCurrency());
      } else {
        return fromRiskClass(r, config.holdingPeriod()).getVegaRiskWeight(weightingClass);
      }
    } else if (s.equals(SensitivityClass.CURVATURE)) {
      return BigDecimal.ONE;
    } else if (s.equals(SensitivityClass.BASECORR)) {
      return SimmRiskWeightBaseCorr.get(weightingClass, config.holdingPeriod());
    } else {
      throw new IllegalStateException("tried to get risk weight for unexpected sensitivity type: " + s + "]!");
    }
  }

  static BigDecimal getForVolWeight(SensitivityIdentifier id, SimmConfig config) {
    RiskClass r = id.getRiskIdentifier();
    if (r.equals(RiskClass.FX)) {
      String ccy1 = id.getQualifier().substring(0, 3);
      String ccy2 = id.getQualifier().substring(3, 6);
      if (config.holdingPeriod().equals(HoldingPeriod.TEN_DAY)) {
        return new FXRiskWeight().getDeltaRiskWeight(ccy1, ccy2);
      } else {
        return new FXRiskWeight1d().getDeltaRiskWeight(ccy1, ccy2);
      }
    } else {
      return fromRiskClass(r, config.holdingPeriod()).getDeltaRiskWeight(id);
    }
  }

  public static SimmRiskWeight fromRiskClass(RiskClass riskClass, HoldingPeriod period) {
    if (period.equals(HoldingPeriod.TEN_DAY)) {
      if (riskClass.equals(RiskClass.INTEREST_RATE)) {
        return new InterestRateRiskWeight();
      } else if (riskClass.equals(RiskClass.CREDIT_QUALIFYING)) {
        return new CreditQualifyingRiskWeight();
      } else if (riskClass.equals(RiskClass.CREDIT_NON_QUALIFYING)) {
        return new CreditNonQualifyingRiskWeight();
      } else if (riskClass.equals(RiskClass.EQUITY)) {
        return new EquityRiskWeight();
      } else if (riskClass.equals(RiskClass.COMMODITY)) {
        return new CommodityRiskWeight();
      } else {
        throw new IllegalStateException("tried to get a threshold for unknown risk class: [" + riskClass + "]!");
      }
    } else {
      if (riskClass.equals(RiskClass.INTEREST_RATE)) {
        return new InterestRateRiskWeight1d();
      } else if (riskClass.equals(RiskClass.CREDIT_QUALIFYING)) {
        return new CreditQualifyingRiskWeight1d();
      } else if (riskClass.equals(RiskClass.CREDIT_NON_QUALIFYING)) {
        return new CreditNonQualifyingRiskWeight1d();
      } else if (riskClass.equals(RiskClass.EQUITY)) {
        return new EquityRiskWeight1d();
      } else if (riskClass.equals(RiskClass.COMMODITY)) {
        return new CommodityRiskWeight1d();
      } else {
        throw new IllegalStateException("tried to get a threshold for unknown risk class: [" + riskClass + "]!");
      }
    }
  }

  public BigDecimal getDeltaRiskWeight(SensitivityIdentifier identifier);

  public BigDecimal getVegaRiskWeight(SensitivityIdentifier identifier);

}


text:
package jp.co.yahoo.dataplatform.mds.binary.maker;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;

import java.util.List;
import java.util.ArrayList;

import jp.co.yahoo.dataplatform.mds.compressor.FindCompressor;
import jp.co.yahoo.dataplatform.mds.compressor.ICompressor;
import jp.co.yahoo.dataplatform.mds.spread.column.ICell;
import jp.co.yahoo.dataplatform.mds.spread.column.PrimitiveCell;
import jp.co.yahoo.dataplatform.mds.spread.column.IColumn;
import jp.co.yahoo.dataplatform.mds.spread.column.ColumnType;
import jp.co.yahoo.dataplatform.mds.spread.column.PrimitiveColumn;
import jp.co.yahoo.dataplatform.mds.spread.analyzer.IColumnAnalizeResult;

import jp.co.yahoo.dataplatform.schema.objects.FloatObj;
import jp.co.yahoo.dataplatform.schema.objects.PrimitiveObject;

import jp.co.yahoo.dataplatform.mds.binary.ColumnBinary;
import jp.co.yahoo.dataplatform.mds.binary.ColumnBinaryMakerConfig;
import jp.co.yahoo.dataplatform.mds.binary.ColumnBinaryMakerCustomConfigNode;
import jp.co.yahoo.dataplatform.mds.binary.maker.index.RangeFloatIndex;
import jp.co.yahoo.dataplatform.mds.blockindex.BlockIndexNode;
import jp.co.yahoo.dataplatform.mds.blockindex.FloatRangeBlockIndex;
import jp.co.yahoo.dataplatform.mds.inmemory.IMemoryAllocator;

public class RangeDumpFloatColumnBinaryMaker extends DumpFloatColumnBinaryMaker{

  private static final int HEADER_SIZE = ( Float.BYTES * 2 ) + Integer.BYTES;

  @Override
  public ColumnBinary toBinary(final ColumnBinaryMakerConfig commonConfig , final ColumnBinaryMakerCustomConfigNode currentConfigNode , final IColumn column ) throws IOException{
    ColumnBinaryMakerConfig currentConfig = commonConfig;
    if( currentConfigNode != null ){
      currentConfig = currentConfigNode.getCurrentConfig();
    }
    byte[] parentsBinaryRaw = new byte[ ( Integer.BYTES * 2 ) + column.size() + ( column.size() * Float.BYTES ) ];
    ByteBuffer lengthBuffer = ByteBuffer.wrap( parentsBinaryRaw );
    lengthBuffer.putInt( column.size() );
    lengthBuffer.putInt( column.size() * Float.BYTES );

    ByteBuffer nullFlagBuffer = ByteBuffer.wrap( parentsBinaryRaw , Integer.BYTES * 2 , column.size() );
    FloatBuffer floatBuffer = ByteBuffer.wrap( parentsBinaryRaw , ( Integer.BYTES * 2 + column.size() ) , ( column.size() * Float.BYTES ) ).asFloatBuffer();
    int rowCount = 0;
    boolean hasNull = false;
    Float min = Float.MAX_VALUE;
    Float max = Float.MIN_VALUE;
    for( int i = 0 ; i < column.size() ; i++ ){
      ICell cell = column.get(i);
      if( cell.getType() == ColumnType.NULL ){
        nullFlagBuffer.put( (byte)1 );
        floatBuffer.put( (float)0 );
        hasNull = true;
      }
      else{
        rowCount++;
        PrimitiveCell byteCell = (PrimitiveCell) cell;
        nullFlagBuffer.put( (byte)0 );
        Float target = Float.valueOf( byteCell.getRow().getFloat() );
        floatBuffer.put( target );
        if( 0 < min.compareTo( target ) ){
          min = Float.valueOf( target );
        }
        if( max.compareTo( target ) < 0 ){
          max = Float.valueOf( target );
        }
      }
    }

    if( ! hasNull && min.equals( max ) ){
      return ConstantColumnBinaryMaker.createColumnBinary( new FloatObj( min ) , column.getColumnName() , column.size() );
    }

    byte[] binary;
    int rawLength;
    if( hasNull ){
      byte[] binaryRaw = parentsBinaryRaw;
      byte[] compressBinaryRaw = currentConfig.compressorClass.compress( binaryRaw , 0 , binaryRaw.length );
      rawLength = binaryRaw.length;

      binary = new byte[ HEADER_SIZE + compressBinaryRaw.length ];
      ByteBuffer wrapBuffer = ByteBuffer.wrap( binary );
      wrapBuffer.putFloat( min );
      wrapBuffer.putFloat( max );
      wrapBuffer.putInt( 0 );
      wrapBuffer.put( compressBinaryRaw );
    }
    else{
      rawLength = column.size() * Float.BYTES;
      byte[] compressBinaryRaw = currentConfig.compressorClass.compress( parentsBinaryRaw , ( Integer.BYTES * 2 ) + column.size() , column.size() * Float.BYTES );

      binary = new byte[ HEADER_SIZE + compressBinaryRaw.length ];
      ByteBuffer wrapBuffer = ByteBuffer.wrap( binary );
      wrapBuffer.putFloat( min );
      wrapBuffer.putFloat( max );
      wrapBuffer.putInt( 1 );
      wrapBuffer.put( compressBinaryRaw );
    }
    return new ColumnBinary( this.getClass().getName() , currentConfig.compressorClass.getClass().getName() , column.getColumnName() , ColumnType.FLOAT , rowCount , rawLength , rowCount * Float.BYTES , -1 , binary , 0 , binary.length , null );
  }

  @Override
  public int calcBinarySize( final IColumnAnalizeResult analizeResult ){
    if( analizeResult.getNullCount() == 0 && analizeResult.getUniqCount() == 1 ){
      return Float.BYTES;
    }
    else if( analizeResult.getNullCount() == 0 ){
      return analizeResult.getColumnSize() * Float.BYTES;
    }
    else{
      return super.calcBinarySize( analizeResult );
    }
  }

  @Override
  public IColumn toColumn( final ColumnBinary columnBinary ) throws IOException{
    ByteBuffer wrapBuffer = ByteBuffer.wrap( columnBinary.binary , columnBinary.binaryStart , columnBinary.binaryLength );
    Float min = Float.valueOf( wrapBuffer.getFloat() );
    Float max = Float.valueOf( wrapBuffer.getFloat() );
    int type = wrapBuffer.getInt();
    if( type == 0 ){
      return new HeaderIndexLazyColumn(
        columnBinary.columnName ,
        columnBinary.columnType ,
        new FloatColumnManager(
          columnBinary ,
          columnBinary.binaryStart + HEADER_SIZE ,
          columnBinary.binaryLength - HEADER_SIZE ) ,
          new RangeFloatIndex( min , max )
      );
    }
    else{
      return new HeaderIndexLazyColumn(
        columnBinary.columnName ,
        columnBinary.columnType ,
        new RangeFloatColumnManager(
          columnBinary ,
          columnBinary.binaryStart + HEADER_SIZE ,
          columnBinary.binaryLength - HEADER_SIZE ) ,
          new RangeFloatIndex( min , max )
      );
    }
  }

  @Override
  public void loadInMemoryStorage( final ColumnBinary columnBinary , final IMemoryAllocator allocator ) throws IOException{
    ByteBuffer wrapBuffer = ByteBuffer.wrap( columnBinary.binary , columnBinary.binaryStart , columnBinary.binaryLength );
    wrapBuffer.position( Float.BYTES * 2 );
    int type = wrapBuffer.getInt();
    if( type == 0 ){
      loadInMemoryStorage( columnBinary , columnBinary.binaryStart + HEADER_SIZE , columnBinary.binaryLength - HEADER_SIZE , allocator );
      return;
    }
    ICompressor compressor = FindCompressor.get( columnBinary.compressorClassName );
    byte[] binary = compressor.decompress( columnBinary.binary , columnBinary.binaryStart + HEADER_SIZE , columnBinary.binaryLength - HEADER_SIZE );
    wrapBuffer = wrapBuffer.wrap( binary );
    for( int i = 0 ; i < columnBinary.rowCount ; i++ ){
      allocator.setFloat( i , wrapBuffer.getFloat() );
    }
    allocator.setValueCount( columnBinary.rowCount );
  }

  @Override
  public void setBlockIndexNode( final BlockIndexNode parentNode , final ColumnBinary columnBinary , final int spreadIndex ) throws IOException{
    ByteBuffer wrapBuffer = ByteBuffer.wrap( columnBinary.binary , columnBinary.binaryStart , columnBinary.binaryLength );
    Float min = Float.valueOf( wrapBuffer.getFloat() );
    Float max = Float.valueOf( wrapBuffer.getFloat() );
    BlockIndexNode currentNode = parentNode.getChildNode( columnBinary.columnName );
    currentNode.setBlockIndex( new FloatRangeBlockIndex( min , max ) );
  }

  public class RangeFloatDicManager implements IDicManager{

    private final FloatBuffer dicBuffer;
    private final int dicLength;

    public RangeFloatDicManager( final FloatBuffer dicBuffer ){
      this.dicBuffer = dicBuffer;
      dicLength = dicBuffer.capacity();
    }

    @Override
    public PrimitiveObject get( final int index ) throws IOException{
      return new FloatObj( dicBuffer.get( index ) );
    }

    @Override
    public int getDicSize() throws IOException{
      return dicLength;
    }

  }

  public class RangeFloatColumnManager implements IColumnManager{

    private final ColumnBinary columnBinary;
    private final int binaryStart;
    private final int binaryLength;
    private PrimitiveColumn column;
    private boolean isCreate;

    public RangeFloatColumnManager( final ColumnBinary columnBinary , final int binaryStart , final int binaryLength ) throws IOException{
      this.columnBinary = columnBinary;
      this.binaryStart = binaryStart;
      this.binaryLength = binaryLength;
    }

    private void create() throws IOException{
      if( isCreate ){
        return;
      }
      ICompressor compressor = FindCompressor.get( columnBinary.compressorClassName );
      byte[] binary = compressor.decompress( columnBinary.binary , binaryStart , binaryLength );

      column = new PrimitiveColumn( columnBinary.columnType , columnBinary.columnName );
      IDicManager dicManager = new RangeFloatDicManager( ByteBuffer.wrap( binary ).asFloatBuffer() );
      column.setCellManager( new BufferDirectCellManager( columnBinary.columnType , dicManager , columnBinary.rowCount ) );

      isCreate = true;
    }

    @Override
    public IColumn get(){
      try{
        create();
      }catch( IOException e ){
        throw new UncheckedIOException( e );
      }
      return column;
    }

    @Override
    public List<String> getColumnKeys(){
      return new ArrayList<String>();
    }

    @Override
    public int getColumnSize(){
      return 0;
    }

  }

}


text:
"""
Created on Fri Feb 17 12:04:09 2017

@author: jrb
"""
def justify(strings, L):
    res = []
    if len(strings) == 1:
        rest = L - sum([len(w) for w in strings[0]])
        res.append(' '.join(strings[0])+' ')
    else:
        for s in strings:
            rest = L - sum([len(w) for w in s])
            while rest > 0:
                if len(s) > 1:
                    for i in range(len(s)-1):
                        if rest > 0:
                            s[i] = s[i]+' '
                            rest -= 1
                        else:
                            break
                else:
                    s[0] += ' '*rest
                    rest = 0
            res.append(''.join(s))
    return res

def textJustification(words, L):
    """
    https://codefights.com/interview/ibANT8ZGc3shACBRF/description
    Given an array of words and a length L, format the text such that each
    line has exactly L characters and is fully justified on both the left and
    the right. Words should be packed in a greedy approach; that is, pack as
    many words as possible in each line. Add extra spaces when necessary so
    that each line has exactly L characters.

    Extra spaces between words should be distributed as evenly as possible. If
    the number of spaces on a line does not divide evenly between words, the
    empty slots on the left will be assigned more spaces than the slots on the
    right. For the last line of text and lines with one word only, the words
    should be left justified with no extra space inserted between them.

    Example
        For words = ["This", "is", "an", "example", "of", "text", "justification."]
        and L = 16, the output should be

        textJustification(words, L) = ["This    is    an",
                                       "example  of text",
                                       "justification.  "]

        >>> words = ["This", "is", "an", "example", "of", "text", "justification."]
        >>> L = 16
        >>> textJustification(words, L)
        ["This    is    an", "example  of text", "justification.  "]

        >>> words = ["Two", "words."]
        >>> L = 10
        >>> textJustification(words, L)
        ["Two words."]
    """

    res = []
    while words != []:
        s = []
        while len(s)+sum([len(w) for w in s])+len(words[0]) <= L:
            s.append(words[0])
            words = words[1:]
            if words == []:
                break
        res.append(s)
    print(res)
    return justify(res, L)

if __name__ == "__main__":
    words = ["Two", "words."]
    L = 10
    textJustification(words, L)

#    import doctest
#    doctest.testmod()


text:
/* Pay close attention to this Class, it demonstrates almost all of what
 * you'll need to program. Also take a good look at the DataStore and FallSensorRecord
 * code. There are a few different calls you can make to the DataStore, if in doubt
 * just use the getRecord call to get the direct handle to the FallSensorRecord.
 * The other methods are for convenience but are NOT necessary.
 *
 * The values for the various states (like CasualMessage.STATE_RUNNING) are defined
 * inside of the handlers for the various message types, e.g. that one was defined
 * in the CasualMessage class, which is the handler for the messages of type
 * "Casual Message". Take a poke around that to see if you need anything in there,
 * also look at some of the other message handlers to see if you need anything they
 * define.
 *
 * Due to problems arising from half-implemented features, we're no longer extending
 * the Agent class (in fact I've removed it). This means you need to directly specify
 * that you're implementing the Observer interface.
 *
 * It's best if there is only one agent of each type running at any one time.
 * (SINGLETON PATTERN ALERT! SINGLETON PATTERN ALERT!)
 *
 * For this reason I've made the constructor of this agent private, which means
 * you can't call "new HughsMagicalDemoAgent()", you've to ask it to start itself.
 *
 * Don't forget to add your agent to the BootStrap class, or else it will never run!
 *
 * P.S. The FallSensorRecords only alert you if the value they have stored CHANGES.
 * Unfortunately the default value for each empty FSR is zero, and the Enumerated values
 * for the status message includes 0 (for 'Running'). This means that if you observe
 * the status record, and send a message saying that you're running, your update() won't fire.
 * Send a message that you're doing anything else, then send a running message to workaround this.
 */

package fallHandler.agent;

import fallHandler.datastore.CasualMessage;
import fallHandler.datastore.DataStore;
import fallHandler.datastore.FallSensorRecord;
import fallHandler.datastore.Observable;
import fallHandler.datastore.Records;
import fallHandler.datastore.Observable.Observer;

public class HughsMagicalDemoAgent implements Observer {

	int oldState = 0;
	static HughsMagicalDemoAgent instance = null;

	public static HughsMagicalDemoAgent startAgent() {

		if (instance == null) {
			instance = new HughsMagicalDemoAgent();
		}

		return instance;

	}

	/* The constructor is as good a place as any to register on observerables.
	 * Let's keep things simple by always dealing with sensor '0'. You can write
	 * code for more sensors if you'd like, but wouldn't you rather be outside? */
	private HughsMagicalDemoAgent() {
                System.out.println(this.toString() + "started\n");
		DataStore.getRecord("0" + Records.prependsrc.mobility.state).addObserver(this);
	}

	/* update is what the observables call when they've changed */
	public void update(Observable updatedObject) {
		System.out.println("\n\n\t\t******\n\t\tHughsMagicalDemoAgent Called!");

		/* Remember that update gives us an Observable object, which is not
		 * necessarily a FallSensorRecord. So we have to test if it is before we
		 * can treat it like it is.
		 */
		if (updatedObject instanceof FallSensorRecord) {
			FallSensorRecord updatedRecord = (FallSensorRecord)updatedObject;

			System.out.println("\t\tRecord Details:\n" +
					"\t\tName: " + updatedRecord.getName() +
					"\n\t\tValue: " + updatedRecord.getVal() + "\n"
					);

			/* This is a state machine right here. No, really, it is. */

			int currentState = updatedRecord.getVal();

			if (oldState == CasualMessage.STATE_RUNNING && currentState == CasualMessage.STATE_LYING) {
				System.out.println("\t\tFALL FALL FALL");
				DataStore.getRecord("0" + Records.prependsrc.status.falldetected).setVal(1);
			}

				oldState = currentState;

			System.out.println("\n\t\t******\n");

		}
	}

}