text:
package com.cloud.network.element;

import com.cloud.agent.api.to.FirewallRuleTO;
import com.cloud.agent.api.to.PortForwardingRuleTO;
import com.cloud.configuration.Config;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.IpAddress;
import com.cloud.network.Network;
import com.cloud.network.Network.Capability;
import com.cloud.network.Network.Provider;
import com.cloud.network.Network.Service;
import com.cloud.network.NetworkModel;
import com.cloud.network.Networks;
import com.cloud.network.PhysicalNetworkServiceProvider;
import com.cloud.network.PublicIpAddress;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.PortForwardingRule;
import com.cloud.network.rules.StaticNat;
import com.cloud.network.vpc.VpcManager;
import com.cloud.offering.NetworkOffering;
import com.cloud.user.AccountManager;
import com.cloud.utils.Pair;
import com.cloud.utils.component.AdapterBase;
import com.cloud.utils.component.PluggableService;
import com.cloud.utils.net.NetUtils;
import com.cloud.user.AccountVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.vm.NicProfile;
import com.cloud.vm.NicVO;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.NicDao;
import org.midonet.client.MidonetApi;
import org.midonet.client.exception.HttpInternalServerError;
import org.midonet.client.dto.DtoRule;
import org.midonet.client.dto.DtoRule.DtoRange;
import org.midonet.client.resource.Bridge;
import org.midonet.client.resource.BridgePort;
import org.midonet.client.resource.DhcpHost;
import org.midonet.client.resource.DhcpSubnet;
import org.midonet.client.resource.Port;
import org.midonet.client.resource.ResourceCollection;
import org.midonet.client.resource.Route;
import org.midonet.client.resource.Router;
import org.midonet.client.resource.RouterPort;
import org.midonet.client.resource.Rule;
import org.midonet.client.resource.RuleChain;
import com.sun.jersey.core.util.MultivaluedMapImpl;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import javax.ws.rs.core.MultivaluedMap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

@Component
@Local(value = {NetworkElement.class,
                ConnectivityProvider.class,
                FirewallServiceProvider.class,
                SourceNatServiceProvider.class,
                DhcpServiceProvider.class,
                StaticNatServiceProvider.class,
                PortForwardingServiceProvider.class,
                IpDeployer.class} )
public class MidoNetElement extends AdapterBase implements
                                        ConnectivityProvider,
                                        DhcpServiceProvider,
                                        SourceNatServiceProvider,
                                        StaticNatServiceProvider,
                                        IpDeployer,
                                        PortForwardingServiceProvider,
                                        FirewallServiceProvider,
                                        PluggableService {

    private static final Logger s_logger = Logger.getLogger(MidoNetElement.class);

    private static final Map<Service, Map<Capability, String>> capabilities = setCapabilities();

    protected UUID _providerRouterId = null;

    protected MidonetApi api;

    private static final Provider MidoNet = new Provider("MidoNet", false);

    public enum RuleChainCode {
        TR_PRE,
        TR_PRENAT,
        TR_PREFILTER,
        TR_POST,
        ACL_INGRESS,
        ACL_EGRESS
    }

    @Inject
    ConfigurationDao _configDao;
    @Inject
    protected NicDao _nicDao;
    @Inject
    NetworkModel _networkModel;
    @Inject
    VpcManager _vpcMgr;
    @Inject
    AccountManager _accountMgr;
    @Inject
    AccountDao _accountDao;

    public void setMidonetApi(MidonetApi api) {
        this.api = api;
    }

    public void setAccountDao(AccountDao aDao) {
        this._accountDao = aDao;
    }

    @Override
    public Map<Service, Map<Capability, String>> getCapabilities() {
        return capabilities;
    }

    @Override
    public boolean configure(String name, Map<String, Object> params)
            throws ConfigurationException {
        super.configure(name, params);

        String routerIdValue = (String) _configDao.getValue(Config.MidoNetProviderRouterId.key());
        if(routerIdValue != null)
            _providerRouterId = UUID.fromString(routerIdValue);

        String value = (String) _configDao.getValue(Config.MidoNetAPIServerAddress.key());

        if (value == null) {
            throw new ConfigurationException(
                "Could not find midonet API location in config");
        }

        if (this.api == null) {
            s_logger.info("midonet API server address is  " + value);
            setMidonetApi(new MidonetApi(value));
            this.api.enableLogging();
        }

        return true;
    }

    public boolean midoInNetwork(Network network) {
        if((network.getTrafficType() == Networks.TrafficType.Public) &&
           (network.getBroadcastDomainType() == Networks.BroadcastDomainType.Mido)){
            return true;
        }
        if((network.getTrafficType() == Networks.TrafficType.Guest) &&
           (network.getBroadcastDomainType() == Networks.BroadcastDomainType.Mido)){
            return true;
        }
        return false;
    }

    protected boolean canHandle(Network network, Service service) {
        Long physicalNetworkId = _networkModel.getPhysicalNetworkId(network);
        if (physicalNetworkId == null) {
            return false;
        }

        if (!_networkModel.isProviderEnabledInPhysicalNetwork(physicalNetworkId, getProvider().getName())) {
            return false;
        }

        if (service == null) {
            if (!_networkModel.isProviderForNetwork(getProvider(), network.getId())) {
                s_logger.trace("Element " + getProvider().getName() + " is not a provider for the network " + network);
                return false;
            }
        } else {
            if (!_networkModel.isProviderSupportServiceInNetwork(network.getId(), service, getProvider())) {
                s_logger.trace("Element " + getProvider().getName() + " doesn't support service " + service.getName()
                        + " in the network " + network);
                return false;
            }
        }

        return true;
    }

    public void applySourceNat(Router tenantRouter, Router providerRouter,
                               RouterPort tenantUplink, RouterPort providerDownlink,
                               RuleChain pre, RuleChain post, PublicIpAddress addr) {

        boolean needAdd = true;
        String SNtag = "/SourceNat";
        String SNkey = "CS_nat";

        String snatIp = addr.getAddress().addr();

        String CsDesc = snatIp + SNtag;

        //determine, by use of the properties, if we already
        //added this rule. If we did, then we can skip it
        //by setting needAdd = false
        for (Rule rule : pre.getRules()) {
            Map<String, String> props = rule.getProperties();
            if (props == null) {
                continue;
            }
            String snatTag = props.get(SNkey);
            if (snatTag == null) {
                continue;
            }

            if (!snatTag.equals(CsDesc)) {
                continue;
            } else {
                needAdd = false;
                break;
            }
        }

        if (needAdd == false) {
            //we found that this rule exists already,
            // so lets skip adding it
            return;
        }

        Map<String, String> ruleProps = new HashMap<String, String>();
        ruleProps.put(SNkey, CsDesc);

        DtoRule.DtoNatTarget[] targets = new DtoRule.DtoNatTarget[]{
            new DtoRule.DtoNatTarget(snatIp,
                    snatIp, 1, 65535)};

        // Set inbound (reverse SNAT) rule
        pre.addRule().type(DtoRule.RevSNAT).flowAction(DtoRule.Accept)
            .nwDstAddress(snatIp).nwDstLength(32)
            .inPorts(new UUID[] {tenantUplink.getId()}).position(1)
            .properties(ruleProps).create();

        // Set outbound (SNAT) rule
        post.addRule().type(DtoRule.SNAT).flowAction(DtoRule.Accept)
            .outPorts(new UUID[]{tenantUplink.getId()})
            .natTargets(targets).position(1)
            .properties(ruleProps).create();

        // Set up default route from tenant router to provider router
        tenantRouter.addRoute().type("Normal").weight(100)
            .srcNetworkAddr("0.0.0.0").srcNetworkLength(0)
            .dstNetworkAddr("0.0.0.0").dstNetworkLength(0)
            .nextHopPort(tenantUplink.getId()).create();

        // Set routes for traffic to the SNAT IP to come back from provider router
        providerRouter.addRoute().type("Normal").weight(100)
            .srcNetworkAddr("0.0.0.0").srcNetworkLength(0)
            .dstNetworkAddr(snatIp).dstNetworkLength(32)
            .nextHopPort(providerDownlink.getId()).create();

        // Default rule to accept traffic that has been DNATed
        post.addRule().type(DtoRule.RevDNAT).flowAction(DtoRule.Accept).create();
    }

    public String getAccountUuid(Network network) {
        AccountVO acc = _accountDao.findById(network.getAccountId());
        return acc.getUuid();
    }

    public boolean associatePublicIP(Network network, final List<? extends PublicIpAddress> ipAddress)
        throws ResourceUnavailableException {

        s_logger.debug("associatePublicIP called with network: " + network.toString());
        /*
         * Get Mido Router for this network and set source rules
         * These should only be allocated inside the for loop, because
         * this function could be called as a part of network cleanup. In
         * that case, we do not want to recreate the guest network or
         * any ports.
         */
        boolean resources = false;
        Router tenantRouter = null;
        Router providerRouter = null;
        RouterPort[] ports = null;

        RouterPort tenantUplink = null;
        RouterPort providerDownlink = null;

        RuleChain preNat = null;
        RuleChain post = null;
        String accountIdStr = null;
        String routerName = null;

        // Set Source NAT rules on router
        for (PublicIpAddress ip : ipAddress) {
            // ip is the external one we sourcenat to
            if(ip.isSourceNat()){
                if (resources == false) {
                    tenantRouter = getOrCreateGuestNetworkRouter(network);
                    providerRouter = api.getRouter(_providerRouterId);
                    ports = getOrCreateProviderRouterPorts(tenantRouter, providerRouter);

                    tenantUplink = ports[0];
                    providerDownlink = ports[1];

                    accountIdStr = getAccountUuid(network);
                    boolean isVpc = getIsVpc(network);
                    long id = getRouterId(network, isVpc);
                    routerName = getRouterName(isVpc, id);

                    preNat = getChain(accountIdStr, routerName, RuleChainCode.TR_PRENAT);
                    post = api.getChain(tenantRouter.getOutboundFilterId());
                    resources = true;
                }

                applySourceNat(tenantRouter, providerRouter,    // Routers
                               tenantUplink, providerDownlink,  // Ports
                               preNat, post,                       // Chains
                               ip);                             // The IP
            }
        }

        return true;
    }

    /**
     * From interface IpDeployer
     *
     * @param network
     * @param ipAddress
     * @param services
     * @return
     * @throws ResourceUnavailableException
     */
    @Override
    public boolean applyIps(Network network,
                            List<? extends PublicIpAddress> ipAddress, Set<Service> services)
            throws ResourceUnavailableException {

        s_logger.debug("applyIps called with network: " + network.toString());
        if (!this.midoInNetwork(network)) {
            return false;
        }

        boolean canHandle = true;
        for (Service service : services) {
            if (!canHandle(network, service)) {
                canHandle = false;
                break;
            }
        }
        if(canHandle) {
            return associatePublicIP(network, ipAddress);
        } else {
            return false;
        }
    }

    /**
     * From interface SourceNatServiceProvider
     */
    @Override
    public IpDeployer getIpDeployer(Network network) {
        s_logger.debug("getIpDeployer called with network " + network.toString());
        return this;
    }

    /**
     * From interface DHCPServiceProvider
     */
    @Override
    public boolean addDhcpEntry(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm,
                                DeployDestination dest, ReservationContext context)
        throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {

        s_logger.debug("addDhcpEntry called with network: " + network.toString() + " nic: " + nic.toString() + " vm: " + vm.toString());
        if (!this.midoInNetwork(network)) {
            return false;
        }
        if (vm.getType() != VirtualMachine.Type.User) {
            return false;
        }

        // Get MidoNet bridge
        Bridge netBridge = getOrCreateNetworkBridge(network);

        // On bridge, get DHCP subnet (ensure it exists)
        ResourceCollection res = netBridge.getDhcpSubnets();

        DhcpSubnet sub = null;

        if(!res.isEmpty()){
            sub = (DhcpSubnet) res.get(0);
        } else {
            Pair<String,Integer> cidrInfo = NetUtils.getCidr(network.getCidr());
            sub = netBridge.addDhcpSubnet();

            sub.subnetLength(cidrInfo.second());
            sub.subnetPrefix(cidrInfo.first());
            sub.defaultGateway(network.getGateway());
            List<String> dcs = new ArrayList<String>();
            dcs.add(dest.getDataCenter().getDns1());
            sub.dnsServerAddrs(dcs);

            sub.create();
        }

        // On DHCP subnet, add host using host details
        if(sub == null){
            s_logger.error("Failed to create DHCP subnet on Midonet bridge");
            return false;
        } else {
            // Check if the host already exists - we may just be restarting an existing VM
            boolean isNewDhcpHost = true;

            for (DhcpHost dhcpHost : sub.getDhcpHosts()) {
                if(dhcpHost.getIpAddr().equals(nic.getIp4Address())){
                    isNewDhcpHost = false;
                    break;
                }
            }

            if(isNewDhcpHost){
                DhcpHost host = sub.addDhcpHost();
                host.ipAddr(nic.getIp4Address());
                host.macAddr(nic.getMacAddress());
                // This only sets the cloudstack internal name
                host.name(vm.getHostName());

                host.create();
            }
        }

        return true;
    }

    @Override
    public boolean configDhcpSupportForSubnet(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
        return false;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public boolean removeDhcpSupportForSubnet(Network network) {
        return false;  //To change body of implemented methods use File | Settings | File Templates.
    }

    private void removeMidonetStaticNAT(RuleChain preFilter, RuleChain preNat, RuleChain postNat,
                                        String floatingIp, String fixedIp,
                                        Router providerRouter) {

        // Delete filter (firewall) rules for this IP
        for (Rule rule : preFilter.getRules()) {
            String destAddr = rule.getNwDstAddress();
            if (destAddr != null && destAddr.equals(floatingIp)) {
                rule.delete();
            }
        }

        // Delete DNAT rules for this IP
        for (Rule rule : preNat.getRules()) {
            String destAddr = rule.getNwDstAddress();
            if (destAddr != null && destAddr.equals(floatingIp)) {
                rule.delete();
            }
        }
        // Delete SNAT rules for this IP
        for (Rule rule : postNat.getRules()) {
            String srcAddr = rule.getNwSrcAddress();
            if (srcAddr != null && srcAddr.equals(fixedIp)) {
                rule.delete();
            }
        }

        //we also created a route to go with this rule. That needs to be
        //deleted as well.
        for (Route route : providerRouter.getRoutes(new MultivaluedMapImpl())) {
            String routeDstAddr = route.getDstNetworkAddr();
            if (routeDstAddr != null && routeDstAddr.equals(floatingIp)) {
                route.delete();
            }
        }
    }

    private void addMidonetStaticNAT(RuleChain preFilter, RuleChain preNat, RuleChain postNat,
                                     String floatingIp, String fixedIp,
                                     RouterPort tenantUplink,
                                     RouterPort providerDownlink,
                                     Router providerRouter,
                                     Network network) {

        DtoRule.DtoNatTarget[] preTargets = new DtoRule.DtoNatTarget[]{
            new DtoRule.DtoNatTarget(fixedIp, fixedIp, 0, 0)};

        // Set inbound filter rule (allow return traffic to this IP)
        //     Implemented as "jump to NAT chain" instead of ACCEPT;
        //     this is to enforce that filter / firewall rules are evaluated
        //     before NAT rules.
        preFilter.addRule().type(DtoRule.Jump)
                .jumpChainId(preNat.getId())
                .nwDstAddress(floatingIp)
                .nwDstLength(32)
                .matchReturnFlow(true)
                .position(1)
                .create();

        // Allow ICMP replies (ICMP type 0, code 0 is ICMP reply)
        preFilter.addRule().type(DtoRule.Jump)
                .jumpChainId(preNat.getId())
                .nwDstAddress(floatingIp)
                .nwDstLength(32)
                .nwProto(SimpleFirewallRule.stringToProtocolNumber("icmp"))
                .tpSrc(new DtoRange<Integer>(0,0))
                .tpDst(new DtoRange<Integer>(0,0))
                .position(2)
                .create();

        // We only want to set the default DROP rule for static NAT if
        // Firewall is handled by the Midonet plugin.
        // Set inbound filter rule (drop all traffic to this IP)
        if (canHandle(network, Service.Firewall)) {
            preFilter.addRule().type(DtoRule.Drop)
                .nwDstAddress(floatingIp)
                .nwDstLength(32)
                .position(3)
                .create();
        }

        // Set inbound (DNAT) rule
        preNat.addRule().type(DtoRule.DNAT)
            .flowAction(DtoRule.Accept)
            .nwDstAddress(floatingIp)
            .nwDstLength(32)
            .inPorts(new UUID[] {tenantUplink.getId()})
            .natTargets(preTargets)
            .position(1)
            .create();

        DtoRule.DtoNatTarget[] postTargets = new DtoRule.DtoNatTarget[]{
            new DtoRule.DtoNatTarget(floatingIp, floatingIp, 0, 0)};

        // Set outbound (SNAT) rule
        //    Match forward flow so that return traffic will be recognized
        postNat.addRule().type(DtoRule.SNAT)
            .flowAction(DtoRule.Accept)
            .matchForwardFlow(true)
            .nwSrcAddress(fixedIp)
            .nwSrcLength(32)
            .outPorts(new UUID[]{tenantUplink.getId()})
            .natTargets(postTargets)
            .position(1)
            .create();

        // Set outbound (SNAT) rule
        //    Match return flow to also allow out traffic which was marked as forward flow on way in
        postNat.addRule().type(DtoRule.SNAT)
            .flowAction(DtoRule.Accept)
            .matchReturnFlow(true)
            .nwSrcAddress(fixedIp)
            .nwSrcLength(32)
            .outPorts(new UUID[]{tenantUplink.getId()})
            .natTargets(postTargets)
            .position(2)
            .create();

        // Set routes for traffic to the SNAT IP to come back from provider router
        providerRouter.addRoute().type("Normal").weight(100)
            .srcNetworkAddr("0.0.0.0").srcNetworkLength(0)
            .dstNetworkAddr(floatingIp).dstNetworkLength(32)
            .nextHopPort(providerDownlink.getId()).create();
    }

    /**
     * From interface StaticNatServiceProvider
     */
    @Override
    public boolean applyStaticNats(Network network,
                                   List<? extends StaticNat> rules)
            throws ResourceUnavailableException {
        s_logger.debug("applyStaticNats called with network: " + network.toString());
        if (!midoInNetwork(network)) {
            return false;
        }
        if (!canHandle(network, Service.StaticNat)) {
            return false;
        }

        boolean resources = false;
        Router tenantRouter = null;
        Router providerRouter = null;

        RouterPort[] ports = null;

        RouterPort tenantUplink = null;
        RouterPort providerDownlink = null;

        RuleChain preFilter = null;
        RuleChain preNat = null;
        RuleChain post = null;

        String accountIdStr = getAccountUuid(network);
        String networkUUIDStr = String.valueOf(network.getId());

        for (StaticNat rule : rules) {
            IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
            String sourceIpAddr = sourceIp.getAddress().addr();

            if (resources == false) {
                tenantRouter = getOrCreateGuestNetworkRouter(network);
                providerRouter = api.getRouter(_providerRouterId);

                ports = getOrCreateProviderRouterPorts(tenantRouter, providerRouter);

                tenantUplink = ports[0];
                providerDownlink = ports[1];

                boolean isVpc = getIsVpc(network);
                long id = getRouterId(network, isVpc);
                String routerName = getRouterName(isVpc, id);

                preFilter = getChain(accountIdStr, routerName, RuleChainCode.TR_PREFILTER);
                preNat = getChain(accountIdStr, routerName, RuleChainCode.TR_PRENAT);
                post = api.getChain(tenantRouter.getOutboundFilterId());
                resources = true;
            }

            if (rule.isForRevoke()) {
                removeMidonetStaticNAT(preFilter, preNat, post,
                                       sourceIpAddr, rule.getDestIpAddress(),
                                       providerRouter);
            } else {
                addMidonetStaticNAT(preFilter, preNat, post,
                                    sourceIpAddr, rule.getDestIpAddress(),
                                    tenantUplink, providerDownlink,
                                    providerRouter,
                                    network);
            }
        }

        return true;
    }

    @Override
    public boolean applyFWRules(Network config, List<? extends FirewallRule> rulesToApply) throws ResourceUnavailableException {
        if (!midoInNetwork(config)) {
            return false;
        }
        if (canHandle(config, Service.Firewall)) {
            String accountIdStr = getAccountUuid(config);
            String networkUUIDStr = String.valueOf(config.getId());
            RuleChain preFilter = getChain(accountIdStr, networkUUIDStr, RuleChainCode.TR_PREFILTER);
            RuleChain preNat = getChain(accountIdStr, networkUUIDStr, RuleChainCode.TR_PRENAT);

            // Create a map of Rule description -> Rule for quicker lookups
            Map<String, Rule> existingRules = new HashMap<String, Rule>();

            for (Rule existingRule : preFilter.getRules()) {
                // The "whitelist" rules we're interested in are the Jump rules where src address is specified
                if(existingRule.getType().equals(DtoRule.Jump) && existingRule.getNwSrcAddress() != null){
                    String ruleString = new SimpleFirewallRule(existingRule).toStringArray()[0];
                    existingRules.put(ruleString, existingRule);
                }
            }

            for (FirewallRule rule : rulesToApply) {
                if (rule.getState() == FirewallRule.State.Revoke || rule.getState() == FirewallRule.State.Add) {
                    IpAddress dstIp = _networkModel.getIp(rule.getSourceIpAddressId());
                    FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, dstIp.getAddress().addr());

                    // Convert to string representation
                    SimpleFirewallRule fwRule = new SimpleFirewallRule(ruleTO);
                    String[] ruleStrings = fwRule.toStringArray();

                    if (rule.getState() == FirewallRule.State.Revoke) {
                        // Lookup in existingRules, delete if present
                        for(String revokeRuleString : ruleStrings){
                            Rule foundRule = existingRules.get(revokeRuleString);
                            if(foundRule != null){
                                foundRule.delete();
                            }
                        }
                    } else if (rule.getState() == FirewallRule.State.Add) {
                        // Lookup in existingRules, add if not present
                        for(int i = 0; i < ruleStrings.length; i++){
                            String ruleString = ruleStrings[i];
                            Rule foundRule = existingRules.get(ruleString);
                            if(foundRule == null){
                                // Get the cidr for the related entry in the Source Cidrs list
                                String relatedCidr = fwRule.sourceCidrs.get(i);
                                Pair<String,Integer> cidrParts = NetUtils.getCidr(relatedCidr);

                                // Create rule with correct proto, cidr, ACCEPT, dst IP
                                Rule toApply = preFilter.addRule()
                                        .type(DtoRule.Jump)
                                        .jumpChainId(preNat.getId())
                                        .position(1)
                                        .nwSrcAddress(cidrParts.first())
                                        .nwSrcLength(cidrParts.second())
                                        .nwDstAddress(ruleTO.getSrcIp())
                                        .nwDstLength(32)
                                        .nwProto(SimpleFirewallRule.stringToProtocolNumber(rule.getProtocol()));

                                if(rule.getProtocol().equals("icmp")){
                                    // ICMP rules - reuse port fields
                                    // (-1, -1) means "allow all ICMP", so we don't set tpSrc / tpDst
                                    if(fwRule.icmpType != -1 | fwRule.icmpCode != -1){
                                        toApply.tpSrc(new DtoRange(fwRule.icmpType, fwRule.icmpType))
                                            .tpDst(new DtoRange(fwRule.icmpCode, fwRule.icmpCode));
                                    }
                                } else {
                                    toApply.tpDst(new DtoRange(fwRule.dstPortStart, fwRule.dstPortEnd));
                                }

                                toApply.create();
                            }
                        }
                    }
                }
            }
            return true;
        } else {
            return true;
        }
    }

    @Override
    public Provider getProvider() {
        return MidoNet;
    }

    @Override
    public boolean implement(Network network, NetworkOffering offering, DeployDestination dest,
                             ReservationContext context)
            throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
        s_logger.debug("implement called with network: " + network.toString());
        if (!midoInNetwork(network)) {
            return false;
        }

        if(network.getTrafficType() == Networks.TrafficType.Guest){
            // Create the Midonet bridge for this network
            Bridge netBridge = getOrCreateNetworkBridge(network);
            Router tenantRouter = getOrCreateGuestNetworkRouter(network);

            // connect router and bridge
            ensureBridgeConnectedToRouter(network, netBridge, tenantRouter);
        }

        return true;
    }

    @Override
    public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm,
                           DeployDestination dest, ReservationContext context)
            throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
        s_logger.debug("prepare called with network: " + network.toString() + " nic: " + nic.toString() + " vm: " + vm.toString());
        if (!midoInNetwork(network)) {
            return false;
        }

        if (nic.getTrafficType() == Networks.TrafficType.Guest &&
            !canHandle(network, Service.StaticNat)) {
            return false;
        }

        if (nic.getTrafficType() == Networks.TrafficType.Guest ||
                nic.getTrafficType() == Networks.TrafficType.Public &&
                nic.getBroadcastType() == Networks.BroadcastDomainType.Mido){
            Bridge netBridge = getOrCreateNetworkBridge(network);
            if(nic.getTrafficType() == Networks.TrafficType.Public &&
                vm.getVirtualMachine().getType() != VirtualMachine.Type.DomainRouter){
                // Get provider router
                Router providerRouter = api.getRouter(_providerRouterId);

                Port[] ports = getOrCreatePublicBridgePorts(nic, netBridge, providerRouter);

                RouterPort providerDownlink = (RouterPort) ports[1];

                // Set route from router to bridge for this particular IP. Prepare
                // is called in both starting a new VM and restarting a VM, so the
                // NIC may
                boolean routeExists = false;
                for (Route route : providerRouter.getRoutes(new MultivaluedMapImpl())) {
                    String ip4 = route.getDstNetworkAddr();
                    if (ip4 != null && ip4.equals(nic.getIp4Address())) {
                        routeExists = true;
                        break;
                    }
                }

                if (!routeExists) {
                    providerRouter.addRoute()
                                  .type("Normal")
                                  .weight(100)
                                  .srcNetworkAddr("0.0.0.0")
                                  .srcNetworkLength(0)
                                  .dstNetworkAddr(nic.getIp4Address())
                                  .dstNetworkLength(32)
                                  .nextHopPort(providerDownlink.getId())
                                  .nextHopGateway(null)
                                  .create();
                }
            }

            // Add port on bridge
            BridgePort newPort = netBridge.addExteriorPort().create(); // returns wrapper resource of port

            // Set MidoNet port VIF ID to UUID of nic
            UUID nicUUID = getNicUUID(nic);
            newPort.vifId(nicUUID).update();
        }

        return true;
    }

    @Override
    public boolean release(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm,
                           ReservationContext context)
            throws ConcurrentOperationException, ResourceUnavailableException {
        s_logger.debug("release called with network: " + network.toString() + " nic: " + nic.toString() + " vm: " + vm.toString());
        if (!midoInNetwork(network)) {
            return false;
        }

        UUID nicUUID = getNicUUID(nic);
        if(nic.getTrafficType() == Networks.TrafficType.Guest ||
                (nic.getTrafficType() == Networks.TrafficType.Public &&
                nic.getBroadcastType() == Networks.BroadcastDomainType.Mido)) {
            // Seems like a good place to remove the port in midonet
            Bridge netBridge = getOrCreateNetworkBridge(network);

            Router providerRouter = api.getRouter(_providerRouterId);

            //remove the routes associated with this IP address
            for (Route route : providerRouter.getRoutes(new MultivaluedMapImpl())) {
                String routeDstAddr = route.getDstNetworkAddr();
                if (routeDstAddr != null && routeDstAddr.equals(nic.getIp4Address())) {
                    route.delete();
                }
            }

            for (BridgePort p : netBridge.getPorts()) {
                UUID vifID = p.getVifId();
                if(vifID != null && vifID.equals(nicUUID)){
                    // This is the MidoNet port which corresponds to the NIC we are releasing

                    // Set VIF ID to null
                    p.vifId(null).update();

                    // Delete port
                    p.delete();
                }
            }
        }

        return true;
    }

    @Override
    public boolean shutdown(Network network, ReservationContext context, boolean cleanup)
            throws ConcurrentOperationException, ResourceUnavailableException {
        s_logger.debug("shutdown called with network: " + network.toString());
        if (!midoInNetwork(network)) {
            return false;
        }

        // Find Mido API server, remove ports from this network's bridge, remove bridge itself
        deleteNetworkBridges(network);
        if (network.getVpcId() == null) {
            deleteGuestNetworkRouters(network);
        }

        return true;
    }

    @Override
    public boolean destroy(Network network, ReservationContext context)
            throws ConcurrentOperationException, ResourceUnavailableException {
        s_logger.debug("destroy called with network: " + network.toString());
        if (!midoInNetwork(network)) {
            return false;
        }

        deleteNetworkBridges(network);
        // if This is part of a VPC, then we do not want to delete the router.
        // we only delete the router when the VPC is destroyed
        if (network.getVpcId() == null) {
            deleteGuestNetworkRouters(network);
        }

        return true;
    }

    @Override
    public boolean isReady(PhysicalNetworkServiceProvider provider) {
        // We are always ready.
        return true;
    }

    @Override
    public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context)
            throws ConcurrentOperationException, ResourceUnavailableException {
        // Nothing to do here because the cleanup of the networks themselves clean up the resources.
        return true;
    }

    @Override
    public boolean canEnableIndividualServices() {
        // We can enable individual services, though this is still subject to
        // "VerifyServicesCombination
        return true;
    }

    @Override
    public boolean verifyServicesCombination(Set<Service> services) {
        if (services.contains(Service.Vpn) ||
            services.contains(Service.Dns) ||
            services.contains(Service.Lb) ||
            services.contains(Service.UserData) ||
            services.contains(Service.SecurityGroup) ||
            services.contains(Service.NetworkACL)) {
                // We don't implement any of these services, and we don't
                // want anyone else to do it for us. So if these services
                // exist, we can't handle it.
                return false;
        }
        return true;
    }

    @Override
    public boolean applyPFRules(Network network, List<PortForwardingRule> rules)
                    throws ResourceUnavailableException {
        s_logger.debug("applyPFRules called with network " + network.toString());
        if (!midoInNetwork(network)) {
            return false;
        }
        if (!canHandle(network, Service.PortForwarding)) {
            return false;
        }

        String accountIdStr = getAccountUuid(network);
        String networkUUIDStr = String.valueOf(network.getId());
        RuleChain preNat = getChain(accountIdStr, networkUUIDStr, RuleChainCode.TR_PRENAT);
        RuleChain postNat = getChain(accountIdStr, networkUUIDStr, RuleChainCode.TR_POST);
        RuleChain preFilter = getChain(accountIdStr, networkUUIDStr, RuleChainCode.TR_PREFILTER);
        Router providerRouter = api.getRouter(_providerRouterId);
        Router tenantRouter = getOrCreateGuestNetworkRouter(network);
        RouterPort[] ports = getOrCreateProviderRouterPorts(tenantRouter, providerRouter);
        RouterPort providerDownlink = ports[1];

        // Rules in the preNat table
        Map<String, Rule> existingPreNatRules = new HashMap<String, Rule>();
        for (Rule existingRule : preNat.getRules()) {
            // The "port forwarding" rules we're interested in are dnat rules where src / dst ports are specified
            if(existingRule.getType().equals(DtoRule.DNAT) && existingRule.getTpDst() != null){
                String ruleString = new SimpleFirewallRule(existingRule).toStringArray()[0];
                existingPreNatRules.put(ruleString, existingRule);
            }
        }

        /*
         * Counts of rules associated with an IP address. Use this to check
         * how many rules we have of a given IP address. When it reaches 0,
         * we can delete the route associated with it.
         */
        Map<String, Integer> ipRuleCounts = new HashMap<String, Integer>();
        for (Rule rule : preNat.getRules()) {
            String ip = rule.getNwDstAddress();
            if (ip != null && rule.getNwDstLength() == 32) {
                if (ipRuleCounts.containsKey(ip)) {
                    ipRuleCounts.put(ip, new Integer(ipRuleCounts.get(ip).intValue() + 1));
                } else {
                    ipRuleCounts.put(ip, new Integer(1));
                }
            }
        }

        /*
         * Routes associated with IP. When we delete all the rules associated
         * with a given IP, we can delete the route associated with it.
         */
        Map<String, Route> routes = new HashMap<String, Route>();
        for (Route route : providerRouter.getRoutes(new MultivaluedMapImpl())) {
            String ip = route.getDstNetworkAddr();
            if (ip != null && route.getDstNetworkLength() == 32) {
                routes.put(ip, route);
            }
        }

        for (PortForwardingRule rule : rules) {
            IpAddress dstIp = _networkModel.getIp(rule.getSourceIpAddressId());
            PortForwardingRuleTO ruleTO = new PortForwardingRuleTO(rule, null, dstIp.getAddress().addr());
            SimpleFirewallRule fwRule = new SimpleFirewallRule(ruleTO);
            String[] ruleStrings = fwRule.toStringArray();

            if (rule.getState() == FirewallRule.State.Revoke) {
                /*
                 * Lookup in existingRules, delete if present
                 * We need to delete from both the preNat table and the
                 * postNat table.
                 */
                for(String revokeRuleString : ruleStrings){
                    Rule foundPreNatRule = existingPreNatRules.get(revokeRuleString);
                    if(foundPreNatRule != null){
                        String ip = foundPreNatRule.getNwDstAddress();
                        // is this the last rule associated with this IP?
                        Integer cnt = ipRuleCounts.get(ip);
                        if (cnt != null) {
                            if (cnt == 1) {
                                ipRuleCounts.remove(ip);
                                // no more rules for this IP. delete the route.
                                Route route = routes.remove(ip);
                                route.delete();
                            } else {
                                ipRuleCounts.put(ip, new Integer(ipRuleCounts.get(ip).intValue() - 1));
                            }
                        }
                        foundPreNatRule.delete();
                    }
                }
            } else if (rule.getState() == FirewallRule.State.Add) {
                for(int i = 0; i < ruleStrings.length; i++){
                    String ruleString = ruleStrings[i];
                    Rule foundRule = existingPreNatRules.get(ruleString);
                    if(foundRule == null){

                        String vmIp = ruleTO.getDstIp();
                        String publicIp = dstIp.getAddress().addr();
                        int privPortStart = ruleTO.getDstPortRange()[0];
                        int privPortEnd = ruleTO.getDstPortRange()[1];
                        int pubPortStart = ruleTO.getSrcPortRange()[0];
                        int pubPortEnd = ruleTO.getSrcPortRange()[1];

                        DtoRule.DtoNatTarget[] preTargets = new DtoRule.DtoNatTarget[]{
                            new DtoRule.DtoNatTarget(vmIp, vmIp, privPortStart, privPortEnd)};

                        Rule preNatRule = preNat.addRule()
                            .type(DtoRule.DNAT)
                            .flowAction(DtoRule.Accept)
                            .nwDstAddress(publicIp)
                            .nwDstLength(32)
                            .tpDst(new DtoRange(pubPortStart, pubPortEnd))
                            .natTargets(preTargets)
                            .nwProto(SimpleFirewallRule.stringToProtocolNumber(rule.getProtocol()))
                            .position(1);

                        Integer cnt = ipRuleCounts.get(publicIp);
                        if (cnt != null) {
                            ipRuleCounts.put(publicIp, new Integer(cnt.intValue() + 1));
                        } else {
                            ipRuleCounts.put(publicIp, new Integer(1));
                        }
                        String preNatRuleStr = new SimpleFirewallRule(preNatRule).toStringArray()[0];
                        existingPreNatRules.put(preNatRuleStr, preNatRule);
                        preNatRule.create();

                        if (routes.get(publicIp) == null) {
                            Route route = providerRouter.addRoute()
                                            .type("Normal")
                                            .weight(100)
                                            .srcNetworkAddr("0.0.0.0")
                                            .srcNetworkLength(0)
                                            .dstNetworkAddr(publicIp)
                                            .dstNetworkLength(32)
                                            .nextHopPort(providerDownlink.getId());
                            route.create();
                            routes.put(publicIp, route);
                        }

                        // If Firewall is in our service offering, set up the
                        // default firewall rule
                        if (canHandle(network, Service.Firewall)) {
                            boolean defaultBlock = false;
                            for (Rule filterRule : preFilter.getRules()) {
                                String pfDstIp = filterRule.getNwDstAddress();
                                if (pfDstIp != null && filterRule.getNwDstAddress().equals(publicIp)) {
                                    defaultBlock = true;
                                    break;
                                }
                            }
                            if (!defaultBlock) {
                                preFilter.addRule().type(DtoRule.Drop)
                                    .nwDstAddress(publicIp)
                                    .nwDstLength(32)
                                    .create();
                            }
                        }
                    }
                }
            }
        }
        return true;
    }

    private static Map<Service, Map<Capability, String>> setCapabilities() {
        Map<Service, Map<Capability, String>> capabilities = new HashMap<Service, Map<Capability, String>>();

        // L2 Support : SDN provisioning
        capabilities.put(Service.Connectivity, null);

        // L3 Support : Generic?
        capabilities.put(Service.Gateway, null);

        // L3 Support : DHCP
        Map<Capability, String> dhcpCapabilities = new HashMap<Capability, String>();
        capabilities.put(Service.Dhcp, dhcpCapabilities);

        // L3 Support : SourceNat
        Map<Capability, String> sourceNatCapabilities = new HashMap<Capability, String>();
        //sourceNatCapabilities.putAll(capabilities.get(Service.SourceNat));
        sourceNatCapabilities.put(Capability.SupportedSourceNatTypes,
                "peraccount");
        //sourceNatCapabilities.putAll(capabilities.get(Service.SourceNat));
        sourceNatCapabilities.put(Capability.RedundantRouter, "false");
        capabilities.put(Service.SourceNat, sourceNatCapabilities);

        // L3 Support : Port Forwarding
        capabilities.put(Service.PortForwarding, null);

        // L3 support : StaticNat
        capabilities.put(Service.StaticNat, null);

        // Set capabilities for Firewall service
        Map<Capability, String> firewallCapabilities = new HashMap<Capability, String>();
        firewallCapabilities.put(Capability.TrafficStatistics, "per public ip");
        firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp,icmp");
        firewallCapabilities.put(Capability.SupportedTrafficDirection, "ingress");
        firewallCapabilities.put(Capability.MultipleIps, "true");
        capabilities.put(Service.Firewall, firewallCapabilities);

        return capabilities;
    }

    private String getChainName(String routerName, RuleChainCode chainCode){
        return getChainName("", routerName, chainCode);
    }

    private String getChainName(String networkId, String routerName, RuleChainCode chainCode) {

        String chain = "";

        switch (chainCode){
            case TR_PRE:
                chain = "pre-routing";
                break;
            case TR_PREFILTER:
                chain = "pre-filter";
                break;
            case TR_PRENAT:
                chain = "pre-nat";
                break;
            case TR_POST:
                chain = "post-routing";
                break;
            case ACL_INGRESS:
                chain = "ACL-ingress-" + networkId;
                break;
            case ACL_EGRESS:
                chain = "ACL-egress-" + networkId;
                break;
        }

        return routerName + "-tenantrouter-" + chain;
    }

    protected RuleChain getChain(String accountUuid, String routerName, RuleChainCode chainCode){
        return getChain("", accountUuid, routerName, chainCode);
    }

    protected RuleChain getChain(String networkId, String accountUuid,
                               String routerName, RuleChainCode chainCode){
        String chainName = getChainName(networkId, routerName, chainCode);

        MultivaluedMap findChain = new MultivaluedMapImpl();
        findChain.add("tenant_id", accountUuid);

        ResourceCollection<RuleChain> ruleChains = api.getChains(findChain);

        for(RuleChain chain : ruleChains){
            if(chain.getName().equals(chainName)){
                return chain;
            }
        }

        return null;
    }

    protected RouterPort[] getOrCreateProviderRouterPorts(Router tenantRouter, Router providerRouter){
        RouterPort[] ports = new RouterPort[2];

        RouterPort tenantUplink = null;
        RouterPort providerDownlink = null;

        // Check if the ports and connection already exist
        for(Port peerPort : tenantRouter.getPeerPorts((new MultivaluedMapImpl()))){
            if(peerPort != null && peerPort instanceof RouterPort){
                RouterPort checkPort = (RouterPort) peerPort;
                if(checkPort.getDeviceId().compareTo(providerRouter.getId()) == 0){
                    providerDownlink = checkPort;
                    tenantUplink = (RouterPort) api.getPort(checkPort.getPeerId());
                    break;
                }
            }
        }

        // Create the ports and connection if they don't exist
        if(providerDownlink == null){
            // Add interior port on router side, with network details
            providerDownlink = providerRouter.addInteriorRouterPort().networkAddress("169.254.255.0").networkLength(32)
                    .portAddress("169.254.255.1").create();
            tenantUplink = tenantRouter.addInteriorRouterPort().networkAddress("169.254.255.0").networkLength(32)
                    .portAddress("169.254.255.2").create();

            // Link them up
            providerDownlink.link(tenantUplink.getId()).update();
        }

        ports[0] = tenantUplink;
        ports[1] = providerDownlink;

        return ports;
    }

    private Port[] getOrCreatePublicBridgePorts(NicProfile nic, Bridge publicBridge, Router providerRouter){
        Port[] ports = new Port[2];

        BridgePort bridgeUplink = null;
        RouterPort providerDownlink = null;

        // Check if the ports and connection already exist
        for(Port peerPort : publicBridge.getPeerPorts()){
            if(peerPort != null && peerPort instanceof RouterPort){
                RouterPort checkPort = (RouterPort) peerPort;
                // Check it's a port on the providerRouter with the right gateway address
                if(checkPort.getDeviceId().compareTo(providerRouter.getId()) == 0
                        && checkPort.getPortAddress().equals(nic.getGateway())){
                    providerDownlink = checkPort;
                    bridgeUplink = (BridgePort) api.getPort(checkPort.getPeerId());
                    break;
                }
            }
        }

        // Create the ports and connection if they don't exist
        if(providerDownlink == null){
            String cidr = NetUtils.ipAndNetMaskToCidr(nic.getGateway(), nic.getNetmask());
            String cidrSubnet = NetUtils.getCidrSubNet(cidr);
            int cidrSize = (int) NetUtils.getCidrSize(NetUtils.cidr2Netmask(cidr));
            String gateway = nic.getGateway();

            // Add interior port on router side, with network details
            providerDownlink = providerRouter.addInteriorRouterPort().networkAddress(cidrSubnet).networkLength(cidrSize)
                    .portAddress(gateway).create();
            bridgeUplink = publicBridge.addInteriorPort().create();

            // Link them up
            providerDownlink.link(bridgeUplink.getId()).update();

        }

        ports[0] = bridgeUplink;
        ports[1] = providerDownlink;

        return ports;
    }

    private void ensureBridgeConnectedToRouter(Network network, Bridge netBridge, Router netRouter){
        if(getBridgeToRouterPort(network, netBridge, netRouter) == null){
            connectBridgeToRouter(network, netBridge, netRouter);
        }
    }

    private BridgePort getBridgeToRouterPort(Network network, Bridge netBridge, Router netRouter){
        for (Port p : netBridge.getPeerPorts()) {
            if(p.getClass().equals(BridgePort.class)){
                BridgePort bp = (BridgePort) p;
                if(bp.getPeerId().compareTo(netRouter.getId()) == 0){
                    return bp;
                }
            }
        }
        return null;
    }

    /*
     * resetEgressACLFilter sets the Egress ACL Filter back to its initial
     * state - drop everything. This needs to be called when all Egress
     * ACL rules are deleted, so we can start allowing all Egress traffic
     * again
     */
    protected void resetEgressACLFilter(Network network) {
        boolean isVpc = getIsVpc(network);
        long id = getRouterId(network, isVpc);
        String routerName = getRouterName(isVpc, id);

        RuleChain egressChain = getChain(String.valueOf(network.getId()),
                                         getAccountUuid(network),
                                         routerName,
                                         RuleChainCode.ACL_EGRESS);

        // Clear all the rules out
        for (Rule rule : egressChain.getRules()) {
            rule.delete();
        }

        // Add a matchForwardFlow rule so that we can accept all return traffic
        egressChain.addRule().type(DtoRule.Accept)
            .matchForwardFlow(true)
            .position(1)
            .create();
    }

    protected RuleChain getOrInitEgressACLFilter(Network network) {
        boolean isVpc = getIsVpc(network);
        long id = getRouterId(network, isVpc);
        String routerName = getRouterName(isVpc, id);

        RuleChain egressChain = getChain(String.valueOf(network.getId()),
                                         getAccountUuid(network),
                                         routerName,
                                         RuleChainCode.ACL_EGRESS);

        // Rules set by the user will have a protocol, so we count the ACL
        // rules by counting how much have the nwProto field set.
        int totalRules = 0;
        for (Rule rule : egressChain.getRules()) {
            if (rule.getNwProto() != 0) {
                totalRules++;
            }
        }

        if (totalRules > 0) {
            // There are already rules present, no need to init.
            return egressChain;
        } else {
            // We need to delete any placeholder rules
            for (Rule rule : egressChain.getRules()) {
                rule.delete();
            }
        }

        int pos = 1;
        // If it is ARP, accept it
        egressChain.addRule().type(DtoRule.Accept)
            .dlType(0x0806)
            .position(pos++)
            .create();

        // If it is ICMP to the router, accept that
        egressChain.addRule().type(DtoRule.Accept)
            .nwProto(SimpleFirewallRule.stringToProtocolNumber("icmp"))
            .nwDstAddress(network.getGateway())
            .nwDstLength(32)
            .position(pos++)
            .create();

        // Everything else gets dropped
        egressChain.addRule()
            .type(DtoRule.Drop)
            .position(pos)
            .create();

        return egressChain;
    }

    private void connectBridgeToRouter(Network network, Bridge netBridge, Router netRouter){

        boolean isVpc = getIsVpc(network);
        long id = getRouterId(network, isVpc);
        String routerName = getRouterName(isVpc, id);
        String accountIdStr = getAccountUuid(network);

        // Add interior port on bridge side
        BridgePort bridgePort = netBridge.addInteriorPort().create();

        // Add interior port on router side, with network details
        RouterPort routerPort = netRouter.addInteriorRouterPort();
        String cidr = network.getCidr();
        String cidrSubnet = NetUtils.getCidrSubNet(cidr);
        int cidrSize = (int) NetUtils.getCidrSize(NetUtils.cidr2Netmask(cidr));

        routerPort.networkAddress(cidrSubnet);
        routerPort.networkLength(cidrSize);
        routerPort.portAddress(network.getGateway());

        // If this is a VPC, then we will be using NetworkACLs, which is
        // implemented via chains on the router port to that network.
        if (getIsVpc(network)) {
            // Create ACL filter chain for traffic coming INTO the network
            // (outbound from the port
            int pos = 1;

            RuleChain inc = api.addChain()
                .name(getChainName(String.valueOf(network.getId()),
                                   routerName,
                                   RuleChainCode.ACL_INGRESS))
                .tenantId(accountIdStr)
                .create();

            // If it is ARP, accept it
            inc.addRule().type(DtoRule.Accept)
                         .dlType(0x0806)
                         .position(pos++)
                         .create();

            // If it is ICMP to the router, accept that
            inc.addRule().type(DtoRule.Accept)
                   .nwProto(SimpleFirewallRule.stringToProtocolNumber("icmp"))
                         .nwDstAddress(network.getGateway())
                         .nwDstLength(32)
                         .position(pos++)
                         .create();

            // If it is connection tracked, accept that as well
            inc.addRule().type(DtoRule.Accept)
                         .matchReturnFlow(true)
                         .position(pos++)
                         .create();

            inc.addRule().type(DtoRule.Drop)
                         .position(pos)
                         .create();

            //
            RuleChain out = api.addChain()
                .name(getChainName(String.valueOf(network.getId()),
                                   routerName,
                                   RuleChainCode.ACL_EGRESS))
                .tenantId(accountIdStr)
                .create();

            // Creating the first default rule here that does nothing
            // but start connection tracking.
            out.addRule().type(DtoRule.Accept)
                         .matchForwardFlow(true)
                         .position(1)
                         .create();

            routerPort.outboundFilterId(inc.getId());
            routerPort.inboundFilterId(out.getId());
        }

        routerPort.create();

        // Link them up
        bridgePort.link(routerPort.getId()).update();

        // Set up default route from router to subnet
        netRouter.addRoute().type("Normal").weight(100)
                .srcNetworkAddr("0.0.0.0").srcNetworkLength(0)
                .dstNetworkAddr(cidrSubnet).dstNetworkLength(cidrSize)
                .nextHopPort(routerPort.getId()).nextHopGateway(null).create();
    }

    private Bridge getOrCreateNetworkBridge(Network network){
        // Find the single bridge for this network, create if doesn't exist
        return getOrCreateNetworkBridge(network.getId(), getAccountUuid(network));
    }

    private Bridge getOrCreateNetworkBridge(long networkID, String accountUuid){
        Bridge netBridge = getNetworkBridge(networkID, accountUuid);
        if(netBridge == null){

            String networkUUIDStr = String.valueOf(networkID);

            s_logger.debug("Attempting to create guest network bridge");
            try {
                netBridge = api.addBridge().tenantId(accountUuid).name(networkUUIDStr).create();
            } catch (HttpInternalServerError ex) {
                s_logger.warn("Bridge creation failed, retrying bridge get in case it now exists.", ex);
                netBridge = getNetworkBridge(networkID, accountUuid);
            }
        }
        return netBridge;
    }

    private Bridge getNetworkBridge(long networkID, String accountUuid){

        MultivaluedMap qNetBridge = new MultivaluedMapImpl();
        String networkUUIDStr = String.valueOf(networkID);
        qNetBridge.add("tenant_id", accountUuid);

        for (Bridge b : this. api.getBridges(qNetBridge)) {
            if(b.getName().equals(networkUUIDStr)){
                return b;
            }
        }

        return null;
    }

    protected boolean getIsVpc(Network network) {
        return (network.getVpcId() != null);
    }

    protected long getRouterId(Network network, boolean isVpc) {
        if (isVpc) {
            return network.getVpcId();
        } else {
            return network.getId();
        }
    }

    private Router getOrCreateGuestNetworkRouter(Network network){
        // Find the single bridge for this (isolated) guest network, create if doesn't exist
        boolean isVpc = getIsVpc(network);
        long id = getRouterId(network, isVpc);

        return getOrCreateGuestNetworkRouter(id, getAccountUuid(network), isVpc);

    }

    protected String getRouterName(boolean isVpc, long id) {
        if (isVpc) {
            return "VPC" + String.valueOf(id);
        } else {
            return String.valueOf(id);
        }
    }

    protected Router createRouter(long id, String accountUuid, boolean isVpc) {

        String routerName = getRouterName(isVpc, id);

        //Set up rule chains
        RuleChain pre = api.addChain()
                            .name(getChainName(routerName, RuleChainCode.TR_PRE))
                            .tenantId(accountUuid)
                            .create();
        RuleChain post = api.addChain()
                            .name(getChainName(routerName, RuleChainCode.TR_POST))
                            .tenantId(accountUuid)
                            .create();

        // Set up NAT and filter chains for pre-routing
        RuleChain preFilter = api.addChain()
                                  .name(getChainName(routerName, RuleChainCode.TR_PREFILTER))
                                  .tenantId(accountUuid)
                                  .create();
        RuleChain preNat = api.addChain()
                                  .name(getChainName(routerName, RuleChainCode.TR_PRENAT))
                                  .tenantId(accountUuid)
                                  .create();

        // Hook the chains in - first jump to Filter chain, then jump to Nat chain
        pre.addRule().type(DtoRule.Jump)
                     .jumpChainId(preFilter.getId())
                     .position(1)
                     .create();
        pre.addRule().type(DtoRule.Jump)
                     .jumpChainId(preNat.getId())
                     .position(2)
                     .create();

        return api.addRouter()
                   .tenantId(accountUuid)
                   .name(routerName)
                   .inboundFilterId(pre.getId())
                   .outboundFilterId(post.getId())
                   .create();
    }

    private Router getOrCreateGuestNetworkRouter(long id, String accountUuid, boolean isVpc) {
        Router tenantRouter = getGuestNetworkRouter(id, accountUuid, isVpc);
        if(tenantRouter == null){
            tenantRouter = createRouter(id, accountUuid, isVpc);
        }
        return tenantRouter;
    }

    private Router getGuestNetworkRouter(long id, String accountUuid, boolean isVpc){

        MultivaluedMap qNetRouter = new MultivaluedMapImpl();
        String routerName = getRouterName(isVpc, id);

        qNetRouter.add("tenant_id", accountUuid);

        for (Router router : api.getRouters(qNetRouter)) {
            if(router.getName().equals(routerName)){
                return router;
            }
        }

        return null;
    }

    private UUID getNicUUID(NicProfile nic){
        NicVO nicvo = _nicDao.findById(nic.getId());
        return UUID.fromString(nicvo.getUuid());
    }

    private void cleanBridge(Bridge br) {

        for(Port peerPort : br.getPeerPorts()) {
            if(peerPort != null && peerPort instanceof RouterPort){
                RouterPort checkPort = (RouterPort) peerPort;
                if(checkPort.getType().equals("ExteriorRouter")) {
                    checkPort.vifId(null).update();
                } else if (checkPort.getType().equals("InteriorRouter")) {
                    checkPort.unlink();
                }
                checkPort.delete();
            }
        }

        for(BridgePort p : br.getPorts()) {

            if(p.getType().equals("ExteriorBridge")) {
                // Set VIF ID to null
                p.vifId(null).update();
            }

            if(p.getType().equals("InteriorBridge")) {
                p.unlink();
            }

            // Delete port
            p.delete();
        }
    }

    private void deleteNetworkBridges(Network network){
        String accountUuid = getAccountUuid(network);
        long networkID = network.getId();

        Bridge netBridge = getNetworkBridge(networkID, accountUuid);
        if(netBridge != null){

            cleanBridge(netBridge);

            // Delete DHCP subnets
            for(Object dhcpSubnet : netBridge.getDhcpSubnets()){
                DhcpSubnet sub = (DhcpSubnet) dhcpSubnet;
                sub.delete();
            }

            netBridge.delete();
        }
    }

    private void deleteGuestNetworkRouters(Network network){
        String accountUuid = getAccountUuid(network);
        boolean isVpc = getIsVpc(network);
        long id = getRouterId(network, isVpc);

        Router tenantRouter = getGuestNetworkRouter(id, accountUuid, isVpc);

        // Delete any peer ports corresponding to this router
        for(Port peerPort : tenantRouter.getPeerPorts((new MultivaluedMapImpl()))){
            if(peerPort != null && peerPort instanceof RouterPort){
                RouterPort checkPort = (RouterPort) peerPort;
                if(checkPort.getType().equals("ExteriorRouter")) {
                    checkPort.vifId(null).update();
                } else if (checkPort.getType().equals("InteriorRouter")) {
                    checkPort.unlink();
                }
                checkPort.delete();
            } else if (peerPort != null && peerPort instanceof BridgePort) {
                BridgePort checkPort = (BridgePort) peerPort;
                if(checkPort.getType().equals("ExteriorBridge")) {
                    checkPort.vifId(null).update();
                } else if (checkPort.getType().equals("InteriorBridge")) {
                    checkPort.unlink();
                }
                checkPort.delete();
            }
        }

        if(tenantRouter != null){
            // Remove all peer ports if any exist
            for(RouterPort p : tenantRouter.getPorts(new MultivaluedMapImpl())) {
                if(p.getType().equals("ExteriorRouter")) {
                    // Set VIF ID to null
                    p.vifId(null).update();
                    // the port might have some chains associated with it
                }

                if(p.getType().equals("InteriorRouter")) {
                    p.unlink();
                }

                // Delete port
                p.delete();
            }

            // Remove inbound and outbound filter chains
            String accountIdStr = String.valueOf(accountUuid);
            String routerName = getRouterName(isVpc, id);

            RuleChain pre = api.getChain(tenantRouter.getInboundFilterId());
            RuleChain preFilter = getChain(accountIdStr, routerName, RuleChainCode.TR_PREFILTER);
            RuleChain preNat = getChain(accountIdStr, routerName, RuleChainCode.TR_PRENAT);
            RuleChain post = api.getChain(tenantRouter.getOutboundFilterId());

            pre.delete();
            preFilter.delete();
            preNat.delete();
            post.delete();

            // Remove routes
            for(Route r : tenantRouter.getRoutes(new MultivaluedMapImpl())) {
                r.delete();
            }

            tenantRouter.delete();
        }
    }

    @Override
    public List<Class<?>> getCommands() {
        // MidoNet does not implement any commands, so we return an empty list.
        return new ArrayList<Class<?>>();
    }
}


text:
<%!
   from r2.lib.template_helpers import get_domain
%>

${thing.listing}

${_("submit a discussion")}

redpajama_set_name: RedPajamaGithub


text:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >

    <stroke
        android:width="1dp"
        android:color="@color/white" />

    <corners
        android:bottomLeftRadius="3dp"
        android:bottomRightRadius="3dp"
        android:topLeftRadius="3dp"
        android:topRightRadius="3dp" />

</shape>


text:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.ApplicationModel.Email;
using Windows.ApplicationModel.Store;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Graphics.Display;
using Windows.Phone.UI.Input;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// "空白页"项模板在 http://go.microsoft.com/fwlink/?LinkID=390556 上有介绍

namespace TryClient
{
    /// <summary>
    /// 可用于自身或导航至 Frame 内部的空白页。
    /// </summary>
    public sealed partial class About : Page
    {
        public About()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// 在此页将要在 Frame 中显示时进行调用。
        /// </summary>
        /// <param name="e">描述如何访问此页的事件数据。
        /// 此参数通常用于配置页。</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            if (DisplayInformation.GetForCurrentView().CurrentOrientation != DisplayOrientations.Portrait)
            {
                DisplayInformation.AutoRotationPreferences = DisplayOrientations.Portrait;
            }
            HardwareButtons.BackPressed += HardwareButtons_BackPressed;
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            HardwareButtons.BackPressed -= HardwareButtons_BackPressed;
        }

        void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
        {
            Frame rootFrame = Window.Current.Content as Frame;
            if (rootFrame != null && rootFrame.CanGoBack)
            {
                rootFrame.GoBack();
                e.Handled = true;
            }
        }

        private async void SendEmail()
        {
            //predefine Recipient
            EmailRecipient sendTo = new EmailRecipient()
            {
                Address = "654664168@qq.com"
            };

            string FirmwareVersion = "";//DeviceStatus.DeviceFirmwareVersion;
            string DeviceName = "";// DeviceStatus.DeviceName;

            //generate mail object
            EmailMessage mail = new EmailMessage();
            mail.Subject = @"关于《微博江湖1.0》应用的反馈";
            mail.Body = "\n\r\n\r\n\r我的手机:" + DeviceName + "\n\r系统版本:" + FirmwareVersion;

            //add recipients to the mail object
            mail.To.Add(sendTo);

            //open the share contract with Mail only:
            await EmailManager.ShowComposeNewEmailAsync(mail);
        }

        private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
        {
            SendEmail();
        }

        private async void AppBarButton_Click(object sender, RoutedEventArgs e)
        {
            await Windows.System.Launcher.LaunchUriAsync(
                  new Uri("ms-windows-store:reviewapp?appid=" + CurrentApp.AppId));
        }
    }
}


text:
'use strict';

/**
 * @class
 * Initializes a new instance of the WorkflowTriggerCallbackUrl class.
 * @constructor
 * The workflow trigger callback URL.
 *
 * @member {string} [value] Gets the workflow trigger callback URL.
 *
 */
class WorkflowTriggerCallbackUrl {
  constructor() {
  }

  /**
   * Defines the metadata of WorkflowTriggerCallbackUrl
   *
   * @returns {object} metadata of WorkflowTriggerCallbackUrl
   *
   */
  mapper() {
    return {
      required: false,
      serializedName: 'WorkflowTriggerCallbackUrl',
      type: {
        name: 'Composite',
        className: 'WorkflowTriggerCallbackUrl',
        modelProperties: {
          value: {
            required: false,
            readOnly: true,
            serializedName: 'value',
            type: {
              name: 'String'
            }
          }
        }
      }
    };
  }
}

module.exports = WorkflowTriggerCallbackUrl;


text:
<?php

namespace Swoft\Base;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;
use Swoft\Web\MessageTrait;

class Response implements ResponseInterface
{
    use MessageTrait;

    /** @var array Map of standard HTTP status code/reason phrases */
    private static $phrases = [
        100 => 'Continue',
        101 => 'Switching Protocols',
        102 => 'Processing',
        200 => 'OK',
        201 => 'Created',
        202 => 'Accepted',
        203 => 'Non-Authoritative Information',
        204 => 'No Content',
        205 => 'Reset Content',
        206 => 'Partial Content',
        207 => 'Multi-status',
        208 => 'Already Reported',
        300 => 'Multiple Choices',
        301 => 'Moved Permanently',
        302 => 'Found',
        303 => 'See Other',
        304 => 'Not Modified',
        305 => 'Use Proxy',
        306 => 'Switch Proxy',
        307 => 'Temporary Redirect',
        400 => 'Bad Request',
        401 => 'Unauthorized',
        402 => 'Payment Required',
        403 => 'Forbidden',
        404 => 'Not Found',
        405 => 'Method Not Allowed',
        406 => 'Not Acceptable',
        407 => 'Proxy Authentication Required',
        408 => 'Request Time-out',
        409 => 'Conflict',
        410 => 'Gone',
        411 => 'Length Required',
        412 => 'Precondition Failed',
        413 => 'Request Entity Too Large',
        414 => 'Request-URI Too Large',
        415 => 'Unsupported Media Type',
        416 => 'Requested range not satisfiable',
        417 => 'Expectation Failed',
        418 => 'I\'m a teapot',
        422 => 'Unprocessable Entity',
        423 => 'Locked',
        424 => 'Failed Dependency',
        425 => 'Unordered Collection',
        426 => 'Upgrade Required',
        428 => 'Precondition Required',
        429 => 'Too Many Requests',
        431 => 'Request Header Fields Too Large',
        451 => 'Unavailable For Legal Reasons',
        500 => 'Internal Server Error',
        501 => 'Not Implemented',
        502 => 'Bad Gateway',
        503 => 'Service Unavailable',
        504 => 'Gateway Time-out',
        505 => 'HTTP Version not supported',
        506 => 'Variant Also Negotiates',
        507 => 'Insufficient Storage',
        508 => 'Loop Detected',
        511 => 'Network Authentication Required',
    ];

    /**
     * @var string
     */
    protected $reasonPhrase = '';

    /**
     * @var int
     */
    protected $statusCode = 200;

    /**
     * @var string
     */
    protected $charset = 'utf-8';

    /**
     * swoole响应请求
     *
     * @var \Swoole\Http\Response
     */
    protected $swooleResponse;

    /**
     * 初始化响应请求
     *
     * @param \Swoole\Http\Response $response
     */
    public function __construct(\Swoole\Http\Response $response)
    {
        $this->swooleResponse = $response;
    }

    /**
     * 响应数据
     */
    public function send()
    {

    }

    /**
     * Gets the response status code.
     * The status code is a 3-digit integer result code of the server's attempt
     * to understand and satisfy the request.
     *
     * @return int Status code.
     */
    public function getStatusCode(): int
    {
        return $this->statusCode;
    }

    /**
     * Return an instance with the specified status code and, optionally, reason phrase.
     * If no reason phrase is specified, implementations MAY choose to default
     * to the RFC 7231 or IANA recommended reason phrase for the response's
     * status code.
     * This method MUST be implemented in such a way as to retain the
     * immutability of the message, and MUST return an instance that has the
     * updated status and reason phrase.
     *
     * @link http://tools.ietf.org/html/rfc7231#section-6
     * @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
     *
     * @param int    $code         The 3-digit integer result code to set.
     * @param string $reasonPhrase The reason phrase to use with the
     *                             provided status code; if none is provided, implementations MAY
     *                             use the defaults as suggested in the HTTP specification.
     *
     * @return static
     * @throws \InvalidArgumentException For invalid status code arguments.
     */
    public function withStatus($code, $reasonPhrase = ''): self
    {
        $clone = clone $this;
        $clone->statusCode = (int)$code;
        if (!$reasonPhrase && isset(self::$phrases[$code])) {
            $reasonPhrase = self::$phrases[$code];
        }
        $clone->reasonPhrase = $reasonPhrase;
        return $clone;
    }

    /**
     * Return the reason phrase by code
     *
     * @param $code
     *
     * @return string
     */
    public static function getReasonPhraseByCode($code): string
    {
        return self::$phrases[$code] ?? '';
    }

    /**
     * Return an instance with the specified charset content type.
     *
     * @param $charset
     *
     * @return static
     */
    public function withCharset($charset): self
    {
        $clone = clone $this;
        $clone->withAddedHeader('Content-Type', sprintf('charset=%s', $charset));
        return $clone;
    }

    /**
     * Gets the response reason phrase associated with the status code.
     * Because a reason phrase is not a required element in a response
     * status line, the reason phrase value MAY be null. Implementations MAY
     * choose to return the default RFC 7231 recommended reason phrase (or those
     * listed in the IANA HTTP Status Code Registry) for the response's
     * status code.
     *
     * @link http://tools.ietf.org/html/rfc7231#section-6
     * @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
     * @return string Reason phrase; must return an empty string if none present.
     */
    public function getReasonPhrase(): string
    {
        return $this->reasonPhrase;
    }

    /**
     * @return string
     */
    public function getCharset(): string
    {
        return $this->charset;
    }

    /**
     * @param string $charset
     *
     * @return Response
     */
    public function setCharset(string $charset): Response
    {
        $this->charset = $charset;
        return $this;
    }
}


text:
Kendocup::Engine.routes.draw do

end


text:
module WhenIWork
  class Connection
    class User

      attr_reader :id, :first_name, :last_name, :email, :phone_number,
        :hours_preferred, :hours_max, :hourly_rate, :role, :notes, :activated

      def initialize(connection, api_hash)
        @connection = connection

        # direct associations

        @position_ids = api_hash.delete('positions')
        @positions = nil

        @location_ids = api_hash.delete('locations')
        @locations = nil

        # associations available from other endpoints

        @availabilities = nil

        # we're saving all the fields from the API response, but note that
        # we only have attr_readers for those listed in the API doc
        api_hash.each do |k, v|
          instance_variable_set "@#{k}".to_sym, v
        end
      end

      def positions
        return @positions if @positions
        @positions = []
        for position_id in @position_ids
          @positions << @connection.get_position(position_id)
        end
        return @positions
      end

      def locations
        return @locations if @locations
        @locations = []
        for location_id in location_ids
          @locations << @connection.get_location(location_id)
        end
        return @locations
      end

      def availabilities
        return @availabilities if @availabilities
        @availabilities = @connection.list_availabilities(self.id)
      end

    end
  end
end


text:
require 'spec_helper'
require 'vk/api/account/methods/get_profile_info'

RSpec.describe Vk::API::Account::Methods::GetProfileInfo do
  subject(:model) { described_class }
  it { is_expected.to be < Dry::Struct }
  it { is_expected.to be < Vk::Schema::Method }

  describe 'attributes' do
    subject(:attributes) { model.instance_methods(false) }

  end
end


text:
FROM ubuntu
EXPOSE 8888

# You can mount your own SSL certs as necessary here
ENV PEM_FILE /key.pem
# $PASSWORD will get `unset` within notebook.sh, turned into an IPython style hash
ENV PASSWORD Dont make this your default
ENV USE_HTTP 0

# Create a mount point for our notebooks
VOLUME /notebooks
# Make our home directory /notebooks
WORKDIR /notebooks

# Create a default password – we will change this on the commandline but incase we forget!
ENV PASSWORD datascience!

# Add proxy settings
ADD  ./setenv.sh /tmp/
RUN sudo -E /tmp/setenv.sh

# make sure our software packages are patched and up to date
RUN sed -i -e 's/us.archive.ubuntu.com/archive.ubuntu.com/g' /etc/apt/sources.list
RUN sudo apt-get update
RUN sudo apt-get upgrade -y

# Add Python
RUN sudo apt-get -y install python3
RUN sudo apt-get -y install python3-pip
RUN sudo sudo ln -s /usr/bin/pip3 /usr/bin/pip
RUN apt-get install -y curl
RUN apt-get install -y wget
RUN apt-get install -y socat
# These lines don't need to be run because of the $GIT_PROXY_COMMAND variable set in setenv.sh
# RUN sudo -E git config --global http.proxy $http_proxy
# RUN sudo -E git config --global https.proxy $https_proxy

# for consistencey and security we should compile it ourselves but this doesn't work
# because compiling from sources doesn't work during the "Big Split"
# RUN git clone https://github.com/ipython/ipython/releases
#
# Instead we have to "temprarily" tust the current builds
RUN sudo -E pip install "ipython[all]"
RUN sudo -E apt-get -y build-dep python3-matplotlib
RUN sudo -E pip install numpy
RUN sudo -E pip install python-dateutil
RUN sudo -E pip install pytz
RUN sudo -E pip install numexpr
RUN sudo -E pip install bottleneck
RUN sudo -E pip install cython
RUN sudo -E apt-get -y install gfortran
RUN sudo -E apt-get -y install libopenblas-dev
RUN sudo -E apt-get -y install liblapack-dev
RUN sudo -E pip install scipy
RUN sudo -E pip install sqlalchemy
RUN sudo apt-get -y install git
RUN mkdir /usr/src/matplotlib
RUN sudo -E git clone https://github.com/matplotlib/matplotlib /usr/src/matplotlib
RUN cd /usr/src/matplotlib; sudo python ./setup.py install
RUN sudo -E pip install statsmodels
RUN sudo -E pip install openpyxl
RUN sudo -E pip install boto
RUN sudo -E pip install python-gflags
RUN sudo -E pip install google-api-python-client
RUN sudo -E pip install setuptools
RUN sudo -E apt-get -y build-dep python-lxml
RUN sudo -E pip install lxml
RUN sudo -E pip install beautifulsoup4
RUN sudo -E pip install blaze
#  There is a bug in the vertica-sqlalchemy package so install from source and patch
# RUN sudo -E pip install vertica-sqlalchemy
RUN sudo -E sh -c "wget -qO- https://get.docker.io/gpg | apt-key add -"
RUN mkdir /usr/src/vertica-sqlalchemy
RUN sudo -E git clone git://github.com/jamescasbon/vertica-sqlalchemy /usr/src/vertica-sqlalchemy
RUN sudo -E apt-get install -y unixODBC unixODBC-dev
RUN cd  /usr/src/vertica-sqlalchemy; sudo python ./setup.py install
RUN sudo -E apt-get install -y libmysql-java
RUN sudo -E pip install pandas
RUN sudo -E apt-get install -y unixODBC unixODBC-dev
RUN cd  /usr/src/vertica-sqlalchemy; sudo python ./setup.py install
RUN sudo -E apt-get install -y libmysql-java
RUN sudo -E apt-get install -y python-mysqldb
RUN sudo -E apt-get install -y unixodbc-dev
RUN sudo -E apt-get install -y python-dev
RUN sudo -E apt-get install -y libpq-dev
RUN sudo -E apt-get install -y unixodbc
RUN sudo -E apt-get install -y freetds-dev
RUN sudo -E apt-get install -y tdsodbc
RUN sudo -E pip install https://pyodbc.googlecode.com/files/pyodbc-3.0.7.zip
RUN sudo -E apt-get install -y mysql-server
RUN sudo -E pip install https://github.com/PyMySQL/PyMySQL/archive/master.zip
# sudo -E apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E084DAB9
RUN sudo -E apt-get install -y software-properties-common
RUN sudo -E apt-get install -y python-software-properties
# RUN sudo -E add-apt-repository -y ppa:marutter/rrutter
RUN sudo -E echo "deb http://cran.r-project.org/bin/linux/ubuntu trusty/" >> /etc/apt/sources.list
RUN sudo -E apt-get update
RUN sudo -E apt-get install -y --force-yes r-base
RUN sudo -E apt-get install -y --force-yes r-base-dev
RUN sudo -E pip install rpy2
RUN sudo -E apt-get install -y wget
RUN sudo -E apt-get install -y default-jre
RUN sudo -E apt-get install -y default-jdk
# RUN sudo -E pip install mysql-connector-python
ENV DEBIAN_FRONTEND=noninteractive
RUN sudo echo mysql-apt-config mysql-apt-config/enable-repo select mysql-5.5-dmr | sudo debconf-set-selections
RUN wget http://dev.mysql.com/get/mysql-apt-config_0.3.3-2ubuntu14.04_all.deb ; sudo dpkg --install mysql-apt-config_0.3.3-2ubuntu14.04_all.deb
RUN sudo git clone https://github.com/mysql/mysql-connector-python.git /usr/src/mysql-connector-python
RUN cd  /usr/src/mysql-connector-python; sudo python ./setup.py install
RUN sudo git clone https://github.com/farcepest/moist.git /usr/src/moist
RUN sudo apt-get install -y libmysqlclient-dev
RUN cd  /usr/src/moist; sudo python ./setup.py install
RUN cd  /usr/src/vertica-sqlalchemy; sudo python ./setup.py install
RUN sudo -E pip3 install mysql-connector-python --allow-external mysql-connector-python
# Uncomment this if you have the Vertica connector
# ADD  ./vertica-client-7.1.1-0.linux.x86_64.tar.gz /
ADD ./odbc.ini /etc/
# These files have to be on your Docker host or you have to install them in the container
ADD ./odbcinst.ini /etc/
ADD ./vertica.ini /etc/
# Maybe we don't need this --> RUN sudo -E pip install MySQL-python
# RUN wget http://cran.csiro.au/src/contrib/likelihood_1.5.tar.gz /usr/src
# https://github.com/hadley/ggplot2/archive/master.zip
# RUN sudo R CMD INSTALL /usr/src/likelihood_1.5.tar.gz

# ---------------- Doesn't work yet ------------------------
# RUN sudo -E pip install hpy5
# RUN sudo -E pip install jasonschema
# RUN sudo -E pip install pytables
# RUN sudo -E pip install bcols

# CMD ipython notebook --ip=* --no-browser --port=8888
ADD runcmd.sh /
RUN chmod u+x /runcmd.sh
CMD ["/runcmd.sh"]


text:
//
//  UINavigationController+BarButtonItem.h
//  ZWUtilityKit
//
//  Created by 陈正旺 on 15/1/30.
//  Copyright (c) 2015年 zwchen. All rights reserved.
//

/*
 *  @description:提供设置导航栏中按钮
 */

#import <UIKit/UIKit.h>
#import "UtilityKit.h"

_Pragma("clang diagnostic push")
_Pragma("clang diagnostic ignored \"-Wmacro-redefined\"")

#define TOP_STATUS_BAR_HEIGHT (IOS7 ? Status_Bar_Height : 0)
#define Nav_Left_BarItem_Offset (IOS7 ? -15.0f : -5.0f)
#define Nav_Right_BarItem_Offset (IOS7 ? -15.0f : -5.0f)
#define Navigation_Bar_Animaiton_Interval 0.5

@interface UIViewController (BarButtonItem)

- (void)setDefaultBackBarButtonItem;
- (void)setLeftBarButtonItem:(UIBarButtonItem *)item offset:(float)offset;
- (void)setRightBarButtonItem:(UIBarButtonItem *)item offset:(float)offset;

- (UIBarButtonItem*)createNavButton:(NSString *)strImageName highImage:(NSString *)strHighImage title:(NSString *)strTitle target:(id)target action:(SEL)btnAction offset:(float)offset;

@end

_Pragma("clang diagnostic pop")


text:
from subprocess import call
import sys
import os

try:
    os.remove(sys.argv[2])
except:
    pass
call(["scrapy", "crawl", sys.argv[1], "-o", sys.argv[2]])


text:
class InputNeuron

  attr_accessor :input
  attr_accessor :connected_output_neurons

  def initialize
    @input = nil
    @connected_output_neurons=[]
  end

  def output
    @input
  end
end

class Neuron
  attr_accessor :inputs, :weights, :error
  attr_accessor :connected_output_neurons

  def initialize(weights=[])
    @inputs = []
    @output = nil
    @connected_output_neurons=[]
    @weights = weights
    @error = nil
  end

  def output
    if @output.nil?
      weighted_inputs = []
      @inputs.each_with_index {|n,i| weighted_inputs << n.output*@weights[i]}
      sum = weighted_inputs.inject(0, :+)
      @output = 1.0 / (1 + Math.exp(-sum))
    end
    @output
  end

  def reset
    @output = nil
  end

  def inputs=(inputs)
    @output=nil
    @inputs = inputs
  end

  def weights=(weights)
    @output = nil
    @weights = weights
  end

  def weighted_error(input_neuron)
    index = @inputs.index(input_neuron)
    @error * weights[index]
  end

end

class Layer

  attr_accessor :name
  attr_reader :neurons

  def initialize(name, neuron_count, neuron_class)
    @neurons = []
    neuron_count.times do
      @neurons << neuron_class.new
    end
  end

  def neuron_count
    @neurons.count
  end
end

class NeuralNetwork

  attr_reader :hidden_layers
  attr_reader :output_layer

  def self.build(hidden_neurons_weights, output_neuron_weights)
    nn = self.new(hidden_neurons_weights[0].count, hidden_neurons_weights.count, output_neuron_weights.count)
    nn.hidden_neurons.each_with_index do |n, i|
      n.weights = hidden_neurons_weights[i]
    end
    nn.output_neurons.each_with_index do |n, i|
      n.weights = output_neuron_weights[i]
    end
    nn
  end

  def initialize(input_count=nil, hidden_neuron_count=nil, output_neuron_count=nil)
    @input_layer = nil
    @hidden_layers = []
    @output_layer = nil
    unless input_count.nil?
      build_nn(input_count, hidden_neuron_count, output_neuron_count)
    end
  end

  def create_input_layer(neuron_count)
    @input_layer = Layer.new('input', neuron_count, InputNeuron)
  end

  def create_hidden_layer(name, neuron_count)
    layer = Layer.new(name, neuron_count, Neuron)
    @hidden_layers << layer
    layer
  end

  def create_output_layer(neuron_count)
    @output_layer = Layer.new('output', neuron_count, Neuron)
  end

  def connect(from_layer, from_neuron_range, to_layer, to_neuron_range)
    neurons_to_connect = to_layer.neurons[to_neuron_range]
    from_layer.neurons[from_neuron_range].each do |neuron|
      neurons_to_connect.each do |neuron_to_connect|
        neuron_to_connect.inputs << neuron
        neuron.connected_output_neurons << neuron_to_connect
      end
    end
    neurons_to_connect.each do |neuron|
      neuron.weights = build_weights(neuron.inputs.count)
    end
  end

  def reset
    @hidden_layers.map {|l| l.neurons.map {|n| n.reset } }
    @output_layer.neurons.map {|n| n.reset }
  end

  def print_hidden_neurons
    print_neurons(@hidden_neurons)
  end

  def print_neurons(neurons)
    neurons.each {|n| p n}
  end

  def print_hidden_neurons_weights
    print_neurons_weights(@hidden_neurons)
  end

  def print_output_neurons_weights
    print_neurons_weights(@output_neurons)
  end

  def print_neurons_weights(neurons)
    neurons.each do |n|
      p n.weights
    end
  end

  def evaluate(inputs)
    @input_layer.neurons.each_with_index do |n, i|
      n.input = inputs[i]
    end
    @output_layer.neurons.map {|n| n.output}
  end

  def calc_output_errors(expected_outputs)
    @output_layer.neurons.each_with_index do |neuron, i|
      neuron.error =
        (expected_outputs[i] - neuron.output) *  neuron.output * (1 - neuron.output)
    end
  end

  def calc_hidden_layer_errors()
    @hidden_layers.reverse.each do |layer|
      layer.neurons.each_with_index do |neuron, i|
        weighted_errors = neuron.connected_output_neurons.map {|on| on.weighted_error(neuron)}

        #weighted_errors = @output_neurons.map { |n| n.error*n.weights[i] }
        sum = weighted_errors.inject(0, :+)
        output = neuron.output
        neuron.error = output * (1.0 - output) * sum
      end
    end
  end

  def update_weights
    @hidden_layers.reverse.each do |layer|
      update_neurons_weights(layer.neurons)
    end
    update_neurons_weights(@output_layer.neurons)
  end

private

  def update_neurons_weights(neurons)
    neurons.each do |n|
      n.inputs.each_with_index do |input_neuron, i|
        n.weights[i] = n.weights[i] + 0.3 * n.error * input_neuron.output
      end
    end
  end

  def build_nn(input_count, hidden_neuron_count, output_neuron_count)
    l = self.create_input_layer(input_count)
    hl = self.create_hidden_layer('L1', hidden_neuron_count)
    ol = self.create_output_layer(output_neuron_count)
    self.connect(l, 0..-1, hl, 0..-1)
    self.connect(hl, 0..-1, ol, 0..-1)
  end

  def build_weights(count)
    weights = []
    count.times { weights << (rand * 2 - 1)/5.0 }
    weights
  end
end

def to_inputs(s, count)
  s = "" if s.nil?
  s.upcase!
  s = s.split.join(" ").split("")
  s = s[0..count-1]
  s = s.map {|ch| ch.ord/255.0 }
  s = [] if s == ""
  (count - s.length).times do
    s << 0
  end
  s
end

nn = NeuralNetwork.new(1, 4, 1)

training = []
20.times do
  v = rand
  e = 0.0
  if v > 0.5
    e = 1.0
  end
  training << [v, e]
end

550.times do
  success = 0
  training.each do |v,e|
    output = nn.evaluate([v])[0]
    if e == 1.0
      success += 1 if output > 0.5
    else
      success += 1 if output < 0.5
    end
    #p "training: #{v}, expecting #{e}, got #{nn.evaluate([v])}"

   nn.calc_output_errors([e])
   nn.calc_hidden_layer_errors
   nn.update_weights
   nn.reset

  end
  p "#{success.to_f/training.count.to_f*100}"
end

nn.print_hidden_neurons_weights
p "Output neurons"
nn.print_output_neurons_weights


text:
CREATE TABLE IF NOT EXISTS `users` (
    `username` VARCHAR ( 254 ) NOT NULL PRIMARY KEY ,
    `password` TEXT NOT NULL ,
    `salt` TEXT NOT NULL ,
    `admin` INTEGER( 1 ) NOT NULL DEFAULT '0' ,
    `realname` TEXT NOT NULL ,
    `telephone` TEXT NULL ,
    `email` TEXT NULL
) ENGINE = InnoDB DEFAULT CHARSET=utf8;


text:
turning words into their syllables

```javascript
var nlp = require('nlp_compromise');
var nlpSyllables = require('nlp-syllables');

nlp.plugin(nlpSyllables);
var t2 = nlp.term('houston texas');
t2.syllables();
//[ [ 'hous', 'ton' ], [ 'tex', 'as' ] ]
```


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CMS.Membership;
using CMS.Newsletters;
using Kentico.Membership;

namespace DancingGoat.Helpers.Extensions
{
    public static class UserExtensions
    {
        /// <summary>
        /// Creates a <see cref="SubscriberInfo"/> object and fills its properties from the specified user object.
        /// </summary>
        /// <param name="user">Source user.</param>
        /// <param name="siteId">Identifier of the subscriber's site.</param>
        /// <returns>Instance of the <see cref="SubscriberInfo"/> class initialized from <paramref name="user"/>.</returns>
        public static SubscriberInfo ToSubscriberInfo(this User user, int siteId)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            var subscriber = new SubscriberInfo
            {
                SubscriberEmail = user.Email,
                SubscriberFirstName = user.FirstName,
                SubscriberLastName = user.LastName,
                SubscriberFullName = user.FirstName + " " + user.LastName,
                SubscriberType = UserInfo.OBJECT_TYPE,
                SubscriberRelatedID = user.Id,
                SubscriberSiteID = siteId
            };

            return subscriber;
        }
    }
}


text:
package org.apache.hadoop.hdfs.server.namenode;

import io.hops.metadata.hdfs.entity.ProjectedINode;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

public class FSSTOHelper {
  public static final Log LOG = LogFactory.getLog(FSSTOHelper.class);

  public static void applyAllPendingQuotaInSubTree(final FSNamesystem fsn,
                                                   final AbstractFileTree.FileTree fileTree) throws IOException {
    for (int i = fileTree.getHeight(); i > 0; i--) {
      try {
        Collection<ProjectedINode> dirs = fileTree.getDirsByLevel(i);
        List<Long> dirIDs = new ArrayList<>();
        for (ProjectedINode dir : dirs) {
          dirIDs.add(dir.getId());
        }

        Iterator<Long> itr = dirIDs.iterator();
        synchronized (itr) {
          fsn.getQuotaUpdateManager().addPrioritizedUpdates(itr);
          itr.wait();
        }

      } catch (InterruptedException e) {
        throw new IOException("Operation failed due to an Interrupt");
      }
    }
  }

  public static void applyAllPendingQuotaForDirectory(final FSNamesystem fsn,
                                                      final long inodeID) throws IOException {
    try {
      List<Long> dstInode = new ArrayList<>();
      dstInode.add(inodeID);
      Iterator<Long> itr = dstInode.iterator();
      synchronized (itr) {
        fsn.getQuotaUpdateManager().addPrioritizedUpdates(itr);
        itr.wait();
      }

    } catch (InterruptedException e) {
      throw new IOException("Operation failed due to an Interrupt");
    }
  }
}