diff --git a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java
index ae8901e00812caa1106281f3f0cc292df01abf89..511893d71743b7801ef0d022df67eb216a4a0b6c 100644
--- a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java
+++ b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java
@@ -5,6 +5,8 @@
 
 package de.blinkt.openvpn;
 
+import static de.blinkt.openvpn.core.connection.Connection.TransportType.OBFS4;
+import static de.blinkt.openvpn.core.connection.Connection.TransportType.OBFS4_HOP;
 import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_PROFILE;
 import static se.leap.bitmaskclient.base.utils.ConfigHelper.stringEqual;
 
@@ -50,6 +52,7 @@ import java.security.cert.X509Certificate;
 import java.security.interfaces.RSAPrivateKey;
 import java.security.spec.MGF1ParameterSpec;
 import java.security.spec.PSSParameterSpec;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Locale;
@@ -73,10 +76,12 @@ import de.blinkt.openvpn.core.VpnStatus;
 import de.blinkt.openvpn.core.X509Utils;
 import de.blinkt.openvpn.core.connection.Connection;
 import de.blinkt.openvpn.core.connection.ConnectionAdapter;
+import de.blinkt.openvpn.core.connection.Obfs4Connection;
 import se.leap.bitmaskclient.BuildConfig;
 import se.leap.bitmaskclient.R;
 import se.leap.bitmaskclient.base.models.ProviderObservable;
 import se.leap.bitmaskclient.base.utils.PreferenceHelper;
+import se.leap.bitmaskclient.pluggableTransports.models.Obfs4Options;
 
 public class VpnProfile implements Serializable, Cloneable {
     // Note that this class cannot be moved to core where it belongs since
@@ -271,12 +276,21 @@ public class VpnProfile implements Serializable, Cloneable {
             return false;
     }
 
+    @Override
+    public int hashCode() {
+        int result =(mGatewayIp != null ? mGatewayIp.hashCode() : 0);
+        result = 31 * result + Arrays.hashCode(mConnections);
+        result = 31 * result + mTransportType;
+        return result;
+    }
+
     @Override
     public boolean equals(Object obj) {
         if (obj instanceof VpnProfile) {
             VpnProfile vp = (VpnProfile) obj;
             return stringEqual(vp.mGatewayIp, mGatewayIp) &&
-                    vp.mTransportType == mTransportType;
+                    vp.mTransportType == mTransportType &&
+                    Arrays.equals(mConnections, vp.mConnections);
         }
         return false;
     }
@@ -315,6 +329,22 @@ public class VpnProfile implements Serializable, Cloneable {
         return Connection.TransportType.fromInt(mTransportType);
     }
 
+    public @Nullable Obfs4Options getObfs4Options() {
+        Connection.TransportType transportType = getTransportType();
+        if (!(transportType == OBFS4 || transportType == OBFS4_HOP)) {
+            return null;
+        }
+        return ((Obfs4Connection) mConnections[0]).getObfs4Options();
+    }
+
+    public String getObfuscationTransportLayerProtocol() {
+        try {
+            return getObfs4Options().transport.getProtocols()[0];
+        } catch (NullPointerException | ArrayIndexOutOfBoundsException ignore) {
+            return null;
+        }
+    }
+
     public String getName() {
         if (TextUtils.isEmpty(mName))
             return "No profile name";
diff --git a/app/src/main/java/de/blinkt/openvpn/core/connection/Connection.java b/app/src/main/java/de/blinkt/openvpn/core/connection/Connection.java
index 0b28cbca8c50a82906b1fe989c040f5bbe8f174c..9943faff8badc176f1b8729f9148e30054b0b422 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/connection/Connection.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/connection/Connection.java
@@ -9,10 +9,13 @@ import static de.blinkt.openvpn.core.connection.Connection.TransportType.*;
 
 import android.text.TextUtils;
 
+import androidx.annotation.NonNull;
+
 import com.google.gson.annotations.JsonAdapter;
 
 import java.io.Serializable;
 import java.util.Locale;
+import java.util.Objects;
 
 @JsonAdapter(ConnectionAdapter.class)
 public abstract class Connection implements Serializable, Cloneable {
@@ -301,5 +304,54 @@ public abstract class Connection implements Serializable, Cloneable {
         this.mProxyAuthPassword = proxyAuthPassword;
     }
 
-    public abstract TransportType getTransportType();
+    public abstract @NonNull TransportType getTransportType();
+
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof Connection that)) return false;
+
+        if (mUseUdp != that.mUseUdp) return false;
+        if (mUseCustomConfig != that.mUseCustomConfig) return false;
+        if (mEnabled != that.mEnabled) return false;
+        if (mConnectTimeout != that.mConnectTimeout) return false;
+        if (mUseProxyAuth != that.mUseProxyAuth) return false;
+        if (!Objects.equals(mServerName, that.mServerName))
+            return false;
+        if (!Objects.equals(mServerPort, that.mServerPort))
+            return false;
+        if (!Objects.equals(mCustomConfiguration, that.mCustomConfiguration))
+            return false;
+        if (mProxyType != that.mProxyType) return false;
+        if (!Objects.equals(mProxyName, that.mProxyName))
+            return false;
+        if (!Objects.equals(mProxyPort, that.mProxyPort))
+            return false;
+        if (!Objects.equals(mProxyAuthUser, that.mProxyAuthUser))
+            return false;
+        if (getTransportType() != that.getTransportType()) {
+            return false;
+        }
+        return Objects.equals(mProxyAuthPassword, that.mProxyAuthPassword);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = mServerName != null ? mServerName.hashCode() : 0;
+        result = 31 * result + (mServerPort != null ? mServerPort.hashCode() : 0);
+        result = 31 * result + (mUseUdp ? 1 : 0);
+        result = 31 * result + (mCustomConfiguration != null ? mCustomConfiguration.hashCode() : 0);
+        result = 31 * result + (mUseCustomConfig ? 1 : 0);
+        result = 31 * result + (mEnabled ? 1 : 0);
+        result = 31 * result + mConnectTimeout;
+        result = 31 * result + (mProxyType != null ? mProxyType.hashCode() : 0);
+        result = 31 * result + (mProxyName != null ? mProxyName.hashCode() : 0);
+        result = 31 * result + (mProxyPort != null ? mProxyPort.hashCode() : 0);
+        result = 31 * result + (mUseProxyAuth ? 1 : 0);
+        result = 31 * result + (mProxyAuthUser != null ? mProxyAuthUser.hashCode() : 0);
+        result = 31 * result + (mProxyAuthPassword != null ? mProxyAuthPassword.hashCode() : 0);
+        result = 31 * result + getTransportType().toInt();
+        return result;
+    }
 }
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
index ed61ca13097a4eaa4cf26eb49d01eb2b45c52c89..429353414a40bc37092cf78d6c44a8e442409722 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
@@ -33,9 +33,7 @@ import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_STOP_BLOCKI
 import static se.leap.bitmaskclient.base.models.Constants.EIP_EARLY_ROUTES;
 import static se.leap.bitmaskclient.base.models.Constants.EIP_N_CLOSEST_GATEWAY;
 import static se.leap.bitmaskclient.base.models.Constants.EIP_RECEIVER;
-import static se.leap.bitmaskclient.base.models.Constants.EIP_RESTART_ON_BOOT;
 import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_PROFILE;
-import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_VPN_CERTIFICATE;
 import static se.leap.bitmaskclient.base.utils.ConfigHelper.ensureNotOnMainThread;
 import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getPreferredCity;
 import static se.leap.bitmaskclient.eip.EIP.EIPErrors.ERROR_INVALID_PROFILE;
@@ -71,8 +69,6 @@ import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.io.Closeable;
 import java.lang.ref.WeakReference;
-import java.util.Observable;
-import java.util.Observer;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
 
@@ -87,7 +83,6 @@ import se.leap.bitmaskclient.base.OnBootReceiver;
 import se.leap.bitmaskclient.base.models.Provider;
 import se.leap.bitmaskclient.base.models.ProviderObservable;
 import se.leap.bitmaskclient.base.utils.PreferenceHelper;
-import se.leap.bitmaskclient.eip.GatewaysManager.GatewayOptions;
 
 /**
  * EIP is the abstract base class for interacting with and managing the Encrypted
@@ -251,8 +246,8 @@ public final class EIP extends JobIntentService implements PropertyChangeListene
             return;
         }
 
-        GatewayOptions gatewayOptions = gatewaysManager.select(nClosestGateway);
-        launchActiveGateway(gatewayOptions, nClosestGateway, result);
+        VpnProfile gatewayOptions = gatewaysManager.selectVpnProfile(nClosestGateway);
+        launchProfile(gatewayOptions, nClosestGateway, result);
         if (result.containsKey(BROADCAST_RESULT_KEY) && !result.getBoolean(BROADCAST_RESULT_KEY)) {
             tellToReceiverOrBroadcast(this, EIP_ACTION_START, RESULT_CANCELED, result);
         } else {
@@ -266,7 +261,7 @@ public final class EIP extends JobIntentService implements PropertyChangeListene
      */
     private void startEIPAlwaysOnVpn() {
         GatewaysManager gatewaysManager = new GatewaysManager(getApplicationContext());
-        GatewayOptions gatewayOptions = gatewaysManager.select(0);
+        VpnProfile vpnProfile = gatewaysManager.selectVpnProfile(0);
         Bundle result = new Bundle();
 
         if (shouldUpdateVPNCertificate()) {
@@ -274,8 +269,7 @@ public final class EIP extends JobIntentService implements PropertyChangeListene
             p.setShouldUpdateVpnCertificate(true);
             ProviderObservable.getInstance().updateProvider(p);
         }
-
-        launchActiveGateway(gatewayOptions, 0, result);
+        launchProfile(vpnProfile, 0, result);
         if (result.containsKey(BROADCAST_RESULT_KEY) && !result.getBoolean(BROADCAST_RESULT_KEY)){
             VpnStatus.logWarning("ALWAYS-ON VPN: " + getString(R.string.no_vpn_profiles_defined));
         }
@@ -317,15 +311,15 @@ public final class EIP extends JobIntentService implements PropertyChangeListene
     }
 
     /**
-     * starts the VPN and connects to the given gateway
+     * starts the VPN and connects to the given Gateway the VpnProfile belongs to
      *
-     * @param gatewayOptions GatewayOptions model containing a Gateway and the associated transport used to connect
+     * @param profile VpnProfile which contains all information to setup a OpenVPN connection
+     *                   and optionally obfsvpn
+     * @param nClosestGateway gateway index, indicating the distance to the user
+     * @param result Bundle containing possible error messages shown to the user
      */
-    private void launchActiveGateway(@Nullable GatewayOptions gatewayOptions, int nClosestGateway, Bundle result) {
-        VpnProfile profile;
-
-        if (gatewayOptions == null || gatewayOptions.gateway == null ||
-                (profile = gatewayOptions.gateway.getProfile(gatewayOptions.transportType)) == null) {
+    private void launchProfile(@Nullable VpnProfile profile, int nClosestGateway, Bundle result) {
+        if (profile == null) {
             String preferredLocation = getPreferredCity();
             if (preferredLocation != null) {
                 setErrorResult(result, NO_MORE_GATEWAYS.toString(), getStringResourceForNoMoreGateways(), getString(R.string.app_name), preferredLocation);
@@ -379,7 +373,6 @@ public final class EIP extends JobIntentService implements PropertyChangeListene
         }
     }
 
-
     /**
      * Stop VPN
      * First checks if the OpenVpnConnection is open then
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java b/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java
index d2592cd7654cf30503dbbeae556db3fe6a6767c9..16c9285516d77d47ee467b61b23dcc27f5e01e6a 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java
@@ -38,6 +38,7 @@ import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getPreferUDP;
 import static se.leap.bitmaskclient.base.utils.PreferenceHelper.useObfuscationPinning;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 
 import com.google.gson.Gson;
 
@@ -45,8 +46,9 @@ import org.json.JSONException;
 import org.json.JSONObject;
 
 import java.io.IOException;
-import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Set;
+import java.util.Vector;
 
 import de.blinkt.openvpn.VpnProfile;
 import de.blinkt.openvpn.core.ConfigParser;
@@ -75,10 +77,7 @@ public class Gateway {
     private String name;
     private int timezone;
     private int apiVersion;
-    /** FIXME: We expect here that not more than one obfs4 transport is offered by a gateway, however
-     * it's possible to setup gateways that have obfs4 over kcp and tcp which result in different VpnProfiles each
-     */
-    private HashMap<Connection.TransportType, VpnProfile> vpnProfiles;
+    private Vector<VpnProfile> vpnProfiles;
 
     /**
      * Build a gateway object from a JSON OpenVPN gateway definition in eip-service.json
@@ -190,10 +189,10 @@ public class Gateway {
     /**
      * Create and attach the VpnProfile to our gateway object
      */
-    private @NonNull HashMap<Connection.TransportType, VpnProfile> createVPNProfiles(VpnConfigGenerator.Configuration profileConfig)
+    private @NonNull Vector<VpnProfile> createVPNProfiles(VpnConfigGenerator.Configuration profileConfig)
             throws ConfigParser.ConfigParseError, IOException, JSONException {
         VpnConfigGenerator vpnConfigurationGenerator = new VpnConfigGenerator(generalConfiguration, secrets, gateway, profileConfig);
-        HashMap<Connection.TransportType, VpnProfile> profiles = vpnConfigurationGenerator.generateVpnProfiles();
+        Vector<VpnProfile> profiles = vpnConfigurationGenerator.generateVpnProfiles();
         return profiles;
     }
 
@@ -201,28 +200,68 @@ public class Gateway {
         return name;
     }
 
-    public HashMap<Connection.TransportType, VpnProfile> getProfiles() {
+    public Vector<VpnProfile> getProfiles() {
         return vpnProfiles;
     }
 
-    public VpnProfile getProfile(Connection.TransportType transportType) {
-        return vpnProfiles.get(transportType);
+    /**
+     * Returns a VpnProfile that supports a given transport type and any of the given transport
+     * layer protocols (e.g. TCP, KCP). If multiple VpnProfiles fulfill these requirements, a random
+     * profile will be chosen. This can currently only occur for obfuscation protocols.
+     * @param transportType transport type, e.g. openvpn or obfs4
+     * @param obfuscationTransportLayerProtocols Vector of transport layer protocols PTs can be based on
+     * @return
+     */
+    public @Nullable VpnProfile getProfile(Connection.TransportType transportType, @Nullable Set<String> obfuscationTransportLayerProtocols) {
+        Vector<VpnProfile> results = new Vector<>();
+        for (VpnProfile vpnProfile : vpnProfiles) {
+            if (vpnProfile.getTransportType() == transportType) {
+                if (!vpnProfile.usePluggableTransports() ||
+                        obfuscationTransportLayerProtocols == null ||
+                        obfuscationTransportLayerProtocols.contains(vpnProfile.getObfuscationTransportLayerProtocol())) {
+                    results.add(vpnProfile);
+                }
+            }
+        }
+        if (results.size() == 0) {
+            return null;
+        }
+        int randomIndex = (int) (Math.random() * (results.size()));
+        return results.get(randomIndex);
     }
 
-    public boolean supportsTransport(Connection.TransportType transportType) {
+    public boolean hasProfile(VpnProfile profile) {
+        return vpnProfiles.contains(profile);
+    }
+
+    /**
+     * Checks if a transport type is supported by the gateway.
+     * In case the transport type is an obfuscation transport, you can pass a Vector of required transport layer protocols.
+     * This way you can filter for TCP based obfs4 traffic versus KCP based obfs4 traffic.
+     * @param transportType transport type, e.g. openvpn or obfs4
+     * @param obfuscationTransportLayerProtocols filters for _any_ of these transport layer protocols (e.g. TCP or KCP) of a given obfuscation transportType, can be omitted if transportType is OPENVPN.
+     *
+     * @return
+     */
+    public boolean supportsTransport(Connection.TransportType transportType, @Nullable Set<String> obfuscationTransportLayerProtocols) {
         if (transportType == PT) {
             return supportsPluggableTransports();
         }
-        return vpnProfiles.get(transportType) != null;
+        return getProfile(transportType, obfuscationTransportLayerProtocols) != null;
     }
 
     public HashSet<Connection.TransportType> getSupportedTransports() {
-        return new HashSet<>(vpnProfiles.keySet());
+        HashSet<Connection.TransportType> transportTypes = new HashSet<>();
+        for (VpnProfile p : vpnProfiles) {
+            transportTypes.add(p.getTransportType());
+        }
+        return transportTypes;
     }
 
     public boolean supportsPluggableTransports() {
-        for (Connection.TransportType transportType : vpnProfiles.keySet()) {
-            if (transportType.isPluggableTransport() && vpnProfiles.get(transportType) != null) {
+        for (VpnProfile profile : vpnProfiles) {
+            Connection.TransportType transportType = profile.getTransportType();
+            if (transportType.isPluggableTransport()) {
                 return true;
             }
         }
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java
index 9b4d431c469b77b81dae4b2e29a03990efbf2d35..cd85f4195774dd015a93b04071fd3909a1bc6739 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java
@@ -22,8 +22,10 @@ import static de.blinkt.openvpn.core.connection.Connection.TransportType.OPENVPN
 import static de.blinkt.openvpn.core.connection.Connection.TransportType.PT;
 import static se.leap.bitmaskclient.base.models.Constants.GATEWAYS;
 import static se.leap.bitmaskclient.base.models.Constants.HOST;
+import static se.leap.bitmaskclient.base.models.Constants.KCP;
 import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_VPN_CERTIFICATE;
 import static se.leap.bitmaskclient.base.models.Constants.SORTED_GATEWAYS;
+import static se.leap.bitmaskclient.base.models.Constants.TCP;
 import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningCert;
 import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningIP;
 import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningKCP;
@@ -46,10 +48,13 @@ import org.json.JSONObject;
 import java.io.IOException;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Set;
 
 import de.blinkt.openvpn.VpnProfile;
 import de.blinkt.openvpn.core.ConfigParser;
@@ -101,16 +106,6 @@ public class GatewaysManager {
         }
     }
 
-    public static class GatewayOptions {
-        public Gateway gateway;
-        public TransportType transportType;
-
-        public GatewayOptions(Gateway gateway, TransportType transportType) {
-            this.gateway = gateway;
-            this.transportType = transportType;
-        }
-    }
-
     private static final String TAG = GatewaysManager.class.getSimpleName();
     public static final String PINNED_OBFUSCATION_PROXY = "pinned.obfuscation.proxy";
 
@@ -130,12 +125,12 @@ public class GatewaysManager {
     }
 
     /**
-     * select closest Gateway
-      * @return the n closest Gateway
+     * selects a VpnProfile of the n closest Gateway or a pinned gateway
+     * @return VpnProfile of the n closest Gateway or null if no remaining VpnProfiles available
      */
-    public GatewayOptions select(int nClosest) {
+    public @Nullable VpnProfile selectVpnProfile(int nClosestGateway) {
         if (PreferenceHelper.useObfuscationPinning()) {
-            if (nClosest > 2) {
+            if (nClosestGateway > 2) {
                 // no need to try again the pinned proxy, probably configuration error
                 return null;
             }
@@ -143,19 +138,35 @@ public class GatewaysManager {
             if (gateway == null) {
                 return null;
             }
-            return new GatewayOptions(gateway, OBFS4);
+            return gateway.getProfile(OBFS4, null);
         }
         String selectedCity = getPreferredCity();
-        return select(nClosest, selectedCity);
+        return selectVpnProfile(nClosestGateway, selectedCity);
     }
 
-    public GatewayOptions select(int nClosest, String city) {
+    /**
+     * Selects a VPN profile, filtered by distance to the user, transportType and
+     * optionally by city and transport layer protocol
+     * @param nClosestGateway
+     * @param city location filter
+     * @return VpnProfile of the n closest Gateway or null if no remaining VpnProfiles available
+     */
+    public @Nullable VpnProfile selectVpnProfile(int nClosestGateway, String city) {
         TransportType[] transportTypes = getUseBridges() ? new TransportType[]{OBFS4, OBFS4_HOP} : new TransportType[]{OPENVPN};
+        Set<String> obfuscationTransportLayerProtocols = getObfuscationTransportLayerProtocols();
         if (presortedList.size() > 0) {
-            return getGatewayFromPresortedList(nClosest, transportTypes, city);
+            return getVpnProfileFromPresortedList(nClosestGateway, transportTypes, obfuscationTransportLayerProtocols, city);
         }
 
-        return getGatewayFromTimezoneCalculation(nClosest, transportTypes, city);
+        return getVpnProfileFromTimezoneCalculation(nClosestGateway, transportTypes, obfuscationTransportLayerProtocols, city);
+    }
+    @Nullable
+    private static Set<String> getObfuscationTransportLayerProtocols() {
+        Set<String> obfuscationTransportLayerProtocols = null;
+        if (getUseBridges()) {
+            obfuscationTransportLayerProtocols = new HashSet<>(Arrays.asList(TCP, KCP));
+        }
+        return obfuscationTransportLayerProtocols;
     }
 
     public void updateTransport(TransportType transportType) {
@@ -239,7 +250,7 @@ public class GatewaysManager {
     }
 
     private void updateLocation(Location location, Gateway gateway, Connection.TransportType transportType) {
-        if (gateway.supportsTransport(transportType)) {
+        if (gateway.supportsTransport(transportType, null)) {
             double averageLoad = location.getAverageLoad(transportType);
             int numberOfGateways = location.getNumberOfGateways(transportType);
             averageLoad = (numberOfGateways * averageLoad + gateway.getFullness()) / (numberOfGateways + 1);
@@ -277,7 +288,7 @@ public class GatewaysManager {
         return Load.getLoadByValue(location.getAverageLoad(transportType));
     }
 
-    private GatewayOptions getGatewayFromTimezoneCalculation(int nClosest, TransportType[] transportTypes, @Nullable String city) {
+    private VpnProfile getVpnProfileFromTimezoneCalculation(int nClosest, TransportType[] transportTypes, @Nullable Set<String> protocols, @Nullable String city) {
         List<Gateway> list = new ArrayList<>(gateways.values());
         if (gatewaySelector == null) {
             gatewaySelector = new GatewaySelector(list);
@@ -287,10 +298,10 @@ public class GatewaysManager {
         int i = 0;
         while ((gateway = gatewaySelector.select(i)) != null) {
             for (TransportType transportType : transportTypes) {
-                if ((city == null && gateway.supportsTransport(transportType)) ||
-                        (gateway.getName().equals(city) && gateway.supportsTransport(transportType))) {
+                if ((city == null && gateway.supportsTransport(transportType, protocols)) ||
+                        (gateway.getName().equals(city) && gateway.supportsTransport(transportType, protocols))) {
                     if (found == nClosest) {
-                        return new GatewayOptions(gateway, transportType);
+                        return gateway.getProfile(transportType, protocols);
                     }
                     found++;
                 }
@@ -300,19 +311,18 @@ public class GatewaysManager {
         return null;
     }
 
-    private GatewayOptions getGatewayFromPresortedList(int nClosest, TransportType[] transportTypes, @Nullable String city) {
+    private VpnProfile getVpnProfileFromPresortedList(int nClosest, TransportType[] transportTypes, @Nullable Set<String> protocols, @Nullable String city) {
         int found = 0;
         for (Gateway gateway : presortedList) {
             for (TransportType transportType : transportTypes) {
-                if ((city == null && gateway.supportsTransport(transportType)) ||
-                        (gateway.getName().equals(city) && gateway.supportsTransport(transportType))) {
+                if ((city == null && gateway.supportsTransport(transportType, protocols)) ||
+                        (gateway.getName().equals(city) && gateway.supportsTransport(transportType, protocols))) {
                     if (found == nClosest) {
-                        return new GatewayOptions(gateway, transportType);
+                        return gateway.getProfile(transportType, protocols);
                     }
                     found++;
                 }
             }
-
         }
         return null;
     }
@@ -331,35 +341,28 @@ public class GatewaysManager {
     }
     
     private int getPositionFromPresortedList(VpnProfile profile) {
-        TransportType transportType = profile.getTransportType();
-        int nClosest = 0;
+        int nClosestGateway = 0;
         for (Gateway gateway : presortedList) {
-            if (gateway.supportsTransport(transportType)) {
-                if (profile.equals(gateway.getProfile(transportType))) {
-                    return nClosest;
-                }
-                nClosest++;
+            if (gateway.hasProfile(profile)) {
+                return nClosestGateway;
             }
+            nClosestGateway++;
         }
         return -1;
     }
 
     private int getPositionFromTimezoneCalculatedList(VpnProfile profile) {
-        TransportType transportType = profile.getTransportType();
         if (gatewaySelector == null) {
             gatewaySelector = new GatewaySelector(new ArrayList<>(gateways.values()));
         }
         Gateway gateway;
-        int nClosest = 0;
+        int nClosestGateway = 0;
         int i = 0;
-        while ((gateway = gatewaySelector.select(i)) != null) {
-            if (gateway.supportsTransport(transportType)) {
-                if (profile.equals(gateway.getProfile(transportType))) {
-                    return nClosest;
-                }
-                nClosest++;
+        while ((gateway = gatewaySelector.select(nClosestGateway)) != null) {
+            if (gateway.hasProfile(profile)) {
+                return nClosestGateway;
             }
-            i++;
+            nClosestGateway++;
         }
         return -1;
     }
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java
index 8cbc428905284cb814986e8e9ff22cefd9e64dcd..5defa7e67d95eac69bb60afabc1d7e2e19847a96 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java
@@ -31,6 +31,7 @@ import static se.leap.bitmaskclient.base.models.Constants.TCP;
 import static se.leap.bitmaskclient.base.models.Constants.TRANSPORT;
 import static se.leap.bitmaskclient.base.models.Constants.UDP;
 
+import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
 import org.json.JSONArray;
@@ -39,17 +40,15 @@ import org.json.JSONObject;
 
 import java.io.IOException;
 import java.io.StringReader;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
+import java.util.Vector;
 
 import de.blinkt.openvpn.VpnProfile;
 import de.blinkt.openvpn.core.ConfigParser;
 import de.blinkt.openvpn.core.VpnStatus;
-import de.blinkt.openvpn.core.connection.Connection;
 import de.blinkt.openvpn.core.connection.Connection.TransportType;
-import de.blinkt.openvpn.core.connection.Obfs4Connection;
 import se.leap.bitmaskclient.base.models.Provider;
 import se.leap.bitmaskclient.base.models.Transport;
 import se.leap.bitmaskclient.base.utils.ConfigHelper;
@@ -60,7 +59,7 @@ public class VpnConfigGenerator {
     private final JSONObject generalConfiguration;
     private final JSONObject gateway;
     private final JSONObject secrets;
-    HashMap<TransportType, Transport> transports = new HashMap<>();
+    Vector<Transport> transports = new Vector<>();
     private final int apiVersion;
     private final boolean preferUDP;
     private final boolean experimentalTransports;
@@ -116,7 +115,7 @@ public class VpnConfigGenerator {
                 JSONArray supportedTransports = gateway.getJSONObject(CAPABILITIES).getJSONArray(TRANSPORT);
                 for (int i = 0; i < supportedTransports.length(); i++) {
                     Transport transport = Transport.fromJson(supportedTransports.getJSONObject(i));
-                    transports.put(transport.getTransportType(), transport);
+                    transports.add(transport);
                 }
             }
         } catch (Exception e) {
@@ -124,32 +123,34 @@ public class VpnConfigGenerator {
         }
     }
 
-    public HashMap<TransportType, VpnProfile> generateVpnProfiles() throws
+    public Vector<VpnProfile> generateVpnProfiles() throws
             ConfigParser.ConfigParseError,
             NumberFormatException {
-        HashMap<Connection.TransportType, VpnProfile> profiles = new HashMap<>();
-        if (supportsOpenvpn()) {
-            try {
-                profiles.put(OPENVPN, createProfile(OPENVPN));
-            } catch (ConfigParser.ConfigParseError | NumberFormatException | JSONException | IOException e) {
-                e.printStackTrace();
-            }
-        }
+        Vector<VpnProfile> profiles = new Vector<>();
+
         if (apiVersion >= 3) {
-            for (TransportType transportType : transports.keySet()) {
-                Transport transport = transports.get(transportType);
-                if (transportType.isPluggableTransport()) {
+            for (Transport transport : transports){
+                if (transport.getTransportType().isPluggableTransport()) {
                     Transport.Options transportOptions = transport.getOptions();
                     if (!experimentalTransports && transportOptions != null && transportOptions.isExperimental()) {
                         continue;
                     }
-                    try {
-                        profiles.put(transportType, createProfile(transportType));
-                    } catch (ConfigParser.ConfigParseError | NumberFormatException | JSONException | IOException e) {
-                        e.printStackTrace();
-                    }
+                } else if (transport.getTransportType() == OPENVPN && useObfuscationPinning) {
+                    continue;
+                }
+                try {
+                    profiles.add(createProfile(transport));
+                } catch (ConfigParser.ConfigParseError | NumberFormatException | JSONException | IOException e) {
+                    e.printStackTrace();
                 }
             }
+        } else if (supportsOpenvpn()) {
+            // API v1 - TODO: let's remove support for API v1 soon
+            try {
+                profiles.add(createApiv1OpenvpnProfile());
+            } catch (ConfigParser.ConfigParseError | NumberFormatException | JSONException | IOException e) {
+                e.printStackTrace();
+            }
         }
         if (profiles.isEmpty()) {
             throw new ConfigParser.ConfigParseError("No supported transports detected.");
@@ -159,14 +160,14 @@ public class VpnConfigGenerator {
 
     private boolean supportsOpenvpn() {
         return !useObfuscationPinning &&
-                ((apiVersion >= 3 && transports.containsKey(OPENVPN)) ||
-                        (apiVersion < 3 && !gatewayConfiguration(OPENVPN).isEmpty()));
+                ((apiVersion >= 3 && getTransport(OPENVPN) != null) ||
+                        (apiVersion < 3 && !gatewayConfiguration(null).isEmpty()));
     }
 
-    private String getConfigurationString(TransportType transportType) {
+    private String getConfigurationString(Transport transport) {
         return generalConfiguration()
                 + newLine
-                + gatewayConfiguration(transportType)
+                + gatewayConfiguration(transport)
                 + newLine
                 + androidCustomizations()
                 + newLine
@@ -174,12 +175,13 @@ public class VpnConfigGenerator {
     }
 
     @VisibleForTesting
-    protected VpnProfile createProfile(TransportType transportType) throws IOException, ConfigParser.ConfigParseError, JSONException {
-        String configuration = getConfigurationString(transportType);
+    protected VpnProfile createProfile(Transport transport) throws IOException, ConfigParser.ConfigParseError, JSONException {
+        TransportType transportType = transport.getTransportType();
+        String configuration = getConfigurationString(transport);
         ConfigParser icsOpenvpnConfigParser = new ConfigParser();
         icsOpenvpnConfigParser.parseConfig(new StringReader(configuration));
         if (transportType == OBFS4 || transportType == OBFS4_HOP) {
-            icsOpenvpnConfigParser.setObfs4Options(getObfs4Options(transportType));
+            icsOpenvpnConfigParser.setObfs4Options(getObfs4Options(transport));
         }
 
         VpnProfile profile = icsOpenvpnConfigParser.convertProfile(transportType);
@@ -191,17 +193,29 @@ public class VpnConfigGenerator {
         return profile;
     }
 
-    private Obfs4Options getObfs4Options(TransportType transportType) throws JSONException {
+    @VisibleForTesting
+    protected VpnProfile createApiv1OpenvpnProfile() throws IOException, ConfigParser.ConfigParseError, JSONException {
+        String configuration = getConfigurationString(null);
+        ConfigParser icsOpenvpnConfigParser = new ConfigParser();
+        icsOpenvpnConfigParser.parseConfig(new StringReader(configuration));
+
+        VpnProfile profile = icsOpenvpnConfigParser.convertProfile(OPENVPN);
+        profile.mName = profileName;
+        profile.mGatewayIp = remoteGatewayIP;
+        if (excludedApps != null) {
+            profile.mAllowedAppsVpn = new HashSet<>(excludedApps);
+        }
+        return profile;
+    }
+
+    private Obfs4Options getObfs4Options(Transport transport) throws JSONException {
         String ip = gateway.getString(IP_ADDRESS);
-        Transport transport;
         if (useObfuscationPinning) {
             transport = new Transport(OBFS4.toString(),
                     new String[]{obfuscationPinningKCP ? KCP : TCP},
                     new String[]{obfuscationPinningPort},
                     obfuscationPinningCert);
             ip = obfuscationPinningIP;
-        } else {
-            transport = transports.get(transportType);
         }
         return new Obfs4Options(ip, transport);
     }
@@ -229,7 +243,7 @@ public class VpnConfigGenerator {
         return commonOptions;
     }
 
-    private String gatewayConfiguration(TransportType transportType) {
+    private String gatewayConfiguration(@Nullable Transport transport) {
         String configs = "";
 
         StringBuilder stringBuilder = new StringBuilder();
@@ -250,11 +264,13 @@ public class VpnConfigGenerator {
                     String[] ipAddresses = ipAddress6.isEmpty()  ?
                             new String[]{ipAddress} :
                             new String[]{ipAddress6, ipAddress};
-
-                    gatewayConfigMinApiv3(transportType, stringBuilder, ipAddresses);
+                    if (transport == null) {
+                        throw new NullPointerException("Transport is not allowed to be null in APIv3+");
+                    }
+                    gatewayConfigMinApiv3(transport, stringBuilder, ipAddresses);
                     break;
             }
-        } catch (JSONException e) {
+        } catch (JSONException | NullPointerException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
@@ -267,12 +283,21 @@ public class VpnConfigGenerator {
         return configs;
     }
 
-    private void gatewayConfigMinApiv3(TransportType transportType, StringBuilder stringBuilder, String[] ipAddresses) throws JSONException {
-        if (transportType.isPluggableTransport()) {
-            ptGatewayConfigMinApiv3(stringBuilder, ipAddresses, transports.get(transportType));
+    private void gatewayConfigMinApiv3(Transport transport, StringBuilder stringBuilder, String[] ipAddresses) throws JSONException {
+        if (transport.getTransportType().isPluggableTransport()) {
+            ptGatewayConfigMinApiv3(stringBuilder, ipAddresses, transport);
         } else {
-            ovpnGatewayConfigMinApi3(stringBuilder, ipAddresses, transports.get(OPENVPN));
+            ovpnGatewayConfigMinApi3(stringBuilder, ipAddresses, transport);
+        }
+    }
+
+    private @Nullable Transport getTransport(TransportType transportType) {
+        for (Transport transport : transports) {
+            if (transport.getTransportType() == transportType) {
+                return transport;
+            }
         }
+        return null;
     }
 
     private void gatewayConfigApiv1(StringBuilder stringBuilder, String ipAddress, JSONObject capabilities) throws JSONException {
@@ -290,8 +315,8 @@ public class VpnConfigGenerator {
         }
     }
 
-    private void ovpnGatewayConfigMinApi3(StringBuilder stringBuilder, String[] ipAddresses, Transport transport) {
-        if (transport.getProtocols() == null || transport.getPorts() == null) {
+    private void ovpnGatewayConfigMinApi3(StringBuilder stringBuilder, String[] ipAddresses, @Nullable Transport transport) {
+        if (transport == null || transport.getProtocols() == null || transport.getPorts() == null) {
             VpnStatus.logError("Misconfigured provider: missing details for transport openvpn on gateway " + ipAddresses[0]);
             return;
         }
@@ -426,7 +451,7 @@ public class VpnConfigGenerator {
             // configuration, so we assume yes
             return true;
         }
-        Transport openvpnTransport = transports.get(OPENVPN);
+        Transport openvpnTransport = getTransport(OPENVPN);
         if (openvpnTransport == null) {
             // the bridge seems to be to be decoupled from the gateway, we can't say if the openvpn gateway
             // will support this PT and hope the admins configured the gateway correctly
@@ -455,6 +480,8 @@ public class VpnConfigGenerator {
         for (String protocol : ptProtocols) {
             if (isAllowedProtocol(transport.getTransportType(), protocol)) {
                 return true;
+            } else {
+                VpnStatus.logError("Provider - client incompatibility: " + protocol + " is not an allowed transport layer protocol for " + transport.getType());
             }
         }
 
diff --git a/app/src/test/java/se/leap/bitmaskclient/eip/GatewayTest.java b/app/src/test/java/se/leap/bitmaskclient/eip/GatewayTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..66c139b2686c852b8c88a268fa681ec66fd8fb75
--- /dev/null
+++ b/app/src/test/java/se/leap/bitmaskclient/eip/GatewayTest.java
@@ -0,0 +1,154 @@
+package se.leap.bitmaskclient.eip;
+
+import static org.junit.Assert.*;
+
+import static se.leap.bitmaskclient.base.models.Constants.GATEWAYS;
+import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_PRIVATE_KEY;
+import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_VPN_CERTIFICATE;
+import static se.leap.bitmaskclient.base.models.Provider.CA_CERT;
+import static se.leap.bitmaskclient.testutils.TestSetupHelper.getProvider;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+import androidx.annotation.Nullable;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Answers;
+import org.mockito.Mock;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+
+import de.blinkt.openvpn.VpnProfile;
+import de.blinkt.openvpn.core.ConfigParser;
+import de.blinkt.openvpn.core.connection.Connection;
+import de.blinkt.openvpn.core.connection.Obfs4Connection;
+import se.leap.bitmaskclient.base.models.Provider;
+import se.leap.bitmaskclient.base.models.ProviderObservable;
+import se.leap.bitmaskclient.base.utils.PreferenceHelper;
+import se.leap.bitmaskclient.base.utils.TimezoneHelper;
+import se.leap.bitmaskclient.testutils.MockSharedPreferences;
+import se.leap.bitmaskclient.testutils.TestSetupHelper;
+
+public class GatewayTest {
+
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private Context mockContext;
+
+    private SharedPreferences sharedPreferences;
+
+    @Before
+    public void setUp() throws IOException, JSONException {
+        sharedPreferences = new MockSharedPreferences();
+
+        PreferenceHelper preferenceHelper = new PreferenceHelper(sharedPreferences);
+    }
+
+
+    private Gateway createGatewayFromProvider(int nClosest, @Nullable String eipServiceJsonPath) throws ConfigParser.ConfigParseError, JSONException, IOException {
+        Provider provider = getProvider(null, null, null, null, null, null, eipServiceJsonPath, null);
+        JSONObject eipServiceJson = provider.getEipServiceJson();
+
+        JSONObject gatewayJson = eipServiceJson.getJSONArray(GATEWAYS).getJSONObject(0);
+        JSONObject secrets = new JSONObject();
+        try {
+            secrets.put(Provider.CA_CERT, provider.getCaCert());
+            secrets.put(PROVIDER_VPN_CERTIFICATE, provider.getVpnCertificate());
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+
+
+        return new Gateway(eipServiceJson, secrets, gatewayJson);
+    }
+    @Test
+    public void testGetProfile_OpenVPN_obfuscationProtocols_ignored_OpenVPNfound() throws ConfigParser.ConfigParseError, JSONException, IOException {
+        Gateway gateway = createGatewayFromProvider(0, "ptdemo_three_mixed_gateways.json");
+        VpnProfile profile = gateway.getProfile(Connection.TransportType.OPENVPN, new HashSet<>(Arrays.asList("invalid")));
+        assertNotNull(profile);
+    }
+
+    @Test
+    public void testGetProfile_obfs4_obfuscationProtocolsTakenIntoAccount_Obfs4Notfound() throws ConfigParser.ConfigParseError, JSONException, IOException {
+        Gateway gateway = createGatewayFromProvider(0, "ptdemo_three_mixed_gateways.json");
+        VpnProfile profile = gateway.getProfile(Connection.TransportType.OBFS4, new HashSet<>(Arrays.asList("invalid")));
+        assertNull(profile);
+    }
+
+    @Test
+    public void testGetProfile_obfs4_obfuscationProtocolsTakenIntoAccount_Obfs4found() throws ConfigParser.ConfigParseError, JSONException, IOException {
+        Gateway gateway = createGatewayFromProvider(0, "ptdemo_three_mixed_gateways.json");
+        VpnProfile profile = gateway.getProfile(Connection.TransportType.OBFS4, new HashSet<>(Arrays.asList("tcp")));
+        assertNotNull(profile);
+    }
+
+    @Test
+    public void testGetProfile_obfs4_obfuscationProtocolsTakenIntoAccount_Obfs4KCPfound() throws ConfigParser.ConfigParseError, JSONException, IOException {
+        Gateway gateway = createGatewayFromProvider(0, "multiple_pts_per_host_eip-service.json");
+        VpnProfile profile = gateway.getProfile(Connection.TransportType.OBFS4, new HashSet<>(Arrays.asList("kcp")));
+        assertNotNull(profile);
+    }
+
+    @Test
+    public void testGetProfile_obfs4_multipleProfiles_randomlySelected() throws ConfigParser.ConfigParseError, JSONException, IOException {
+        Gateway gateway = createGatewayFromProvider(0, "multiple_pts_per_host_eip-service.json");
+        VpnProfile profile1 = gateway.getProfile(Connection.TransportType.OBFS4, new HashSet<>(Arrays.asList("kcp", "tcp")));
+        assertNotNull(profile1);
+        assertEquals(1, profile1.mConnections.length);
+        assertTrue(profile1.mConnections[0] instanceof Obfs4Connection);
+        String[] transportLayerProtocols = ((Obfs4Connection)profile1.mConnections[0]).getObfs4Options().transport.getProtocols();
+
+        boolean profileWithDifferentTransportLayerProtosFound = false;
+        for (int i = 0; i < 1000; i++) {
+            VpnProfile otherProfile = gateway.getProfile(Connection.TransportType.OBFS4, new HashSet<>(Arrays.asList("kcp", "tcp")));
+            String[] otherProtocols =  ((Obfs4Connection)otherProfile.mConnections[0]).getObfs4Options().transport.getProtocols();
+            if (!transportLayerProtocols[0].equals(otherProtocols[0])) {
+                profileWithDifferentTransportLayerProtosFound = true;
+                System.out.println(i + 1 + " attempts");
+                break;
+            }
+        }
+        assertTrue(profileWithDifferentTransportLayerProtosFound);
+    }
+
+    @Test
+    public void testSupportsTransport() throws ConfigParser.ConfigParseError, JSONException, IOException {
+        Gateway gateway = createGatewayFromProvider(0, "multiple_pts_per_host_eip-service.json");
+        assertFalse(gateway.supportsTransport(Connection.TransportType.OBFS4_HOP, null));
+        assertTrue(gateway.supportsTransport(Connection.TransportType.OBFS4, null));
+        assertTrue(gateway.supportsTransport(Connection.TransportType.OBFS4, new HashSet<>(Arrays.asList("kcp"))));
+        assertTrue(gateway.supportsTransport(Connection.TransportType.OBFS4, new HashSet<>(Arrays.asList("tcp"))));
+        assertFalse(gateway.supportsTransport(Connection.TransportType.OBFS4, new HashSet<>(Arrays.asList("invalid"))));
+    }
+
+    @Test
+    public void testGetSupportedTransports() throws ConfigParser.ConfigParseError, JSONException, IOException {
+        Gateway gateway = createGatewayFromProvider(0, "multiple_pts_per_host_eip-service.json");
+        assertEquals(2, gateway.getSupportedTransports().size());
+        assertTrue(gateway.getSupportedTransports().contains(Connection.TransportType.OBFS4));
+        assertTrue(gateway.getSupportedTransports().contains(Connection.TransportType.OPENVPN));
+    }
+
+    @Test
+    public void testHasProfile() throws ConfigParser.ConfigParseError, JSONException, IOException {
+        Gateway gateway = createGatewayFromProvider(0, "multiple_pts_per_host_eip-service.json");
+        VpnProfile profile = gateway.getProfiles().get(0);
+        String profileString = profile.toJson();
+        VpnProfile newProfile = VpnProfile.fromJson(profileString);
+        assertTrue(gateway.hasProfile(newProfile));
+
+        newProfile.mGatewayIp = "XXXX";
+        assertFalse(gateway.hasProfile(newProfile));
+
+        VpnProfile newProfile2 = VpnProfile.fromJson(profileString);
+        newProfile2.mConnections = new Connection[0];
+        assertFalse(gateway.hasProfile(newProfile2));
+    }
+
+
+}
\ No newline at end of file
diff --git a/app/src/test/java/se/leap/bitmaskclient/eip/GatewaysManagerTest.java b/app/src/test/java/se/leap/bitmaskclient/eip/GatewaysManagerTest.java
index 9286a787da11c2ac25e2779ba7837392908e46b3..b79c34ae1acf624c20418224a8169bc00b68e44a 100644
--- a/app/src/test/java/se/leap/bitmaskclient/eip/GatewaysManagerTest.java
+++ b/app/src/test/java/se/leap/bitmaskclient/eip/GatewaysManagerTest.java
@@ -3,6 +3,7 @@ package se.leap.bitmaskclient.eip;
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNull;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 import static de.blinkt.openvpn.core.connection.Connection.TransportType.OBFS4;
@@ -20,11 +21,12 @@ import static se.leap.bitmaskclient.testutils.TestSetupHelper.getProvider;
 import android.content.Context;
 import android.content.SharedPreferences;
 
+import androidx.annotation.Nullable;
+
 import org.json.JSONException;
 import org.json.JSONObject;
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.function.ThrowingRunnable;
 import org.mockito.Answers;
 import org.mockito.Mock;
 
@@ -34,9 +36,11 @@ import java.util.List;
 
 import de.blinkt.openvpn.VpnProfile;
 import de.blinkt.openvpn.core.ConfigParser;
+import de.blinkt.openvpn.core.connection.Connection;
 import se.leap.bitmaskclient.base.models.Location;
 import se.leap.bitmaskclient.base.models.Provider;
 import se.leap.bitmaskclient.base.models.ProviderObservable;
+import se.leap.bitmaskclient.base.models.Transport;
 import se.leap.bitmaskclient.base.utils.PreferenceHelper;
 import se.leap.bitmaskclient.base.utils.TimezoneHelper;
 import se.leap.bitmaskclient.testutils.MockSharedPreferences;
@@ -87,6 +91,18 @@ public class GatewaysManagerTest {
         assertEquals(3, gatewaysManager.size());
     }
 
+    @Nullable
+    private static VpnProfile createProfile(VpnConfigGenerator configGenerator, Connection.TransportType transportType) throws IOException, ConfigParser.ConfigParseError, JSONException {
+        VpnProfile profile = null;
+        for (Transport transport : configGenerator.transports) {
+            if (transport.getTransportType() == transportType) {
+                profile = configGenerator.createProfile(transport);
+                break;
+            }
+        }
+        return profile;
+    }
+
     @Test
     public void TestGetPosition_VpnProfileExtistingObfs4_returnPositionZero() throws JSONException, ConfigParser.ConfigParseError, IOException {
         Provider provider = getProvider(null, null, null, null, null, null, "ptdemo_three_mixed_gateways.json", null);
@@ -99,9 +115,10 @@ public class GatewaysManagerTest {
         configuration.apiVersion = 3;
         configuration.remoteGatewayIP = "37.218.247.60";
         VpnConfigGenerator configGenerator = new VpnConfigGenerator(provider.getDefinition(), secrets, gateway1, configuration);
-        VpnProfile profile = configGenerator.createProfile(OBFS4);
-
+        VpnProfile profile = createProfile(configGenerator, OBFS4);
+        assertNotNull(profile);
         assertEquals(0, gatewaysManager.getPosition(profile));
+
     }
 
     @Test
@@ -116,8 +133,8 @@ public class GatewaysManagerTest {
         configuration.apiVersion = 3;
         configuration.remoteGatewayIP = "37.218.247.60";
         VpnConfigGenerator configGenerator = new VpnConfigGenerator(provider.getDefinition(), secrets, gateway1, configuration);
-        VpnProfile profile = configGenerator.createProfile(OPENVPN);
-
+        VpnProfile profile = createProfile(configGenerator, OPENVPN);
+        assertNotNull(profile);
         assertEquals(0, gatewaysManager.getPosition(profile));
     }
 
@@ -133,7 +150,7 @@ public class GatewaysManagerTest {
         configuration.apiVersion = 3;
         configuration.remoteGatewayIP = "37.218.247.60";
         VpnConfigGenerator configGenerator = new VpnConfigGenerator(provider.getDefinition(), secrets, gateway1, configuration);
-        assertThrows(ConfigParser.ConfigParseError.class, () -> configGenerator.createProfile(OBFS4));
+        assertThrows(ConfigParser.ConfigParseError.class, () -> createProfile(configGenerator, OBFS4));
     }
 
     @Test
@@ -148,9 +165,9 @@ public class GatewaysManagerTest {
         configuration.apiVersion = 3;
         configuration.remoteGatewayIP = "37.218.247.60";
         VpnConfigGenerator configGenerator = new VpnConfigGenerator(provider.getDefinition(), secrets, gateway1, configuration);
-        VpnProfile profile = configGenerator.createProfile(OBFS4);
+        VpnProfile profile = createProfile(configGenerator, OBFS4);
 
-        assertEquals(1, gatewaysManager.getPosition(profile));
+        assertEquals(2, gatewaysManager.getPosition(profile));
     }
 
     @Test
@@ -165,7 +182,7 @@ public class GatewaysManagerTest {
         configuration.apiVersion = 3;
         configuration.remoteGatewayIP = "37.218.247.60";
         VpnConfigGenerator configGenerator = new VpnConfigGenerator(provider.getDefinition(), secrets, gateway1, configuration);
-        VpnProfile profile = configGenerator.createProfile(OPENVPN);
+        VpnProfile profile = createProfile(configGenerator, OPENVPN);
 
         assertEquals(2, gatewaysManager.getPosition(profile));
     }
@@ -182,7 +199,7 @@ public class GatewaysManagerTest {
         configuration.apiVersion = 3;
         configuration.remoteGatewayIP = "37.218.247.61";
         VpnConfigGenerator configGenerator = new VpnConfigGenerator(provider.getDefinition(), secrets, gateway1, configuration);
-        VpnProfile profile = configGenerator.createProfile(OBFS4);
+        VpnProfile profile = createProfile(configGenerator, OBFS4);
 
         assertEquals(-1, gatewaysManager.getPosition(profile));
     }
@@ -199,7 +216,7 @@ public class GatewaysManagerTest {
         configuration.apiVersion = 3;
         configuration.remoteGatewayIP = "3.21.247.89";
         VpnConfigGenerator configGenerator = new VpnConfigGenerator(provider.getDefinition(), secrets, gateway1, configuration);
-        VpnProfile profile = configGenerator.createProfile(OBFS4);
+        VpnProfile profile = createProfile(configGenerator, OBFS4);
 
         assertEquals(1, gatewaysManager.getPosition(profile));
     }
@@ -212,7 +229,7 @@ public class GatewaysManagerTest {
         sharedPreferences.edit().putBoolean(USE_BRIDGES, true).commit();
         GatewaysManager gatewaysManager = new GatewaysManager(mockContext);
 
-        assertEquals("37.12.247.10", gatewaysManager.select(0).gateway.getRemoteIP());
+        assertEquals("37.12.247.10", gatewaysManager.selectVpnProfile(0).mGatewayIp);
     }
 
     @Test
@@ -226,11 +243,11 @@ public class GatewaysManagerTest {
                 commit();
         GatewaysManager gatewaysManager = new GatewaysManager(mockContext);
         ArrayList<String> hosts = new ArrayList<>();
-        hosts.add(gatewaysManager.select(0).gateway.getHost());
-        hosts.add(gatewaysManager.select(1).gateway.getHost());
+        hosts.add(gatewaysManager.selectVpnProfile(0).mGatewayIp);
+        hosts.add(gatewaysManager.selectVpnProfile(1).mGatewayIp);
 
-        assertTrue(hosts.contains("bridge-nyc1-02.bitmask-dev.leapvpn.net"));
-        assertTrue(hosts.contains("bridge-nyc1-01.bitmask-dev.leapvpn.net"));
+        assertTrue(hosts.contains("192.81.208.164"));
+        assertTrue(hosts.contains("104.248.232.240"));
 
     }
 
@@ -246,10 +263,10 @@ public class GatewaysManagerTest {
         GatewaysManager gatewaysManager = new GatewaysManager(mockContext);
 
         ArrayList<String> hosts = new ArrayList<>();
-        hosts.add(gatewaysManager.select(0).gateway.getHost());
-        hosts.add(gatewaysManager.select(1).gateway.getHost());
-        assertTrue(hosts.contains("bridge-nyc1-02.bitmask-dev.leapvpn.net"));
-        assertTrue(hosts.contains("bridge-nyc1-01.bitmask-dev.leapvpn.net"));
+        hosts.add(gatewaysManager.selectVpnProfile(0).mGatewayIp);
+        hosts.add(gatewaysManager.selectVpnProfile(1).mGatewayIp);
+        assertTrue(hosts.contains("192.81.208.164"));
+        assertTrue(hosts.contains("104.248.232.240"));
     }
 
     @Test
@@ -264,7 +281,7 @@ public class GatewaysManagerTest {
 
         for (int i = 0; i < 1000; i++) {
             GatewaysManager gatewaysManager = new GatewaysManager(mockContext);
-            assertEquals("bridge-nyc1-01.bitmask-dev.leapvpn.net", gatewaysManager.select(0).gateway.getHost());
+            assertEquals("104.248.232.240", gatewaysManager.selectVpnProfile(0).mGatewayIp);
         }
     }
 
@@ -279,8 +296,8 @@ public class GatewaysManagerTest {
                 commit();
         GatewaysManager gatewaysManager = new GatewaysManager(mockContext);
 
-        assertEquals("bridge-nyc1-01.bitmask-dev.leapvpn.net", gatewaysManager.select(0).gateway.getHost());
-        assertNull(gatewaysManager.select(1));
+        assertEquals("104.248.232.240", gatewaysManager.selectVpnProfile(0).mGatewayIp);
+        assertNull(gatewaysManager.selectVpnProfile(1));
     }
 
     @Test
@@ -295,11 +312,11 @@ public class GatewaysManagerTest {
         GatewaysManager gatewaysManager = new GatewaysManager(mockContext);
 
         ArrayList<String> hosts = new ArrayList<>();
-        hosts.add(gatewaysManager.select(0).gateway.getHost());
-        hosts.add(gatewaysManager.select(1).gateway.getHost());
+        hosts.add(gatewaysManager.selectVpnProfile(0).mGatewayIp);
+        hosts.add(gatewaysManager.selectVpnProfile(1).mGatewayIp);
 
-        assertTrue(hosts.contains("pt.demo.bitmask.net"));
-        assertTrue(hosts.contains("manila.bitmask.net"));
+        assertTrue(hosts.contains("37.218.247.60"));
+        assertTrue(hosts.contains("37.12.247.10"));
     }
 
     @Test
@@ -309,9 +326,9 @@ public class GatewaysManagerTest {
         providerObservable.updateProvider(provider);
         GatewaysManager gatewaysManager = new GatewaysManager(mockContext);
 
-        assertEquals("manila.bitmask.net", gatewaysManager.select(0).gateway.getHost());
-        assertEquals("moscow.bitmask.net", gatewaysManager.select(1).gateway.getHost());
-        assertEquals("pt.demo.bitmask.net", gatewaysManager.select(2).gateway.getHost());
+        assertEquals("37.12.247.10", gatewaysManager.selectVpnProfile(0).mGatewayIp);
+        assertEquals("3.21.247.89", gatewaysManager.selectVpnProfile(1).mGatewayIp);
+        assertEquals("37.218.247.60", gatewaysManager.selectVpnProfile(2).mGatewayIp);
     }
 
     @Test
@@ -325,9 +342,9 @@ public class GatewaysManagerTest {
                 commit();
         GatewaysManager gatewaysManager = new GatewaysManager(mockContext);
 
-        assertEquals("moscow.bitmask.net", gatewaysManager.select(0).gateway.getHost());
-        assertEquals("pt.demo.bitmask.net", gatewaysManager.select(1).gateway.getHost());
-        assertNull(gatewaysManager.select(2));
+        assertEquals("3.21.247.89", gatewaysManager.selectVpnProfile(0).mGatewayIp);
+        assertEquals("37.218.247.60", gatewaysManager.selectVpnProfile(1).mGatewayIp);
+        assertNull(gatewaysManager.selectVpnProfile(2));
     }
 
 
@@ -342,9 +359,9 @@ public class GatewaysManagerTest {
                 commit();
         GatewaysManager gatewaysManager = new GatewaysManager(mockContext);
 
-        assertEquals("mouette.riseup.net", gatewaysManager.select(0).gateway.getHost());
-        assertEquals("hoatzin.riseup.net", gatewaysManager.select(1).gateway.getHost());
-        assertEquals("zarapito.riseup.net", gatewaysManager.select(2).gateway.getHost());
+        assertEquals("163.172.126.44", gatewaysManager.selectVpnProfile(0).mGatewayIp);
+        assertEquals("212.83.143.67", gatewaysManager.selectVpnProfile(1).mGatewayIp);
+        assertEquals("212.129.62.247", gatewaysManager.selectVpnProfile(2).mGatewayIp);
     }
 
     @Test
@@ -358,9 +375,9 @@ public class GatewaysManagerTest {
                 commit();
         GatewaysManager gatewaysManager = new GatewaysManager(mockContext);
 
-        assertEquals("mouette.riseup.net", gatewaysManager.select(0).gateway.getHost());
-        assertEquals("hoatzin.riseup.net", gatewaysManager.select(1).gateway.getHost());
-        assertEquals("zarapito.riseup.net", gatewaysManager.select(2).gateway.getHost());
+        assertEquals("163.172.126.44", gatewaysManager.selectVpnProfile(0).mGatewayIp);
+        assertEquals("212.83.143.67", gatewaysManager.selectVpnProfile(1).mGatewayIp);
+        assertEquals("212.129.62.247", gatewaysManager.selectVpnProfile(2).mGatewayIp);
     }
 
     @Test
@@ -375,10 +392,10 @@ public class GatewaysManagerTest {
                 commit();
         GatewaysManager gatewaysManager = new GatewaysManager(mockContext);
 
-        assertEquals("Paris", gatewaysManager.select(0).gateway.getName());
-        assertEquals("Paris", gatewaysManager.select(1).gateway.getName());
-        assertEquals("Paris", gatewaysManager.select(2).gateway.getName());
-        assertEquals(null, gatewaysManager.select(3));
+        assertEquals("Paris", gatewaysManager.selectVpnProfile(0).getName());
+        assertEquals("Paris", gatewaysManager.selectVpnProfile(1).getName());
+        assertEquals("Paris", gatewaysManager.selectVpnProfile(2).getName());
+        assertEquals(null, gatewaysManager.selectVpnProfile(3));
     }
 
     @Test
@@ -388,9 +405,9 @@ public class GatewaysManagerTest {
         providerObservable.updateProvider(provider);
         GatewaysManager gatewaysManager = new GatewaysManager(mockContext);
 
-        assertEquals("mouette.riseup.net", gatewaysManager.select(0, "Paris").gateway.getHost());
-        assertEquals("hoatzin.riseup.net", gatewaysManager.select(1, "Paris").gateway.getHost());
-        assertEquals("zarapito.riseup.net", gatewaysManager.select(2, "Paris").gateway.getHost());
+        assertEquals("163.172.126.44", gatewaysManager.selectVpnProfile(0, "Paris").mGatewayIp);
+        assertEquals("212.83.143.67", gatewaysManager.selectVpnProfile(1, "Paris").mGatewayIp);
+        assertEquals("212.129.62.247", gatewaysManager.selectVpnProfile(2, "Paris").mGatewayIp);
     }
 
     @Test
@@ -400,9 +417,9 @@ public class GatewaysManagerTest {
         providerObservable.updateProvider(provider);
         GatewaysManager gatewaysManager = new GatewaysManager(mockContext);
 
-        assertEquals("mouette.riseup.net", gatewaysManager.select(0, "Paris").gateway.getHost());
-        assertEquals("hoatzin.riseup.net", gatewaysManager.select(1, "Paris").gateway.getHost());
-        assertEquals("zarapito.riseup.net", gatewaysManager.select(2, "Paris").gateway.getHost());
+        assertEquals("163.172.126.44", gatewaysManager.selectVpnProfile(0, "Paris").mGatewayIp);
+        assertEquals("212.83.143.67", gatewaysManager.selectVpnProfile(1, "Paris").mGatewayIp);
+        assertEquals("212.129.62.247", gatewaysManager.selectVpnProfile(2, "Paris").mGatewayIp);
     }
 
     @Test
@@ -413,10 +430,10 @@ public class GatewaysManagerTest {
         providerObservable.updateProvider(provider);
         GatewaysManager gatewaysManager = new GatewaysManager(mockContext);
 
-        assertEquals("Paris", gatewaysManager.select(0, "Paris").gateway.getName());
-        assertEquals("Paris", gatewaysManager.select(1, "Paris").gateway.getName());
-        assertEquals("Paris", gatewaysManager.select(2, "Paris").gateway.getName());
-        assertEquals(null, gatewaysManager.select(3, "Paris"));
+        assertEquals("Paris", gatewaysManager.selectVpnProfile(0, "Paris").getName());
+        assertEquals("Paris", gatewaysManager.selectVpnProfile(1, "Paris").getName());
+        assertEquals("Paris", gatewaysManager.selectVpnProfile(2, "Paris").getName());
+        assertEquals(null, gatewaysManager.selectVpnProfile(3, "Paris"));
     }
 
     @Test
@@ -426,7 +443,7 @@ public class GatewaysManagerTest {
         provider.setGeoIpJson(new JSONObject());
         providerObservable.updateProvider(provider);
         GatewaysManager gatewaysManager = new GatewaysManager(mockContext);
-        assertNull(gatewaysManager.select(0, "Stockholm"));
+        assertNull(gatewaysManager.selectVpnProfile(0, "Stockholm"));
     }
 
     @Test
diff --git a/app/src/test/java/se/leap/bitmaskclient/eip/VpnConfigGeneratorTest.java b/app/src/test/java/se/leap/bitmaskclient/eip/VpnConfigGeneratorTest.java
index 547bb3df8a4fcadee688ff712e2a301c81904688..5343c4669751f5d4976c2a29ee6270c3cb4ca6c5 100644
--- a/app/src/test/java/se/leap/bitmaskclient/eip/VpnConfigGeneratorTest.java
+++ b/app/src/test/java/se/leap/bitmaskclient/eip/VpnConfigGeneratorTest.java
@@ -19,6 +19,7 @@ import org.junit.Test;
 
 import java.io.File;
 import java.util.HashMap;
+import java.util.Vector;
 
 import de.blinkt.openvpn.VpnProfile;
 import de.blinkt.openvpn.core.ConfigParser;
@@ -1353,15 +1354,33 @@ public class VpnConfigGeneratorTest {
         when(context.getCacheDir()).thenReturn(new File("/data/data/se.leap.bitmask"));
     }
 
+    private static boolean containsKey(Vector<VpnProfile> profiles, Connection.TransportType transportType) {
+        for (VpnProfile profile : profiles) {
+            if (profile.getTransportType() == transportType) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static VpnProfile getVpnProfile(Vector<VpnProfile> profiles, Connection.TransportType transportType) {
+        for (VpnProfile profile : profiles) {
+            if (profile.getTransportType() == transportType) {
+                return profile;
+            }
+        }
+        return null;
+    }
+
     @Test
     public void testGenerateVpnProfile_v1_tcp_udp() throws Exception {
         gateway = new JSONObject(TestSetupHelper.getInputAsString(getClass().getClassLoader().getResourceAsStream("gateway_tcp_udp.json")));
         VpnConfigGenerator.Configuration configuration = new VpnConfigGenerator.Configuration();
         configuration.apiVersion = 1;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertFalse(vpnProfiles.containsKey(OBFS4));
-        assertEquals(expectedVPNConfig_v1_tcp_udp.trim(), vpnProfiles.get(OPENVPN).getConfigFile(context, false).trim());
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertFalse(containsKey(vpnProfiles, OBFS4));
+        assertEquals(expectedVPNConfig_v1_tcp_udp.trim(), getVpnProfile(vpnProfiles, OPENVPN).getConfigFile(context, false).trim());
     }
 
     @Test
@@ -1370,9 +1389,9 @@ public class VpnConfigGeneratorTest {
         VpnConfigGenerator.Configuration configuration = new VpnConfigGenerator.Configuration();
         configuration.apiVersion = 1;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertFalse(vpnProfiles.containsKey(OBFS4));
-        assertEquals(expectedVPNConfig_v1_udp_tcp.trim(), vpnProfiles.get(OPENVPN).getConfigFile(context, false).trim());
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertFalse(containsKey(vpnProfiles, OBFS4));
+        assertEquals(expectedVPNConfig_v1_udp_tcp.trim(), getVpnProfile(vpnProfiles, OPENVPN).getConfigFile(context, false).trim());
     }
 
     @Test
@@ -1381,9 +1400,9 @@ public class VpnConfigGeneratorTest {
         VpnConfigGenerator.Configuration configuration = new VpnConfigGenerator.Configuration();
         configuration.apiVersion = 2;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertFalse(vpnProfiles.containsKey(OBFS4));
-        assertEquals(expectedVPNConfig_v1_tcp_udp.trim(), vpnProfiles.get(OPENVPN).getConfigFile(context, false).trim());
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertFalse(containsKey(vpnProfiles, OBFS4));
+        assertEquals(expectedVPNConfig_v1_tcp_udp.trim(), getVpnProfile(vpnProfiles, OPENVPN).getConfigFile(context, false).trim());
     }
 
     @Test
@@ -1392,9 +1411,9 @@ public class VpnConfigGeneratorTest {
         VpnConfigGenerator.Configuration configuration = new VpnConfigGenerator.Configuration();
         configuration.apiVersion = 2;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertFalse(vpnProfiles.containsKey(OBFS4));
-        assertEquals(expectedVPNConfig_v1_udp_tcp.trim(), vpnProfiles.get(OPENVPN).getConfigFile(context, false).trim());
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertFalse(containsKey(vpnProfiles, OBFS4));
+        assertEquals(expectedVPNConfig_v1_udp_tcp.trim(), getVpnProfile(vpnProfiles, OPENVPN).getConfigFile(context, false).trim());
     }
 
 
@@ -1405,11 +1424,11 @@ public class VpnConfigGeneratorTest {
         VpnConfigGenerator.Configuration configuration = new VpnConfigGenerator.Configuration();
         configuration.apiVersion = 3;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertTrue(vpnProfiles.containsKey(OBFS4));
-        assertTrue(vpnProfiles.containsKey(OPENVPN));
-        System.out.println(vpnProfiles.get(OBFS4).getConfigFile(context, false));
-        assertEquals(expectedVPNConfig_v3_obfs4.trim(), vpnProfiles.get(OBFS4).getConfigFile(context, false).trim());
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertTrue(containsKey(vpnProfiles, OBFS4));
+        assertTrue(containsKey(vpnProfiles, OPENVPN));
+        System.out.println(getVpnProfile(vpnProfiles, OBFS4).getConfigFile(context, false));
+        assertEquals(expectedVPNConfig_v3_obfs4.trim(), getVpnProfile(vpnProfiles, OBFS4).getConfigFile(context, false).trim());
     }
 
     @Test
@@ -1419,11 +1438,11 @@ public class VpnConfigGeneratorTest {
         VpnConfigGenerator.Configuration configuration = new VpnConfigGenerator.Configuration();
         configuration.apiVersion = 3;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertTrue(vpnProfiles.containsKey(OBFS4));
-        assertTrue(vpnProfiles.containsKey(OPENVPN));
-        System.out.println(vpnProfiles.get(OBFS4).getConfigFile(context, false));
-        assertEquals(expectedVPNConfig_v3_obfsvpn_obfs4.trim(), vpnProfiles.get(OBFS4).getConfigFile(context, false).trim());
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertTrue(containsKey(vpnProfiles, OBFS4));
+        assertTrue(containsKey(vpnProfiles, OPENVPN));
+        System.out.println(getVpnProfile(vpnProfiles, OBFS4).getConfigFile(context, false));
+        assertEquals(expectedVPNConfig_v3_obfsvpn_obfs4.trim(), getVpnProfile(vpnProfiles, OBFS4).getConfigFile(context, false).trim());
     }
 
     @Test
@@ -1432,11 +1451,11 @@ public class VpnConfigGeneratorTest {
         VpnConfigGenerator.Configuration configuration = new VpnConfigGenerator.Configuration();
         configuration.apiVersion = 3;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertTrue(vpnProfiles.containsKey(OBFS4));
-        assertTrue(vpnProfiles.containsKey(OPENVPN));
-        System.out.println(vpnProfiles.get(OPENVPN).getConfigFile(context, false));
-        assertEquals(expectedVPNConfig_v3_ovpn_tcp_udp.trim(), vpnProfiles.get(OPENVPN).getConfigFile(context, false).trim());
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertTrue(containsKey(vpnProfiles, OBFS4));
+        assertTrue(containsKey(vpnProfiles, OPENVPN));
+        System.out.println(getVpnProfile(vpnProfiles, OPENVPN).getConfigFile(context, false));
+        assertEquals(expectedVPNConfig_v3_ovpn_tcp_udp.trim(), getVpnProfile(vpnProfiles, OPENVPN).getConfigFile(context, false).trim());
     }
 
     @Test
@@ -1445,11 +1464,11 @@ public class VpnConfigGeneratorTest {
         VpnConfigGenerator.Configuration configuration = new VpnConfigGenerator.Configuration();
         configuration.apiVersion = 3;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertTrue(vpnProfiles.containsKey(OBFS4));
-        assertTrue(vpnProfiles.containsKey(OPENVPN));
-        System.out.println(vpnProfiles.get(OPENVPN).getConfigFile(context, false));
-        assertEquals(expectedVPNConfig_v3_ovpn_udp_tcp.trim(), vpnProfiles.get(OPENVPN).getConfigFile(context, false).trim());
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertTrue(containsKey(vpnProfiles, OBFS4));
+        assertTrue(containsKey(vpnProfiles, OPENVPN));
+        System.out.println(getVpnProfile(vpnProfiles, OPENVPN).getConfigFile(context, false));
+        assertEquals(expectedVPNConfig_v3_ovpn_udp_tcp.trim(), getVpnProfile(vpnProfiles, OPENVPN).getConfigFile(context, false).trim());
     }
 
     @Test
@@ -1460,11 +1479,11 @@ public class VpnConfigGeneratorTest {
         VpnConfigGenerator.Configuration configuration = new VpnConfigGenerator.Configuration();
         configuration.apiVersion = 3;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertTrue(vpnProfiles.containsKey(OBFS4));
-        assertTrue(vpnProfiles.containsKey(OPENVPN));
-        System.out.println(vpnProfiles.get(OPENVPN).getConfigFile(context, false));
-        assertEquals(expectedVPNConfig_v3_ovpn_udp_tcp_defaultDataCiphers.trim(), vpnProfiles.get(OPENVPN).getConfigFile(context, false).trim());
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertTrue(containsKey(vpnProfiles, OBFS4));
+        assertTrue(containsKey(vpnProfiles, OPENVPN));
+        System.out.println(getVpnProfile(vpnProfiles, OPENVPN).getConfigFile(context, false));
+        assertEquals(expectedVPNConfig_v3_ovpn_udp_tcp_defaultDataCiphers.trim(), getVpnProfile(vpnProfiles, OPENVPN).getConfigFile(context, false).trim());
     }
 
     @Test
@@ -1474,11 +1493,11 @@ public class VpnConfigGeneratorTest {
         VpnConfigGenerator.Configuration configuration = new VpnConfigGenerator.Configuration();
         configuration.apiVersion = 4;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertTrue(vpnProfiles.containsKey(OBFS4));
-        assertTrue(vpnProfiles.containsKey(OPENVPN));
-        System.out.println(vpnProfiles.get(OPENVPN).getConfigFile(context, false));
-        assertEquals(expectedVPNConfig_v4_ovpn_tcp_udp.trim(), vpnProfiles.get(OPENVPN).getConfigFile(context, false).trim());
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertTrue(containsKey(vpnProfiles, OBFS4));
+        assertTrue(containsKey(vpnProfiles, OPENVPN));
+        System.out.println(getVpnProfile(vpnProfiles, OPENVPN).getConfigFile(context, false));
+        assertEquals(expectedVPNConfig_v4_ovpn_tcp_udp.trim(), getVpnProfile(vpnProfiles, OPENVPN).getConfigFile(context, false).trim());
     }
 
     @Test
@@ -1488,11 +1507,11 @@ public class VpnConfigGeneratorTest {
         VpnConfigGenerator.Configuration configuration = new VpnConfigGenerator.Configuration();
         configuration.apiVersion = 4;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertTrue(vpnProfiles.containsKey(OBFS4));
-        assertTrue(vpnProfiles.containsKey(OPENVPN));
-        System.out.println(vpnProfiles.get(OPENVPN).getConfigFile(context, false));
-        assertEquals(expectedVPNConfig_v4_ovpn_udp_tcp.trim(), vpnProfiles.get(OPENVPN).getConfigFile(context, false).trim());
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertTrue(containsKey(vpnProfiles, OBFS4));
+        assertTrue(containsKey(vpnProfiles, OPENVPN));
+        System.out.println(getVpnProfile(vpnProfiles, OPENVPN).getConfigFile(context, false));
+        assertEquals(expectedVPNConfig_v4_ovpn_udp_tcp.trim(), getVpnProfile(vpnProfiles, OPENVPN).getConfigFile(context, false).trim());
     }
 
     @Test
@@ -1502,8 +1521,8 @@ public class VpnConfigGeneratorTest {
         VpnConfigGenerator.Configuration configuration = new VpnConfigGenerator.Configuration();
         configuration.apiVersion = 3;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertTrue(vpnProfiles.containsKey(OPENVPN));
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertTrue(containsKey(vpnProfiles, OPENVPN));
     }
 
     @Test
@@ -1513,8 +1532,8 @@ public class VpnConfigGeneratorTest {
         VpnConfigGenerator.Configuration configuration = new VpnConfigGenerator.Configuration();
         configuration.apiVersion = 3;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertFalse(vpnProfiles.containsKey(OBFS4));
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertFalse(containsKey(vpnProfiles, OBFS4));
     }
 
     /**
@@ -1527,11 +1546,11 @@ public class VpnConfigGeneratorTest {
         VpnConfigGenerator.Configuration configuration = new VpnConfigGenerator.Configuration();
         configuration.apiVersion = 3;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertTrue(vpnProfiles.containsKey(OBFS4));
-        assertTrue(vpnProfiles.containsKey(OPENVPN));
-        assertEquals(1, vpnProfiles.get(OBFS4).mConnections.length);
-        assertEquals("37.218.247.60/32", vpnProfiles.get(OBFS4).mExcludedRoutes.trim());
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertTrue(containsKey(vpnProfiles, OBFS4));
+        assertTrue(containsKey(vpnProfiles, OPENVPN));
+        assertEquals(1, getVpnProfile(vpnProfiles, OBFS4).mConnections.length);
+        assertEquals("37.218.247.60/32", getVpnProfile(vpnProfiles, OBFS4).mExcludedRoutes.trim());
     }
 
     /**
@@ -1544,9 +1563,9 @@ public class VpnConfigGeneratorTest {
         VpnConfigGenerator.Configuration configuration = new VpnConfigGenerator.Configuration();
         configuration.apiVersion = 3;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertFalse(vpnProfiles.containsKey(OBFS4));
-        assertTrue(vpnProfiles.containsKey(OPENVPN));
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertFalse(containsKey(vpnProfiles, OBFS4));
+        assertTrue(containsKey(vpnProfiles, OPENVPN));
     }
 
     /**
@@ -1559,9 +1578,9 @@ public class VpnConfigGeneratorTest {
         VpnConfigGenerator.Configuration configuration = new VpnConfigGenerator.Configuration();
         configuration.apiVersion = 3;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertFalse(vpnProfiles.containsKey(OBFS4));
-        assertTrue(vpnProfiles.containsKey(OPENVPN));
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertFalse(containsKey(vpnProfiles, OBFS4));
+        assertTrue(containsKey(vpnProfiles, OPENVPN));
     }
 
     @Test
@@ -1571,10 +1590,10 @@ public class VpnConfigGeneratorTest {
         VpnConfigGenerator.Configuration configuration = new VpnConfigGenerator.Configuration();
         configuration.apiVersion = 3;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertTrue(vpnProfiles.containsKey(OBFS4));
-        assertTrue(vpnProfiles.containsKey(OPENVPN));
-        assertEquals(1, vpnProfiles.get(OBFS4).mConnections.length);
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertTrue(containsKey(vpnProfiles, OBFS4));
+        assertTrue(containsKey(vpnProfiles, OPENVPN));
+        assertEquals(1, getVpnProfile(vpnProfiles, OBFS4).mConnections.length);
     }
 
     @Test
@@ -1585,11 +1604,11 @@ public class VpnConfigGeneratorTest {
         configuration.apiVersion = 3;
         configuration.preferUDP = true;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertTrue(vpnProfiles.containsKey(OBFS4));
-        assertTrue(vpnProfiles.containsKey(OPENVPN));
-        System.out.println(vpnProfiles.get(OPENVPN).getConfigFile(context, false));
-        assertEquals(expectedVPNConfig_v4_ovpn_multiport_tcpudp.trim(), vpnProfiles.get(OPENVPN).getConfigFile(context, false).trim());
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertTrue(containsKey(vpnProfiles, OBFS4));
+        assertTrue(containsKey(vpnProfiles, OPENVPN));
+        System.out.println(getVpnProfile(vpnProfiles, OPENVPN).getConfigFile(context, false));
+        assertEquals(expectedVPNConfig_v4_ovpn_multiport_tcpudp.trim(), getVpnProfile(vpnProfiles, OPENVPN).getConfigFile(context, false).trim());
     }
 
     @Test
@@ -1599,9 +1618,9 @@ public class VpnConfigGeneratorTest {
         VpnConfigGenerator.Configuration configuration = new VpnConfigGenerator.Configuration();
         configuration.apiVersion = 4;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        System.out.println(vpnProfiles.get(OPENVPN).getConfigFile(context, false));
-        assertEquals(expectedVPNConfig_v4_ovpn_tcp_udp_new_ciphers.trim(), vpnProfiles.get(OPENVPN).getConfigFile(context, false).trim());
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        System.out.println(getVpnProfile(vpnProfiles, OPENVPN).getConfigFile(context, false));
+        assertEquals(expectedVPNConfig_v4_ovpn_tcp_udp_new_ciphers.trim(), getVpnProfile(vpnProfiles, OPENVPN).getConfigFile(context, false).trim());
     }
 
     @Test
@@ -1613,9 +1632,9 @@ public class VpnConfigGeneratorTest {
         configuration.experimentalTransports = true;
         configuration.preferUDP = true;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertTrue(vpnProfiles.containsKey(OBFS4) && ((Obfs4Connection)vpnProfiles.get(OBFS4).mConnections[0]).getObfs4Options().transport.getProtocols()[0].equals("kcp"));
-        assertTrue(vpnProfiles.containsKey(OPENVPN));
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertTrue(containsKey(vpnProfiles, OBFS4) && ((Obfs4Connection)getVpnProfile(vpnProfiles, OBFS4).mConnections[0]).getObfs4Options().transport.getProtocols()[0].equals("kcp"));
+        assertTrue(containsKey(vpnProfiles, OPENVPN));
     }
 
     @Test
@@ -1626,9 +1645,9 @@ public class VpnConfigGeneratorTest {
         configuration.apiVersion = 3;
         configuration.experimentalTransports = true;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertFalse(vpnProfiles.containsKey(OBFS4));
-        assertTrue(vpnProfiles.containsKey(OPENVPN));
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertFalse(containsKey(vpnProfiles, OBFS4));
+        assertTrue(containsKey(vpnProfiles, OPENVPN));
     }
 
     @Test
@@ -1644,10 +1663,10 @@ public class VpnConfigGeneratorTest {
         configuration.obfuscationProxyKCP = true;
         configuration.remoteGatewayIP = "1.2.3.4";
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertTrue("has openvpn profile", vpnProfiles.containsKey(OPENVPN));
-        assertTrue("has obfs4 profile", vpnProfiles.containsKey(OBFS4));
-        assertTrue("bridge is running KCP", vpnProfiles.get(OBFS4).mGatewayIp.equals("1.2.3.4"));
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertTrue("has openvpn profile", containsKey(vpnProfiles, OPENVPN));
+        assertTrue("has obfs4 profile", containsKey(vpnProfiles, OBFS4));
+        assertTrue("bridge is running KCP", getVpnProfile(vpnProfiles, OBFS4).mGatewayIp.equals("1.2.3.4"));
 
     }
 
@@ -1664,11 +1683,11 @@ public class VpnConfigGeneratorTest {
         configuration.obfuscationProxyCert = "asdfasdf";
         configuration.remoteGatewayIP = "1.2.3.4";
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertFalse("has openvpn profile", vpnProfiles.containsKey(OPENVPN));
-        assertTrue("has obfs4 profile", vpnProfiles.containsKey(OBFS4));
-        assertTrue("bridge is pinned one", vpnProfiles.get(OBFS4).getTransportType() == OBFS4 && vpnProfiles.get(OBFS4).mConnections[0].isUseUdp());
-        assertTrue("bridge is running TCP", ((Obfs4Connection) vpnProfiles.get(OBFS4).mConnections[0]).getObfs4Options().transport.getProtocols()[0].equals("tcp"));
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertFalse("has openvpn profile", containsKey(vpnProfiles, OPENVPN));
+        assertTrue("has obfs4 profile", containsKey(vpnProfiles, OBFS4));
+        assertTrue("bridge is pinned one", getVpnProfile(vpnProfiles, OBFS4).getTransportType() == OBFS4 && getVpnProfile(vpnProfiles, OBFS4).mConnections[0].isUseUdp());
+        assertTrue("bridge is running TCP", ((Obfs4Connection) getVpnProfile(vpnProfiles, OBFS4).mConnections[0]).getObfs4Options().transport.getProtocols()[0].equals("tcp"));
     }
 
     @Test
@@ -1685,11 +1704,11 @@ public class VpnConfigGeneratorTest {
         configuration.remoteGatewayIP = "1.2.3.4";
 
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertFalse("has openvpn profile", vpnProfiles.containsKey(OPENVPN));
-        assertTrue("has no obfs4 profile", vpnProfiles.containsKey(OBFS4));
-        assertTrue("bridge is pinned one", vpnProfiles.get(OBFS4).getTransportType() == OBFS4 && vpnProfiles.get(OBFS4).mGatewayIp.equals("1.2.3.4"));
-        assertTrue("bridge is running KCP", ((Obfs4Connection) vpnProfiles.get(OBFS4).mConnections[0]).getObfs4Options().transport.getProtocols()[0].equals("kcp"));
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertFalse("has openvpn profile", containsKey(vpnProfiles, OPENVPN));
+        assertTrue("has no obfs4 profile", containsKey(vpnProfiles, OBFS4));
+        assertTrue("bridge is pinned one", getVpnProfile(vpnProfiles, OBFS4).getTransportType() == OBFS4 && getVpnProfile(vpnProfiles, OBFS4).mGatewayIp.equals("1.2.3.4"));
+        assertTrue("bridge is running KCP", ((Obfs4Connection) getVpnProfile(vpnProfiles, OBFS4).mConnections[0]).getObfs4Options().transport.getProtocols()[0].equals("kcp"));
     }
     @Test
     public void testGenerateVpnProfile_obfs4hop_tcp () throws Exception {
@@ -1699,9 +1718,9 @@ public class VpnConfigGeneratorTest {
         configuration.apiVersion = 3;
         configuration.experimentalTransports = true;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertTrue(vpnProfiles.containsKey(OBFS4_HOP) && ((Obfs4Connection)vpnProfiles.get(OBFS4_HOP).mConnections[0]).getObfs4Options().transport.getProtocols()[0].equals("tcp"));
-        assertTrue(vpnProfiles.containsKey(OPENVPN));
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertTrue(containsKey(vpnProfiles, OBFS4_HOP) && ((Obfs4Connection)getVpnProfile(vpnProfiles, OBFS4_HOP).mConnections[0]).getObfs4Options().transport.getProtocols()[0].equals("tcp"));
+        assertTrue(containsKey(vpnProfiles, OPENVPN));
     }
 
     @Test
@@ -1712,9 +1731,9 @@ public class VpnConfigGeneratorTest {
         configuration.apiVersion = 3;
         configuration.experimentalTransports = true;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertTrue(vpnProfiles.containsKey(OBFS4_HOP) && ((Obfs4Connection)vpnProfiles.get(OBFS4_HOP).mConnections[0]).getObfs4Options().transport.getProtocols()[0].equals("kcp"));
-        assertTrue(vpnProfiles.containsKey(OPENVPN));
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertTrue(containsKey(vpnProfiles, OBFS4_HOP) && ((Obfs4Connection)getVpnProfile(vpnProfiles, OBFS4_HOP).mConnections[0]).getObfs4Options().transport.getProtocols()[0].equals("kcp"));
+        assertTrue(containsKey(vpnProfiles, OPENVPN));
     }
 
     @Test
@@ -1726,9 +1745,9 @@ public class VpnConfigGeneratorTest {
         configuration.apiVersion = 3;
         configuration.experimentalTransports = true;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        System.out.println(vpnProfiles.get(OBFS4_HOP).getConfigFile(context, false));
-        assertEquals(expectedVPNConfig_hopping_pt_portHopping.trim(), vpnProfiles.get(OBFS4_HOP).getConfigFile(context, false).trim());
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        System.out.println(getVpnProfile(vpnProfiles, OBFS4_HOP).getConfigFile(context, false));
+        assertEquals(expectedVPNConfig_hopping_pt_portHopping.trim(), getVpnProfile(vpnProfiles, OBFS4_HOP).getConfigFile(context, false).trim());
     }
 
     @Test
@@ -1740,9 +1759,9 @@ public class VpnConfigGeneratorTest {
         configuration.apiVersion = 3;
         configuration.experimentalTransports = true;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        System.out.println(vpnProfiles.get(OBFS4_HOP).getConfigFile(context, false));
-        assertEquals(expectedVPNConfig_hopping_pt_portHopping.trim(), vpnProfiles.get(OBFS4_HOP).getConfigFile(context, false).trim());
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        System.out.println(getVpnProfile(vpnProfiles, OBFS4_HOP).getConfigFile(context, false));
+        assertEquals(expectedVPNConfig_hopping_pt_portHopping.trim(), getVpnProfile(vpnProfiles, OBFS4_HOP).getConfigFile(context, false).trim());
     }
     @Test
     public void testGenerateVpnProfile_obfs4_decoupled() throws Exception {
@@ -1753,10 +1772,10 @@ public class VpnConfigGeneratorTest {
         configuration.apiVersion = 3;
         configuration.experimentalTransports = true;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertTrue(vpnProfiles.containsKey(OBFS4));
-        assertTrue(((Obfs4Connection)vpnProfiles.get(OBFS4).mConnections[0]).getObfs4Options().transport.getProtocols()[0].equals("tcp"));
-        assertFalse(vpnProfiles.containsKey(OPENVPN));
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertTrue(containsKey(vpnProfiles, OBFS4));
+        assertTrue(((Obfs4Connection)getVpnProfile(vpnProfiles, OBFS4).mConnections[0]).getObfs4Options().transport.getProtocols()[0].equals("tcp"));
+        assertFalse(containsKey(vpnProfiles, OPENVPN));
     }
 
     @Test
@@ -1768,11 +1787,11 @@ public class VpnConfigGeneratorTest {
         configuration.apiVersion = 3;
         configuration.experimentalTransports = true;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertTrue(vpnProfiles.containsKey(OBFS4_HOP));
-        assertTrue(((Obfs4Connection)vpnProfiles.get(OBFS4_HOP).mConnections[0]).getObfs4Options().transport.getProtocols()[0].equals("tcp"));
-        assertFalse(vpnProfiles.containsKey(OPENVPN));
-        assertFalse(vpnProfiles.containsKey(OBFS4));
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertTrue(containsKey(vpnProfiles, OBFS4_HOP));
+        assertTrue(((Obfs4Connection)getVpnProfile(vpnProfiles, OBFS4_HOP).mConnections[0]).getObfs4Options().transport.getProtocols()[0].equals("tcp"));
+        assertFalse(containsKey(vpnProfiles, OPENVPN));
+        assertFalse(containsKey(vpnProfiles, OBFS4));
     }
 
     @Test
@@ -1802,10 +1821,10 @@ public class VpnConfigGeneratorTest {
         configuration.apiVersion = 3;
         configuration.experimentalTransports = true;
         vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway, configuration);
-        HashMap<Connection.TransportType, VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
-        assertTrue(vpnProfiles.containsKey(OBFS4_HOP));
-        assertTrue(((Obfs4Connection)vpnProfiles.get(OBFS4_HOP).mConnections[0]).getObfs4Options().transport.getProtocols()[0].equals("tcp"));
-        assertFalse(vpnProfiles.containsKey(OPENVPN));
-        assertFalse(vpnProfiles.containsKey(OBFS4));
+        Vector<VpnProfile> vpnProfiles = vpnConfigGenerator.generateVpnProfiles();
+        assertTrue(containsKey(vpnProfiles, OBFS4_HOP));
+        assertTrue(((Obfs4Connection)getVpnProfile(vpnProfiles, OBFS4_HOP).mConnections[0]).getObfs4Options().transport.getProtocols()[0].equals("tcp"));
+        assertFalse(containsKey(vpnProfiles, OPENVPN));
+        assertFalse(containsKey(vpnProfiles, OBFS4));
     }
 }
\ No newline at end of file
diff --git a/app/src/test/resources/multiple_pts_per_host_eip-service.json b/app/src/test/resources/multiple_pts_per_host_eip-service.json
new file mode 100644
index 0000000000000000000000000000000000000000..2bd053d8e8f0df1106652b3a2059c010bb2b47ce
--- /dev/null
+++ b/app/src/test/resources/multiple_pts_per_host_eip-service.json
@@ -0,0 +1,132 @@
+{
+  "gateways":[
+    {
+      "capabilities":{
+        "adblock":false,
+        "filter_dns":false,
+        "limited":false,
+        "transport":[
+          {
+            "ports":[
+              "80"
+            ],
+            "protocols":[
+              "tcp",
+              "udp"
+            ],
+            "type":"openvpn"
+          },
+          {
+            "options":{
+              "cert":"XXXX",
+              "iatMode":"0"
+            },
+            "ports":[
+              "443"
+            ],
+            "protocols":[
+              "tcp"
+            ],
+            "type":"obfs4"
+          },
+          {
+            "options":{
+              "cert":"XXXX",
+              "iatMode":"0"
+            },
+            "ports":[
+              "4431"
+            ],
+            "protocols":[
+              "kcp"
+            ],
+            "type":"obfs4"
+          }
+        ]
+      },
+      "host":"cod.demo.bitmask.net",
+      "ip_address":"37.218.245.94",
+      "location":"North Brabant"
+    },
+    {
+      "capabilities":{
+        "adblock":false,
+        "filter_dns":false,
+        "limited":false,
+        "transport":[
+          {
+            "ports":[
+              "80"
+            ],
+            "protocols":[
+              "tcp",
+              "udp"
+            ],
+            "type":"openvpn"
+          },
+          {
+            "options":{
+              "cert":"XXXX",
+              "iatMode":"0"
+            },
+            "ports":[
+              "443"
+            ],
+            "protocols":[
+              "udp"
+            ],
+            "type":"obfs4"
+          },
+          {
+            "options":{
+              "cert":"XXXX",
+              "iatMode":"0"
+            },
+            "ports":[
+              "4431"
+            ],
+            "protocols":[
+              "kcp"
+            ],
+            "type":"obfs4"
+          }
+        ]
+      },
+      "host":"mullet.demo.bitmask.net",
+      "ip_address":"37.218.241.208",
+      "location":"Florida"
+    }
+  ],
+  "locations":{
+    "Florida":{
+      "country_code":"US",
+      "hemisphere":"N",
+      "name":"United States",
+      "timezone":"-6"
+    },
+    "North Brabant":{
+      "country_code":"NL",
+      "hemisphere":"N",
+      "name":"Netherlands",
+      "timezone":"+2"
+    }
+  },
+  "openvpn_configuration":{
+    "auth":"SHA512",
+    "cipher":"AES-256-GCM",
+    "data-ciphers":"AES-256-GCM",
+    "dev":"tun",
+    "float":"",
+    "keepalive":"10 30",
+    "key-direction":"1",
+    "nobind":true,
+    "persist-key":true,
+    "rcvbuf":"0",
+    "sndbuf":"0",
+    "tls-cipher":"TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384",
+    "tls-version-min":"1.2",
+    "verb":"3"
+  },
+  "serial":3,
+  "version":3
+}
\ No newline at end of file