Repository: graphhopper/graphhopper
Pull request #2281 (2021-04-14 21:56:03)

remove GraphHopper.setEncodingManager 
This is required to allow adding encoded values from profiles. 

In the most cases it makes handling of the GraphHopper class easier as only profiles (and no FlagEncoders) needs to be set.

Additionally this helps to reduce usage of the FlagEncoder class as we could add turn cost parser etc from the profile directly.

Required for #2273 


Patch:
diff --git a/config-example.yml b/config-example.yml
index a35ef9ac6..62137371b 100644
--- a/config-example.yml
+++ b/config-example.yml
@@ -10,7 +10,7 @@ graphhopper:
 
   # More options: foot,hike,bike,bike2,mtb,racingbike,motorcycle,car4wd,wheelchair (comma separated)
   # bike2 takes elevation data into account (like up-hill is slower than down-hill) and requires enabling graph.elevation.provider below.
-  graph.flag_encoders: car
+  # graph.flag_encoders: car
 
   # Enable turn restrictions for car or motorcycle.
   # graph.flag_encoders: car|turn_costs=true
diff --git a/core/files/changelog.txt b/core/files/changelog.txt
index 0978842ca..769c6e82c 100644
--- a/core/files/changelog.txt
+++ b/core/files/changelog.txt
@@ -1,4 +1,5 @@
 3.0
+    removed setEncodingManager use setProfiles instead or for more custom requirements use GraphHopper.getEncodingManagerBuilder
     CustomWeighting language breaks old format but is more powerful and easier to read; it also allows factors >1 for server-side CustomModels
     renamed GHUtilities.setProperties to setSpeed
     Helper.createFormatter is using the ENGLISH Locale instead of UK, see #2186
diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java
index 1772bab13..82d79bad0 100644
--- a/core/src/main/java/com/graphhopper/GraphHopper.java
+++ b/core/src/main/java/com/graphhopper/GraphHopper.java
@@ -86,6 +86,7 @@ public class GraphHopper implements GraphHopperAPI {
     boolean removeZipped = true;
     // for graph:
     private GraphHopperStorage ghStorage;
+    private final EncodingManager.Builder emBuilder = new EncodingManager.Builder();
     private EncodingManager encodingManager;
     private int defaultSegmentSize = -1;
     private String ghLocation = "";
@@ -133,25 +134,22 @@ public class GraphHopper implements GraphHopperAPI {
     /**
      * For testing only
      */
-    protected GraphHopper loadGraph(GraphHopperStorage g) {
+    protected GraphHopper loadGraph(GraphHopperStorage g, EncodingManager encodingManager) {
         this.ghStorage = g;
+        this.encodingManager = encodingManager;
         setFullyLoaded();
         initLocationIndex();
         return this;
     }
 
-    public EncodingManager getEncodingManager() {
-        return encodingManager;
+    public EncodingManager.Builder getEncodingManagerBuilder() {
+        return emBuilder;
     }
 
-    /**
-     * Specify which vehicles can be read by this GraphHopper instance. An encoding manager defines
-     * how data from every vehicle is written (und read) into edges of the graph.
-     */
-    public GraphHopper setEncodingManager(EncodingManager em) {
-        ensureNotLoaded();
-        this.encodingManager = em;
-        return this;
+    public EncodingManager getEncodingManager() {
+        if (encodingManager == null)
+            throw new IllegalStateException("EncodingManager not yet build");
+        return encodingManager;
     }
 
     public ElevationProvider getElevationProvider() {
@@ -240,7 +238,6 @@ public class GraphHopper implements GraphHopperAPI {
      *
      * <pre>
      * {@code
-     *   // make sure the encoding manager contains a "car" and a "bike" flag encoder
      *   hopper.setProfiles(
      *     new Profile("my_car").setVehicle("car").setWeighting("shortest"),
      *     new Profile("your_bike").setVehicle("bike").setWeighting("fastest")
@@ -265,7 +262,10 @@ public class GraphHopper implements GraphHopperAPI {
     }
 
     public GraphHopper setProfiles(List<Profile> profiles) {
-        profilesByName.clear();
+        if (!profilesByName.isEmpty())
+            throw new IllegalArgumentException("Cannot initialize profiles multiple times");
+        if (encodingManager != null)
+            throw new IllegalArgumentException("Cannot set profiles after EncodingManager was built");
         for (Profile profile : profiles) {
             Profile previous = this.profilesByName.put(profile.getName(), profile);
             if (previous != null)
@@ -373,7 +373,7 @@ public class GraphHopper implements GraphHopperAPI {
      */
     public LocationIndex getLocationIndex() {
         if (locationIndex == null)
-            throw new IllegalStateException("Location index not initialized");
+            throw new IllegalStateException("LocationIndex not initialized");
 
         return locationIndex;
     }
@@ -460,11 +460,16 @@ public class GraphHopper implements GraphHopperAPI {
 
         sortGraph = ghConfig.getBool("graph.do_sort", sortGraph);
         removeZipped = ghConfig.getBool("graph.remove_zipped", removeZipped);
-        EncodingManager encodingManager = createEncodingManager(ghConfig);
-        if (encodingManager != null) {
-            // overwrite EncodingManager object from configuration file
-            setEncodingManager(encodingManager);
-        }
+
+        if (encodingManager != null)
+            throw new IllegalStateException("Cannot call init twice. EncodingManager was already initialized.");
+
+        emBuilder.setEnableInstructions(ghConfig.getBool("datareader.instructions", true));
+        emBuilder.setPreferredLanguage(ghConfig.getString("datareader.preferred_language", ""));
+        emBuilder.setDateRangeParser(DateRangeParser.createInstance(ghConfig.getString("datareader.date_range_parser_day", "")));
+        setProfiles(ghConfig.getProfiles());
+        // currently we cannot require profiles at this point as GTFS module does not use them
+        encodingManager = buildEncodingManager(ghConfig, false);
 
         if (ghConfig.getString("graph.locktype", "native").equals("simple"))
             lockFactory = new SimpleFSLockFactory();
@@ -484,9 +489,6 @@ public class GraphHopper implements GraphHopperAPI {
         // optimizable prepare
         minNetworkSize = ghConfig.getInt("prepare.min_network_size", minNetworkSize);
 
-        // profiles
-        setProfiles(ghConfig.getProfiles());
-
         // prepare CH&LM
         chPreparationHandler.init(ghConfig);
         lmPreparationHandler.init(ghConfig);
@@ -513,23 +515,26 @@ public class GraphHopper implements GraphHopperAPI {
         return this;
     }
 
-    private EncodingManager createEncodingManager(GraphHopperConfig ghConfig) {
+    private EncodingManager buildEncodingManager(GraphHopperConfig ghConfig, boolean requireProfilesByName) {
         String flagEncodersStr = ghConfig.getString("graph.flag_encoders", "");
         String encodedValueStr = ghConfig.getString("graph.encoded_values", "");
-        if (flagEncodersStr.isEmpty() && encodedValueStr.isEmpty()) {
-            return null;
-        } else {
-            EncodingManager.Builder emBuilder = new EncodingManager.Builder();
-            if (!encodedValueStr.isEmpty())
-                emBuilder.addAll(tagParserFactory, encodedValueStr);
-            registerCustomEncodedValues(emBuilder);
-            if (!flagEncodersStr.isEmpty())
-                emBuilder.addAll(flagEncoderFactory, flagEncodersStr);
-            emBuilder.setEnableInstructions(ghConfig.getBool("datareader.instructions", true));
-            emBuilder.setPreferredLanguage(ghConfig.getString("datareader.preferred_language", ""));
-            emBuilder.setDateRangeParser(DateRangeParser.createInstance(ghConfig.getString("datareader.date_range_parser_day", "")));
-            return emBuilder.build();
+        Map<String, String> flagEncoderMap = new LinkedHashMap<>();
+        for (String encoderStr : Arrays.asList(flagEncodersStr.split(","))) {
+            String key = encoderStr.split("\\|")[0];
+            if (!key.isEmpty()) flagEncoderMap.put(key, encoderStr);
         }
+        if (requireProfilesByName && profilesByName.isEmpty())
+            throw new IllegalStateException("no profiles exist but assumed to create EncodingManager. E.g. provide them in GraphHopperConfig when calling GraphHopper.init");
+        for (Profile profile : profilesByName.values()) {
+            if (!flagEncoderMap.containsKey(profile.getVehicle()) || profile.isTurnCosts())
+                flagEncoderMap.put(profile.getVehicle(), profile.getVehicle() + (profile.isTurnCosts() ? "|turn_costs=true" : ""));
+        }
+        flagEncoderMap.values().stream().forEach(s -> emBuilder.addIfAbsent(flagEncoderFactory, s));
+        for (String tpStr : encodedValueStr.split(",")) {
+            if (!tpStr.isEmpty()) emBuilder.addIfAbsent(tagParserFactory, tpStr);
+        }
+
+        return emBuilder.build();
     }
 
     private static ElevationProvider createElevationProvider(GraphHopperConfig ghConfig) {
@@ -702,15 +707,17 @@ public class GraphHopper implements GraphHopperAPI {
 
         setGraphHopperLocation(graphHopperFolder);
 
-        if (encodingManager == null)
-            setEncodingManager(EncodingManager.create(encodedValueFactory, flagEncoderFactory, ghLocation));
-
         if (!allowWrites && dataAccessType.isMMap())
             dataAccessType = DAType.MMAP_RO;
+        if (encodingManager == null) {
+            StorableProperties properties = new StorableProperties(new GHDirectory(ghLocation, dataAccessType));
+            encodingManager = properties.loadExisting()
+                    ? EncodingManager.create(emBuilder, encodedValueFactory, flagEncoderFactory, properties)
+                    : buildEncodingManager(new GraphHopperConfig(), true);
+        }
 
         GHDirectory dir = new GHDirectory(ghLocation, dataAccessType);
         ghStorage = new GraphHopperStorage(dir, encodingManager, hasElevation(), encodingManager.needsTurnCostsSupport(), defaultSegmentSize);
-
         checkProfilesConsistency();
 
         if (lmPreparationHandler.isEnabled())
@@ -753,6 +760,7 @@ public class GraphHopper implements GraphHopperAPI {
     }
 
     private void checkProfilesConsistency() {
+        EncodingManager encodingManager = getEncodingManager();
         for (Profile profile : profilesByName.values()) {
             if (!encodingManager.hasEncoder(profile.getVehicle())) {
                 throw new IllegalArgumentException("Unknown vehicle '" + profile.getVehicle() + "' in profile: " + profile + ". Make sure all vehicles used in 'profiles' exist in 'graph.flag_encoders'");
@@ -906,9 +914,6 @@ public class GraphHopper implements GraphHopperAPI {
         }
     }
 
-    protected void registerCustomEncodedValues(EncodingManager.Builder emBuilder) {
-    }
-
     protected void importPublicTransit() {
     }
 
@@ -945,7 +950,7 @@ public class GraphHopper implements GraphHopperAPI {
     }
 
     protected WeightingFactory createWeightingFactory() {
-        return new DefaultWeightingFactory(ghStorage, encodingManager);
+        return new DefaultWeightingFactory(ghStorage, getEncodingManager());
     }
 
     @Override
diff --git a/core/src/main/java/com/graphhopper/routing/util/DefaultFlagEncoderFactory.java b/core/src/main/java/com/graphhopper/routing/util/DefaultFlagEncoderFactory.java
index 72dd9467d..bf727838c 100644
--- a/core/src/main/java/com/graphhopper/routing/util/DefaultFlagEncoderFactory.java
+++ b/core/src/main/java/com/graphhopper/routing/util/DefaultFlagEncoderFactory.java
@@ -57,6 +57,6 @@ public class DefaultFlagEncoderFactory implements FlagEncoderFactory {
         if (name.equals(WHEELCHAIR))
             return new WheelchairFlagEncoder(configuration);
 
-        throw new IllegalArgumentException("entry in encoder list not supported " + name);
+        throw new IllegalArgumentException("entry in encoder list not supported: " + name);
     }
 }
diff --git a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java
index cc5f60498..99c18f6ec 100644
--- a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java
+++ b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java
@@ -24,13 +24,15 @@ import com.graphhopper.reader.ReaderWay;
 import com.graphhopper.reader.osm.conditional.DateRangeParser;
 import com.graphhopper.routing.ev.*;
 import com.graphhopper.routing.util.parsers.*;
-import com.graphhopper.storage.*;
+import com.graphhopper.storage.Graph;
+import com.graphhopper.storage.IntsRef;
+import com.graphhopper.storage.StorableProperties;
 import com.graphhopper.util.EdgeIteratorState;
-import com.graphhopper.util.Helper;
 import com.graphhopper.util.PMap;
 
 import java.util.*;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 import static com.graphhopper.util.Helper.toLowerCase;
 
@@ -58,22 +60,19 @@ public class EncodingManager implements EncodedValueLookup {
 
     /**
      * Instantiate manager with the given list of encoders. The manager knows several default
-     * encoders ignoring case.
-     *
-     * @param flagEncodersStr comma delimited list of encoders. The order does not matter.
+     * encoders using DefaultFlagEncoderFactory.
      */
     public static EncodingManager create(String flagEncodersStr) {
         return create(new DefaultFlagEncoderFactory(), flagEncodersStr);
     }
 
     public static EncodingManager create(FlagEncoderFactory factory, String flagEncodersStr) {
-        return createBuilder(parseEncoderString(factory, flagEncodersStr)).build();
+        return createBuilder(Arrays.stream(flagEncodersStr.split(",")).filter(s -> !s.trim().isEmpty()).
+                map(s -> parseEncoderString(factory, s)).collect(Collectors.toList())).build();
     }
 
     /**
      * Instantiate manager with the given list of encoders.
-     *
-     * @param flagEncoders comma delimited list of encoders. The order does not matter.
      */
     public static EncodingManager create(FlagEncoder... flagEncoders) {
         return create(Arrays.asList(flagEncoders));
@@ -81,8 +80,6 @@ public class EncodingManager implements EncodedValueLookup {
 
     /**
      * Instantiate manager with the given list of encoders.
-     *
-     * @param flagEncoders comma delimited list of encoders. The order does not matter.
      */
     public static EncodingManager create(List<? extends FlagEncoder> flagEncoders) {
         return createBuilder(flagEncoders).build();
@@ -100,25 +97,15 @@ public class EncodingManager implements EncodedValueLookup {
      * Create the EncodingManager from the provided GraphHopper location. Throws an
      * IllegalStateException if it fails. Used if no EncodingManager specified on load.
      */
-    public static EncodingManager create(EncodedValueFactory evFactory, FlagEncoderFactory flagEncoderFactory, String ghLoc) {
-        Directory dir = new RAMDirectory(ghLoc, true);
-        StorableProperties properties = new StorableProperties(dir);
-        if (!properties.loadExisting())
-            throw new IllegalStateException("Cannot load properties to fetch EncodingManager configuration at: "
-                    + dir.getLocation());
-
-        EncodingManager.Builder builder = new EncodingManager.Builder();
+    public static EncodingManager create(EncodingManager.Builder builder, EncodedValueFactory evFactory, FlagEncoderFactory flagEncoderFactory, StorableProperties properties) {
         String encodedValuesStr = properties.get("graph.encoded_values");
-        if (!Helper.isEmpty(encodedValuesStr))
-            builder.addAll(evFactory, encodedValuesStr);
+        for (String evString : encodedValuesStr.split(",")) {
+            builder.addIfAbsent(evFactory, evString);
+        }
         String flagEncoderValuesStr = properties.get("graph.flag_encoders");
-        if (!Helper.isEmpty(flagEncoderValuesStr))
-            builder.addAll(flagEncoderFactory, flagEncoderValuesStr);
-
-        if (Helper.isEmpty(flagEncoderValuesStr) && Helper.isEmpty(encodedValuesStr))
-            throw new IllegalStateException("EncodingManager was not configured. And no one was found in the graph: "
-                    + dir.getLocation());
-
+        for (String encoderString : flagEncoderValuesStr.split(",")) {
+            builder.addIfAbsent(flagEncoderFactory, encoderString);
+        }
         return builder.build();
     }
 
@@ -144,9 +131,9 @@ public class EncodingManager implements EncodedValueLookup {
     public static class Builder {
         private EncodingManager em;
         private DateRangeParser dateRangeParser;
-        private final List<AbstractFlagEncoder> flagEncoderList = new ArrayList<>();
-        private final List<EncodedValue> encodedValueList = new ArrayList<>();
-        private final List<TagParser> tagParsers = new ArrayList<>();
+        private final Map<String, AbstractFlagEncoder> flagEncoderMap = new LinkedHashMap<>();
+        private final Map<String, EncodedValue> encodedValueMap = new LinkedHashMap<>();
+        private final Set<TagParser> tagParserSet = new LinkedHashSet<>();
         private final List<TurnCostParser> turnCostParsers = new ArrayList<>();
         private final List<RelationTagParser> relationTagParsers = new ArrayList<>();
 
@@ -181,27 +168,33 @@ public class EncodingManager implements EncodedValueLookup {
             return this;
         }
 
-        /**
-         * For backward compatibility provide a way to add multiple FlagEncoders
-         */
-        public Builder addAll(FlagEncoderFactory factory, String flagEncodersStr) {
+        public boolean addIfAbsent(FlagEncoderFactory factory, String flagEncoderString) {
             check();
-            for (FlagEncoder fe : parseEncoderString(factory, flagEncodersStr)) {
-                flagEncoderList.add((AbstractFlagEncoder) fe);
-            }
-            return this;
+            String key = flagEncoderString.split("\\|")[0].trim();
+            if (flagEncoderMap.containsKey(key))
+                return false;
+            FlagEncoder fe = parseEncoderString(factory, flagEncoderString);
+            flagEncoderMap.put(fe.toString(), (AbstractFlagEncoder) fe);
+            return true;
         }
 
-        public Builder addAll(EncodedValueFactory factory, String encodedValueString) {
+        public boolean addIfAbsent(EncodedValueFactory factory, String encodedValueString) {
             check();
-            em.add(encodedValueList, factory, encodedValueString);
-            return this;
+            String key = encodedValueString.split("\\|")[0].trim();
+            if (encodedValueMap.containsKey(key))
+                return false;
+            EncodedValue ev = parseEncodedValueString(factory, encodedValueString);
+            encodedValueMap.put(ev.getName(), ev);
+            return true;
         }
 
-        public Builder addAll(TagParserFactory factory, String tagParserString) {
+        public boolean addIfAbsent(TagParserFactory factory, String tagParserString) {
             check();
-            em.add(tagParsers, factory, tagParserString);
-            return this;
+            tagParserString = tagParserString.trim();
+            if (tagParserString.isEmpty()) return false;
+
+            TagParser tagParser = em.parseEncodedValueString(factory, tagParserString);
+            return tagParserSet.add(tagParser);
         }
 
         public Builder addTurnCostParser(TurnCostParser parser) {
@@ -218,19 +211,17 @@ public class EncodingManager implements EncodedValueLookup {
 
         public Builder add(FlagEncoder encoder) {
             check();
-            flagEncoderList.add((AbstractFlagEncoder) encoder);
+            if (flagEncoderMap.containsKey(encoder.toString()))
+                throw new IllegalArgumentException("FlagEncoder already exists: " + encoder);
+            flagEncoderMap.put(encoder.toString(), (AbstractFlagEncoder) encoder);
             return this;
         }
 
         public Builder add(EncodedValue encodedValue) {
             check();
-            encodedValueList.add(encodedValue);
-            return this;
-        }
-
-        public Builder setDateRangeParser(DateRangeParser dateRangeParser) {
-            check();
-            this.dateRangeParser = dateRangeParser;
+            if (encodedValueMap.containsKey(encodedValue.getName()))
+                throw new IllegalArgumentException("EncodedValue already exists: " + encodedValue.getName());
+            encodedValueMap.put(encodedValue.getName(), encodedValue);
             return this;
         }
 
@@ -240,7 +231,15 @@ public class EncodingManager implements EncodedValueLookup {
          */
         public Builder add(TagParser tagParser) {
             check();
-            tagParsers.add(tagParser);
+            if (!tagParserSet.add(tagParser))
+                throw new IllegalArgumentException("TagParser already exists: " + tagParser);
+
+            return this;
+        }
+
+        public Builder setDateRangeParser(DateRangeParser dateRangeParser) {
+            check();
+            this.dateRangeParser = dateRangeParser;
             return this;
         }
 
@@ -296,7 +295,7 @@ public class EncodingManager implements EncodedValueLookup {
             }
 
             List<SpatialRuleParser> insertLater = new ArrayList<>();
-            for (TagParser tagParser : tagParsers) {
+            for (TagParser tagParser : tagParserSet) {
                 if (SpatialRuleParser.class.isAssignableFrom(tagParser.getClass())) {
                     insertLater.add((SpatialRuleParser) tagParser);
                 } else {
@@ -304,7 +303,7 @@ public class EncodingManager implements EncodedValueLookup {
                 }
             }
 
-            for (EncodedValue ev : encodedValueList) {
+            for (EncodedValue ev : encodedValueMap.values()) {
                 em.addEncodedValue(ev, false);
             }
 
@@ -333,7 +332,7 @@ public class EncodingManager implements EncodedValueLookup {
             if (dateRangeParser == null)
                 dateRangeParser = new DateRangeParser(DateRangeParser.createCalendar());
 
-            for (AbstractFlagEncoder encoder : flagEncoderList) {
+            for (AbstractFlagEncoder encoder : flagEncoderMap.values()) {
                 if (encoder instanceof BikeCommonFlagEncoder) {
                     if (!em.hasEncodedValue(RouteNetwork.key("bike")))
                         _addRelationTagParser(new OSMBikeNetworkTagParser());
@@ -346,7 +345,7 @@ public class EncodingManager implements EncodedValueLookup {
                 }
             }
 
-            for (AbstractFlagEncoder encoder : flagEncoderList) {
+            for (AbstractFlagEncoder encoder : flagEncoderMap.values()) {
                 encoder.init(dateRangeParser);
                 em.addEncoder(encoder);
             }
@@ -356,7 +355,7 @@ public class EncodingManager implements EncodedValueLookup {
             }
 
             // FlagEncoder can demand TurnCostParsers => add them after the explicitly added ones
-            for (AbstractFlagEncoder encoder : flagEncoderList) {
+            for (AbstractFlagEncoder encoder : flagEncoderMap.values()) {
                 if (encoder.supportsTurnCosts() && !em.turnCostParsers.containsKey(encoder.toString()))
                     _addTurnCostParser(new OSMTurnRelationParser(encoder.toString(), encoder.getMaxTurnCosts(),
                             OSMRoadAccessParser.toOSMRestrictions(encoder.getTransportationMode())));
@@ -371,62 +370,44 @@ public class EncodingManager implements EncodedValueLookup {
         }
     }
 
-    static List<FlagEncoder> parseEncoderString(FlagEncoderFactory factory, String encoderList) {
-        if (encoderList.contains(":"))
-            throw new IllegalArgumentException("EncodingManager does no longer use reflection instantiate encoders directly.");
-
-        if (!encoderList.equals(toLowerCase(encoderList)))
-            throw new IllegalArgumentException("Since 0.7 EncodingManager does no longer accept upper case profiles: " + encoderList);
+    static FlagEncoder parseEncoderString(FlagEncoderFactory factory, String encoderString) {
+        if (!encoderString.equals(toLowerCase(encoderString)))
+            throw new IllegalArgumentException("An upper case name for the FlagEncoder is not allowed: " + encoderString);
 
-        String[] entries = encoderList.split(",");
-        List<FlagEncoder> resultEncoders = new ArrayList<>();
+        encoderString = encoderString.trim();
+        if (encoderString.isEmpty())
+            throw new IllegalArgumentException("FlagEncoder cannot be empty. " + encoderString);
 
-        for (String entry : entries) {
-            entry = toLowerCase(entry.trim());
-            if (entry.isEmpty())
-                continue;
-
-            String entryVal = "";
-            if (entry.contains("|")) {
-                entryVal = entry;
-                entry = entry.split("\\|")[0];
-            }
-            PMap configuration = new PMap(entryVal);
-            resultEncoders.add(factory.createFlagEncoder(entry, configuration));
+        String entryVal = "";
+        if (encoderString.contains("|")) {
+            entryVal = encoderString;
+            encoderString = encoderString.split("\\|")[0];
         }
-        return resultEncoders;
+        PMap configuration = new PMap(entryVal);
+        return factory.createFlagEncoder(encoderString, configuration);
     }
 
-    private void add(List<EncodedValue> returnList, EncodedValueFactory factory, String evList) {
-        if (!evList.equals(toLowerCase(evList)))
-            throw new IllegalArgumentException("Use lower case for EncodedValues: " + evList);
+    static EncodedValue parseEncodedValueString(EncodedValueFactory factory, String encodedValueString) {
+        if (!encodedValueString.equals(toLowerCase(encodedValueString)))
+            throw new IllegalArgumentException("Use lower case for EncodedValues: " + encodedValueString);
 
-        for (String entry : evList.split(",")) {
-            entry = toLowerCase(entry.trim());
-            if (entry.isEmpty())
-                continue;
+        encodedValueString = encodedValueString.trim();
+        if (encodedValueString.isEmpty())
+            throw new IllegalArgumentException("EncodedValue cannot be empty. " + encodedValueString);
 
-            EncodedValue evObject = factory.create(entry);
-            PMap map = new PMap(entry);
-            if (!map.has("version"))
-                throw new IllegalArgumentException("encoded value must have a version specified but it was " + entry);
-            returnList.add(evObject);
-        }
+        EncodedValue evObject = factory.create(encodedValueString);
+        PMap map = new PMap(encodedValueString);
+        if (!map.has("version"))
+            throw new IllegalArgumentException("EncodedValue must have a version specified but it was " + encodedValueString);
+        return evObject;
     }
 
-    private void add(List<TagParser> returnList, TagParserFactory factory, String tpList) {
-        if (!tpList.equals(toLowerCase(tpList)))
-            throw new IllegalArgumentException("Use lower case for TagParser: " + tpList);
+    private TagParser parseEncodedValueString(TagParserFactory factory, String tagParserString) {
+        if (!tagParserString.equals(toLowerCase(tagParserString)))
+            throw new IllegalArgumentException("Use lower case for TagParser: " + tagParserString);
 
-        for (String entry : tpList.split(",")) {
-            entry = entry.trim();
-            if (entry.isEmpty())
-                continue;
-
-            PMap map = new PMap(entry);
-            TagParser tp = factory.create(entry, map);
-            returnList.add(tp);
-        }
+        PMap map = new PMap(tagParserString);
+        return factory.create(tagParserString, map);
     }
 
     static String fixWayName(String str) {
@@ -455,11 +436,6 @@ public class EncodingManager implements EncodedValueLookup {
     }
 
     private void addEncoder(AbstractFlagEncoder encoder) {
-        for (FlagEncoder fe : edgeEncoders) {
-            if (fe.toString().equals(encoder.toString()))
-                throw new IllegalArgumentException("Cannot register edge encoder. Name already exists: " + fe.toString());
-        }
-
         int encoderCount = edgeEncoders.size();
 
         encoder.setEncodedValueLookup(this);
@@ -473,8 +449,6 @@ public class EncodingManager implements EncodedValueLookup {
     }
 
     private void addEncodedValue(EncodedValue ev, boolean withNamespace) {
-        if (hasEncodedValue(ev.getName()))
-            throw new IllegalStateException("EncodedValue " + ev.getName() + " already exists " + encodedValueMap.get(ev.getName()) + " vs " + ev);
         String normalizedKey = ev.getName().replaceAll(SPECIAL_SEPARATOR, "_");
         if (hasEncodedValue(normalizedKey))
             throw new IllegalStateException("EncodedValue " + ev.getName() + " collides with " + normalizedKey);
@@ -507,7 +481,7 @@ public class EncodingManager implements EncodedValueLookup {
                 return encoder;
         }
         if (throwExc)
-            throw new IllegalArgumentException("Encoder for " + name + " not found. Existing: " + toFlagEncodersAsString());
+            throw new IllegalArgumentException("FlagEncoder for " + name + " not found. Existing: " + toFlagEncodersAsString());
         return null;
     }
 
diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java b/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java
index 0a5f53645..7d705a2f0 100644
--- a/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java
+++ b/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java
@@ -74,6 +74,6 @@ public class DefaultTagParserFactory implements TagParserFactory {
             throw new IllegalArgumentException("The property spatial_rules.borders_directory is required in the configuration " +
                     "when using 'country' in encoded_values");
 
-        throw new IllegalArgumentException("entry in encoder list not supported " + name);
+        throw new IllegalArgumentException("DefaultTagParserFactory cannot find: " + name);
     }
 }
diff --git a/core/src/main/java/com/graphhopper/storage/GraphBuilder.java b/core/src/main/java/com/graphhopper/storage/GraphBuilder.java
index cb968c6be..a8c7eca8d 100644
--- a/core/src/main/java/com/graphhopper/storage/GraphBuilder.java
+++ b/core/src/main/java/com/graphhopper/storage/GraphBuilder.java
@@ -97,11 +97,6 @@ public class GraphBuilder {
         return setDir(new RAMDirectory(location, store));
     }
 
-    public GraphBuilder setBytes(long bytes) {
-        this.bytes = bytes;
-        return this;
-    }
-
     public GraphBuilder set3D(boolean withElevation) {
         this.elevation = withElevation;
         return this;
diff --git a/core/src/main/java/com/graphhopper/util/GHUtility.java b/core/src/main/java/com/graphhopper/util/GHUtility.java
index 6527d06ff..a78ba0851 100644
--- a/core/src/main/java/com/graphhopper/util/GHUtility.java
+++ b/core/src/main/java/com/graphhopper/util/GHUtility.java
@@ -472,7 +472,6 @@ public class GHUtility {
                 .set3D(is3D)
                 .setDir(outdir)
                 .setCHConfigs(store.getCHConfigs())
-                .setBytes(store.getNodes())
                 .create();
     }
 
diff --git a/docs/core/create-new-flagencoder.md b/docs/core/create-new-flagencoder.md
index 33dc3132b..47e331dc1 100644
--- a/docs/core/create-new-flagencoder.md
+++ b/docs/core/create-new-flagencoder.md
@@ -34,4 +34,5 @@ and call edge.fetchWayGeometry(FetchMode.ALL) or again, see Bike2WeightFlagEncod
 ## Add to the core
 
 If you want to include your FlagEncoder in GraphHopper and e.g. still want to use the config.yml
-you can use a subclass of DefaultFlagEncoderFactory and use the configuration object to change different properties.
+you can use a subclass of DefaultFlagEncoderFactory, set it to to the GraphHopper instance
+and use the configuration object to change different properties.
diff --git a/docs/core/routing.md b/docs/core/routing.md
index afedc35d8..22ba0a9f1 100644
--- a/docs/core/routing.md
+++ b/docs/core/routing.md
@@ -21,9 +21,6 @@ can disable speed mode using `ch.disable=true`. In this case either hybrid mode
 chosen profile) or flexible mode will be used. To use flexible mode in the presence of an LM preparation you need to 
 also set `lm.disable=true`.
 
-If you need multiple vehicle profiles you can specify a list of vehicle profiles (see
-config.yml e.g. `graph.flag_encoders=car,bike` or use `EncodingManager.create("car,bike")`). 
-
 To calculate a route you have to pick one vehicle and optionally an algorithm like
 `bidirectional_astar`, see the test speedModeVersusHybridMode.
 
diff --git a/example/src/main/java/com/graphhopper/example/IsochroneExample.java b/example/src/main/java/com/graphhopper/example/IsochroneExample.java
index 528adfc55..39c17f41f 100644
--- a/example/src/main/java/com/graphhopper/example/IsochroneExample.java
+++ b/example/src/main/java/com/graphhopper/example/IsochroneExample.java
@@ -48,7 +48,6 @@ public class IsochroneExample {
         GraphHopper hopper = new GraphHopper();
         hopper.setOSMFile(ghLoc);
         hopper.setGraphHopperLocation("target/isochrone-graph-cache");
-        hopper.setEncodingManager(EncodingManager.create("car"));
         hopper.setProfiles(new Profile("car").setVehicle("car").setWeighting("fastest").setTurnCosts(false));
         hopper.importOrLoad();
         return hopper;
diff --git a/example/src/main/java/com/graphhopper/example/LocationIndexExample.java b/example/src/main/java/com/graphhopper/example/LocationIndexExample.java
index 29f3eec05..16bc9ecca 100644
--- a/example/src/main/java/com/graphhopper/example/LocationIndexExample.java
+++ b/example/src/main/java/com/graphhopper/example/LocationIndexExample.java
@@ -1,6 +1,7 @@
 package com.graphhopper.example;
 
 import com.graphhopper.GraphHopper;
+import com.graphhopper.config.Profile;
 import com.graphhopper.routing.util.CarFlagEncoder;
 import com.graphhopper.routing.util.EdgeFilter;
 import com.graphhopper.routing.util.EncodingManager;
@@ -20,7 +21,8 @@ public class LocationIndexExample {
     }
 
     public static void graphhopperLocationIndex(String relDir) {
-        GraphHopper hopper = new GraphHopper().setEncodingManager(EncodingManager.create(new CarFlagEncoder()));
+        GraphHopper hopper = new GraphHopper();
+        hopper.setProfiles(new Profile("car").setVehicle("car").setWeighting("fastest"));
         hopper.setOSMFile(relDir + "core/files/andorra.osm.pbf");
         hopper.setGraphHopperLocation("./target/locationindex-graph-cache");
         hopper.importOrLoad();
diff --git a/example/src/main/java/com/graphhopper/example/LowLevelAPIExample.java b/example/src/main/java/com/graphhopper/example/LowLevelAPIExample.java
index 2c322af03..1c8835565 100644
--- a/example/src/main/java/com/graphhopper/example/LowLevelAPIExample.java
+++ b/example/src/main/java/com/graphhopper/example/LowLevelAPIExample.java
@@ -16,6 +16,11 @@ import com.graphhopper.util.EdgeIteratorState;
 import com.graphhopper.util.Helper;
 import com.graphhopper.util.PMap;
 
+/**
+ * Use this example to gain access to the low level API of GraphHopper.
+ * If you want to keep using the GraphHopper class but want to customize the internal EncodingManager
+ * you can use the hook GraphHopper.customizeEncodingManager.
+ */
 public class LowLevelAPIExample {
     public static void main(String[] args) {
         createAndSaveGraph();
diff --git a/example/src/main/java/com/graphhopper/example/RoutingExample.java b/example/src/main/java/com/graphhopper/example/RoutingExample.java
index 2e1c32b4d..19a1dad4e 100644
--- a/example/src/main/java/com/graphhopper/example/RoutingExample.java
+++ b/example/src/main/java/com/graphhopper/example/RoutingExample.java
@@ -8,6 +8,7 @@ import com.graphhopper.config.CHProfile;
 import com.graphhopper.config.LMProfile;
 import com.graphhopper.config.Profile;
 import com.graphhopper.routing.util.EncodingManager;
+import com.graphhopper.routing.util.parsers.OSMSurfaceParser;
 import com.graphhopper.routing.weighting.custom.CustomProfile;
 import com.graphhopper.util.*;
 import com.graphhopper.util.shapes.GHPoint;
@@ -37,7 +38,6 @@ public class RoutingExample {
         hopper.setOSMFile(ghLoc);
         // specify where to store graphhopper files
         hopper.setGraphHopperLocation("target/routing-graph-cache");
-        hopper.setEncodingManager(EncodingManager.create("car"));
 
         // see docs/core/profiles.md to learn more about profiles
         hopper.setProfiles(new Profile("car").setVehicle("car").setWeighting("fastest").setTurnCosts(false));
@@ -121,7 +121,6 @@ public class RoutingExample {
         GraphHopper hopper = new GraphHopper();
         hopper.setOSMFile(ghLoc);
         hopper.setGraphHopperLocation("target/routing-custom-graph-cache");
-        hopper.setEncodingManager(EncodingManager.create("car"));
         hopper.setProfiles(new CustomProfile("car_custom").setCustomModel(new CustomModel()).setVehicle("car"));
 
         // The hybrid mode uses the "landmark algorithm" and is up to 15x faster than the flexible mode (Dijkstra).
diff --git a/example/src/main/java/com/graphhopper/example/RoutingExampleTC.java b/example/src/main/java/com/graphhopper/example/RoutingExampleTC.java
index 73c5ae2c8..c356f2c61 100644
--- a/example/src/main/java/com/graphhopper/example/RoutingExampleTC.java
+++ b/example/src/main/java/com/graphhopper/example/RoutingExampleTC.java
@@ -70,8 +70,6 @@ public class RoutingExampleTC {
         hopper.setGraphHopperLocation("target/routing-tc-graph-cache");
         // by enabling turn costs for the FlagEncoder, turn restriction constraints like 'no_left_turn' will be taken
         // from OSM
-        EncodingManager encodingManager = EncodingManager.create("car|turn_costs=true");
-        hopper.setEncodingManager(encodingManager);
         Profile profile = new Profile("car").setVehicle("car").setWeighting("fastest")
                 // to actually use the turn restrictions when routing we have to enable turn costs for our routing profile
                 .setTurnCosts(true)
diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphHopperGtfs.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphHopperGtfs.java
index 4327d77f1..a11fdbdf5 100644
--- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphHopperGtfs.java
+++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphHopperGtfs.java
@@ -56,11 +56,7 @@ public class GraphHopperGtfs extends GraphHopper {
 
     public GraphHopperGtfs(GraphHopperConfig ghConfig) {
         this.ghConfig = ghConfig;
-    }
-
-    @Override
-    protected void registerCustomEncodedValues(EncodingManager.Builder emBuilder) {
-        PtEncodedValues.createAndAddEncodedValues(emBuilder);
+        PtEncodedValues.createAndAddEncodedValues(getEncodingManagerBuilder());
     }
 
     @Override
diff --git a/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java b/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java
index 65422f8e4..d4e3624a0 100644
--- a/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java
+++ b/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java
@@ -136,7 +136,8 @@ public class MapMatchingResource {
                     setPathDetailsBuilders(graphHopper.getPathDetailsBuilderFactory(), pathDetails).
                     setDouglasPeucker(peucker).
                     setSimplifyResponse(minPathPrecision > 0);
-            ResponsePath responsePath = pathMerger.doWork(PointList.EMPTY, Collections.singletonList(matchResult.getMergedPath()), graphHopper.getEncodingManager(), tr);
+            ResponsePath responsePath = pathMerger.doWork(PointList.EMPTY, Collections.singletonList(matchResult.getMergedPath()),
+                    graphHopper.getEncodingManager(), tr);
 
             // GraphHopper thinks an empty path is an invalid path, and further that an invalid path is still a path but
             // marked with a non-empty list of Exception objects. I disagree, so I clear it.


Test patch:
diff --git a/core/src/test/java/com/graphhopper/GraphHopperAPITest.java b/core/src/test/java/com/graphhopper/GraphHopperAPITest.java
index 93d2cb711..abaa026b6 100644
--- a/core/src/test/java/com/graphhopper/GraphHopperAPITest.java
+++ b/core/src/test/java/com/graphhopper/GraphHopperAPITest.java
@@ -65,10 +65,10 @@ public class GraphHopperAPITest {
         GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 4).setDistance(40));
         GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 3).setDistance(40));
 
-        GraphHopper instance = createGraphHopper(vehicle).
+        GraphHopper instance = new GraphHopper().
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setStoreOnFlush(false).
-                loadGraph(graph);
+                loadGraph(graph, em);
         // 3 -> 0
         GHResponse rsp = instance.route(new GHRequest(42, 10.4, 42, 10).setProfile(profile));
         assertFalse(rsp.getErrors().toString(), rsp.hasErrors());
@@ -93,10 +93,10 @@ public class GraphHopperAPITest {
         GraphHopperStorage graph = new GraphBuilder(em).create();
         initGraph(graph, em.getEncoder(vehicle));
 
-        GraphHopper instance = createGraphHopper(vehicle).
+        GraphHopper instance = new GraphHopper().
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setStoreOnFlush(false).
-                loadGraph(graph);
+                loadGraph(graph, em);
         GHResponse rsp = instance.route(new GHRequest(42, 10, 42, 10.4).setProfile(profile));
         assertTrue(rsp.hasErrors());
 
@@ -129,10 +129,11 @@ public class GraphHopperAPITest {
         GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(10));
 
         final AtomicInteger counter = new AtomicInteger(0);
-        GraphHopper instance = createGraphHopper(vehicle)
+        GraphHopper instance = new GraphHopper()
+                .setProfiles(new Profile(vehicle).setVehicle(vehicle).setWeighting("fastest"))
                 .setElevation(true)
                 .setGraphHopperLocation(loc)
-                .loadGraph(graph);
+                .loadGraph(graph, encodingManager);
         instance.flush();
         instance.close();
         assertEquals(0, counter.get());
@@ -144,7 +145,6 @@ public class GraphHopperAPITest {
                 super.interpolateBridgesTunnelsAndFerries();
             }
         }
-                .setEncodingManager(encodingManager)
                 .setProfiles(new Profile(vehicle).setVehicle(vehicle).setWeighting("fastest"))
                 .setElevation(true);
         instance.load(loc);
@@ -159,7 +159,6 @@ public class GraphHopperAPITest {
                 super.interpolateBridgesTunnelsAndFerries();
             }
         }
-                .setEncodingManager(encodingManager)
                 .setProfiles(new Profile(vehicle).setVehicle(vehicle).setWeighting("fastest"))
                 .setElevation(true);
         instance.load(loc);
@@ -175,7 +174,7 @@ public class GraphHopperAPITest {
         String profile = "profile";
         String vehicle = "car";
         String weighting = "fastest";
-        GraphHopper instance = createGraphHopper(vehicle).
+        GraphHopper instance = new GraphHopper().
                 setProfiles(new Profile(profile).setVehicle(vehicle).setVehicle(weighting)).
                 setStoreOnFlush(false);
         try {
@@ -185,7 +184,8 @@ public class GraphHopperAPITest {
             assertTrue(ex.getMessage(), ex.getMessage().startsWith("Do a successful call to load or importOrLoad before routing"));
         }
 
-        instance = createGraphHopper(vehicle);
+        instance = new GraphHopper()
+                .setProfiles(new Profile(vehicle).setVehicle(vehicle).setWeighting("fastest"));
         try {
             instance.route(new GHRequest(42, 10.4, 42, 10).setProfile(profile));
             fail();
@@ -193,10 +193,4 @@ public class GraphHopperAPITest {
             assertTrue(ex.getMessage(), ex.getMessage().startsWith("Do a successful call to load or importOrLoad before routing"));
         }
     }
-
-    private GraphHopper createGraphHopper(String vehicle) {
-        return new GraphHopper()
-                .setEncodingManager(EncodingManager.create(vehicle))
-                .setProfiles(new Profile(vehicle).setVehicle(vehicle).setWeighting("fastest"));
-    }
 }
diff --git a/core/src/test/java/com/graphhopper/GraphHopperProfileTest.java b/core/src/test/java/com/graphhopper/GraphHopperProfileTest.java
index d1848a315..b5375a4a8 100644
--- a/core/src/test/java/com/graphhopper/GraphHopperProfileTest.java
+++ b/core/src/test/java/com/graphhopper/GraphHopperProfileTest.java
@@ -24,7 +24,7 @@ import com.graphhopper.config.LMProfile;
 import com.graphhopper.config.Profile;
 import com.graphhopper.jackson.Jackson;
 import com.graphhopper.jackson.ProfileMixIn;
-import com.graphhopper.routing.util.EncodingManager;
+import com.graphhopper.routing.util.CarFlagEncoder;
 import org.junit.jupiter.api.Test;
 
 import java.io.IOException;
@@ -53,7 +53,7 @@ public class GraphHopperProfileTest {
 
     @Test
     public void duplicateProfileName_error() {
-        final GraphHopper hopper = createHopper(EncodingManager.create("car"));
+        final GraphHopper hopper = createHopper();
         assertIllegalArgument(new Runnable() {
             @Override
             public void run() {
@@ -68,31 +68,44 @@ public class GraphHopperProfileTest {
 
     @Test
     public void vehicleDoesNotExist_error() {
-        final GraphHopper hopper = createHopper(EncodingManager.create("car"));
-        hopper.setProfiles(new Profile("profile").setVehicle("your_car"));
+        final GraphHopper hopper = new GraphHopper();
+        hopper.getEncodingManagerBuilder().add(new CarFlagEncoder());
+        hopper.setGraphHopperLocation(GH_LOCATION).setStoreOnFlush(false).
+                setProfiles(new Profile("profile").setVehicle("your_car"));
         assertIllegalArgument(new Runnable() {
             @Override
             public void run() {
                 hopper.load(GH_LOCATION);
             }
-        }, "Unknown vehicle 'your_car' in profile: name=profile");
+        }, "entry in encoder list not supported: your_car");
     }
 
     @Test
-    public void vehicleWithoutTurnCostSupport_error() {
-        final GraphHopper hopper = createHopper(EncodingManager.create("car"));
-        hopper.setProfiles(new Profile("profile").setVehicle("car").setTurnCosts(true));
+    public void vehicleDoesNotExist_error2() {
+        final GraphHopper hopper = new GraphHopper().setGraphHopperLocation(GH_LOCATION).setStoreOnFlush(false).
+                setProfiles(new Profile("profile").setVehicle("your_car"));
+
         assertIllegalArgument(new Runnable() {
             @Override
             public void run() {
                 hopper.load(GH_LOCATION);
             }
-        }, "The profile 'profile' was configured with 'turn_costs=true', but the corresponding vehicle 'car' does not support turn costs");
+        }, "entry in encoder list not supported: your_car");
+    }
+
+    @Test
+    public void oneVehicleWithoutTurnCostSupport_noerror() {
+        final GraphHopper hopper = createHopper();
+        // no error even if profile without turn costs is specified first
+        hopper.setProfiles(
+                new Profile("profile1").setVehicle("car").setTurnCosts(false),
+                new Profile("profile2").setVehicle("car").setTurnCosts(true));
+        hopper.load(GH_LOCATION);
     }
 
     @Test
     public void profileWithUnknownWeighting_error() {
-        final GraphHopper hopper = createHopper(EncodingManager.create("car"));
+        final GraphHopper hopper = createHopper();
         hopper.setProfiles(new Profile("profile").setVehicle("car").setWeighting("your_weighting"));
         assertIllegalArgument(new Runnable() {
                                   @Override
@@ -107,7 +120,7 @@ public class GraphHopperProfileTest {
 
     @Test
     public void chProfileDoesNotExist_error() {
-        final GraphHopper hopper = createHopper(EncodingManager.create("car"));
+        final GraphHopper hopper = createHopper();
         hopper.setProfiles(new Profile("profile1").setVehicle("car"));
         hopper.getCHPreparationHandler().setCHProfiles(new CHProfile("other_profile"));
         assertIllegalArgument(new Runnable() {
@@ -120,7 +133,7 @@ public class GraphHopperProfileTest {
 
     @Test
     public void duplicateCHProfile_error() {
-        final GraphHopper hopper = createHopper(EncodingManager.create("car"));
+        final GraphHopper hopper = createHopper();
         hopper.setProfiles(new Profile("profile").setVehicle("car"));
         hopper.getCHPreparationHandler().setCHProfiles(
                 new CHProfile("profile"),
@@ -136,7 +149,7 @@ public class GraphHopperProfileTest {
 
     @Test
     public void lmProfileDoesNotExist_error() {
-        final GraphHopper hopper = createHopper(EncodingManager.create("car"));
+        final GraphHopper hopper = createHopper();
         hopper.setProfiles(new Profile("profile1").setVehicle("car"));
         hopper.getLMPreparationHandler().setLMProfiles(new LMProfile("other_profile"));
         assertIllegalArgument(new Runnable() {
@@ -149,7 +162,7 @@ public class GraphHopperProfileTest {
 
     @Test
     public void duplicateLMProfile_error() {
-        final GraphHopper hopper = createHopper(EncodingManager.create("car"));
+        final GraphHopper hopper = createHopper();
         hopper.setProfiles(new Profile("profile").setVehicle("car"));
         hopper.getLMPreparationHandler().setLMProfiles(
                 new LMProfile("profile"),
@@ -165,7 +178,7 @@ public class GraphHopperProfileTest {
 
     @Test
     public void unknownLMPreparationProfile_error() {
-        final GraphHopper hopper = createHopper(EncodingManager.create("car"));
+        final GraphHopper hopper = createHopper();
         hopper.setProfiles(new Profile("profile").setVehicle("car"));
         hopper.getLMPreparationHandler().setLMProfiles(
                 new LMProfile("profile").setPreparationProfile("xyz")
@@ -180,7 +193,7 @@ public class GraphHopperProfileTest {
 
     @Test
     public void lmPreparationProfileChain_error() {
-        final GraphHopper hopper = createHopper(EncodingManager.create("car,bike,foot"));
+        final GraphHopper hopper = createHopper();
         hopper.setProfiles(
                 new Profile("profile1").setVehicle("car"),
                 new Profile("profile2").setVehicle("bike"),
@@ -201,7 +214,7 @@ public class GraphHopperProfileTest {
 
     @Test
     public void noLMProfileForPreparationProfile_error() {
-        final GraphHopper hopper = createHopper(EncodingManager.create("car,bike,foot"));
+        final GraphHopper hopper = createHopper();
         hopper.setProfiles(
                 new Profile("profile1").setVehicle("car"),
                 new Profile("profile2").setVehicle("bike"),
@@ -218,11 +231,10 @@ public class GraphHopperProfileTest {
         }, "Unknown LM preparation profile 'profile2' in LM profile 'profile1' cannot be used as preparation_profile");
     }
 
-    private GraphHopper createHopper(EncodingManager encodingManager) {
+    private GraphHopper createHopper() {
         final GraphHopper hopper = new GraphHopper();
         hopper.setGraphHopperLocation(GH_LOCATION);
         hopper.setStoreOnFlush(false);
-        hopper.setEncodingManager(encodingManager);
         return hopper;
     }
 
diff --git a/core/src/test/java/com/graphhopper/routing/ch/CHProfileSelectorTest.java b/core/src/test/java/com/graphhopper/routing/ch/CHProfileSelectorTest.java
index de486e59f..70c67c82f 100644
--- a/core/src/test/java/com/graphhopper/routing/ch/CHProfileSelectorTest.java
+++ b/core/src/test/java/com/graphhopper/routing/ch/CHProfileSelectorTest.java
@@ -214,12 +214,11 @@ public class CHProfileSelectorTest {
     @Test
     public void multipleVehiclesMissingWeighting() {
         // this is a common use-case, there are multiple vehicles for one weighting
-        EncodingManager em = EncodingManager.create("car,bike,motorcycle,bike2,foot");
         List<Profile> profiles = new ArrayList<>();
         List<CHProfile> chProfiles = new ArrayList<>();
-        for (FlagEncoder encoder : em.fetchEdgeEncoders()) {
-            profiles.add(new Profile(encoder.toString()).setVehicle(encoder.toString()).setWeighting("short_fastest").setTurnCosts(false));
-            chProfiles.add(new CHProfile(encoder.toString()));
+        for (String vehicle : Arrays.asList("car", "bike", "motorcycle", "bike2", "foot")) {
+            profiles.add(new Profile(vehicle).setVehicle(vehicle).setWeighting("short_fastest").setTurnCosts(false));
+            chProfiles.add(new CHProfile(vehicle));
         }
         // we do not specify the weighting but this is ok, because there is only one in use
         String weighting = null;
diff --git a/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java b/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java
index 3482cdf01..992b14477 100644
--- a/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java
+++ b/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java
@@ -27,6 +27,7 @@ import com.graphhopper.storage.IntsRef;
 import org.junit.Test;
 
 import java.util.Arrays;
+import java.util.List;
 
 import static org.junit.Assert.*;
 
@@ -78,7 +79,7 @@ public class EncodingManagerTest {
             EncodingManager.create(foot, foot);
             fail("There should have been an exception");
         } catch (Exception ex) {
-            assertEquals("You must not register a FlagEncoder (foot) twice or for two EncodingManagers!", ex.getMessage());
+            assertEquals("FlagEncoder already exists: foot", ex.getMessage());
         }
     }
 
@@ -221,24 +222,24 @@ public class EncodingManagerTest {
     @Test
     public void testSupportFords() {
         // 1) no encoder crossing fords
-        String flagEncodersStr = "car,bike,foot";
-        EncodingManager manager = EncodingManager.create(new DefaultFlagEncoderFactory(), flagEncodersStr);
+        String flagEncoderStrings = "car,bike,foot";
+        EncodingManager manager = EncodingManager.create(new DefaultFlagEncoderFactory(), flagEncoderStrings);
 
         assertFalse(((AbstractFlagEncoder) manager.getEncoder("car")).isBlockFords());
         assertFalse(((AbstractFlagEncoder) manager.getEncoder("bike")).isBlockFords());
         assertFalse(((AbstractFlagEncoder) manager.getEncoder("foot")).isBlockFords());
 
         // 2) two encoders crossing fords
-        flagEncodersStr = "car,bike|block_fords=true,foot|block_fords=false";
-        manager = EncodingManager.create(new DefaultFlagEncoderFactory(), flagEncodersStr);
+        flagEncoderStrings = "car, bike|block_fords=true, foot|block_fords=false";
+        manager = EncodingManager.create(new DefaultFlagEncoderFactory(), flagEncoderStrings);
 
         assertFalse(((AbstractFlagEncoder) manager.getEncoder("car")).isBlockFords());
         assertTrue(((AbstractFlagEncoder) manager.getEncoder("bike")).isBlockFords());
         assertFalse(((AbstractFlagEncoder) manager.getEncoder("foot")).isBlockFords());
 
         // 2) Try combined with another tag
-        flagEncodersStr = "car|turn_costs=true|block_fords=true,bike,foot|block_fords=false";
-        manager = EncodingManager.create(new DefaultFlagEncoderFactory(), flagEncodersStr);
+        flagEncoderStrings = "car|turn_costs=true|block_fords=true, bike, foot|block_fords=false";
+        manager = EncodingManager.create(new DefaultFlagEncoderFactory(), flagEncoderStrings);
 
         assertTrue(((AbstractFlagEncoder) manager.getEncoder("car")).isBlockFords());
         assertFalse(((AbstractFlagEncoder) manager.getEncoder("bike")).isBlockFords());
diff --git a/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java b/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java
index 3f7fcba70..5c42dafc5 100644
--- a/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java
+++ b/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java
@@ -314,7 +314,7 @@ public abstract class AbstractGraphStorageTester {
     public void testCopyTo() {
         graph = createGHStorage();
         initExampleGraph(graph);
-        GraphHopperStorage gs = GraphBuilder.start(encodingManager).setSegmentSize(8000).setBytes(10).create();
+        GraphHopperStorage gs = GraphBuilder.start(encodingManager).setSegmentSize(8000).create();
         graph.copyTo(gs);
         checkExampleGraph(gs);
 
diff --git a/core/src/test/java/com/graphhopper/storage/GraphHopperStorageTest.java b/core/src/test/java/com/graphhopper/storage/GraphHopperStorageTest.java
index da000932e..a2ffdee8c 100644
--- a/core/src/test/java/com/graphhopper/storage/GraphHopperStorageTest.java
+++ b/core/src/test/java/com/graphhopper/storage/GraphHopperStorageTest.java
@@ -21,6 +21,7 @@ import com.graphhopper.GraphHopper;
 import com.graphhopper.config.CHProfile;
 import com.graphhopper.config.Profile;
 import com.graphhopper.routing.util.BikeFlagEncoder;
+import com.graphhopper.routing.util.CarFlagEncoder;
 import com.graphhopper.routing.util.EncodingManager;
 import com.graphhopper.util.*;
 import com.graphhopper.util.shapes.BBox;
@@ -28,6 +29,7 @@ import org.junit.Test;
 
 import java.io.File;
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.Collections;
 
 import static com.graphhopper.util.EdgeIteratorState.REVERSE_STATE;
@@ -266,7 +268,8 @@ public class GraphHopperStorageTest extends AbstractGraphStorageTester {
 
         // load without configured FlagEncoders
         GraphHopper hopper = new GraphHopper();
-        hopper.setProfiles(Collections.singletonList(new Profile("p_car").setVehicle("car").setWeighting("fastest")));
+        hopper.setProfiles(Arrays.asList(new Profile("p_car").setVehicle("car").setWeighting("fastest"),
+                new Profile("p_bike").setVehicle("bike").setWeighting("fastest")));
         if (ch) {
             hopper.getCHPreparationHandler().setCHProfiles(new CHProfile("p_car"));
         }
@@ -276,10 +279,10 @@ public class GraphHopperStorageTest extends AbstractGraphStorageTester {
         assertEquals(edges, graph.getAllEdges().length());
         Helper.close(graph);
 
-        // load via explicitly configured FlagEncoders
-        hopper = new GraphHopper()
-                .setEncodingManager(encodingManager)
-                .setProfiles(Collections.singletonList(new Profile("p_car").setVehicle("car").setWeighting("fastest")));
+        hopper = new GraphHopper();
+        // load via explicitly configured FlagEncoders then we can define only one profile
+        hopper.getEncodingManagerBuilder().add(createCarFlagEncoder()).add(new BikeFlagEncoder());
+        hopper.setProfiles(Collections.singletonList(new Profile("p_car").setVehicle("car").setWeighting("fastest")));
         if (ch) {
             hopper.getCHPreparationHandler().setCHProfiles(new CHProfile("p_car"));
         }
diff --git a/navigation/src/test/java/com/graphhopper/navigation/NavigateResponseConverterTest.java b/navigation/src/test/java/com/graphhopper/navigation/NavigateResponseConverterTest.java
index cad88876a..ee5035749 100644
--- a/navigation/src/test/java/com/graphhopper/navigation/NavigateResponseConverterTest.java
+++ b/navigation/src/test/java/com/graphhopper/navigation/NavigateResponseConverterTest.java
@@ -42,7 +42,6 @@ public class NavigateResponseConverterTest {
                 setOSMFile(osmFile).
                 setStoreOnFlush(true).
                 setGraphHopperLocation(graphFolder).
-                setEncodingManager(EncodingManager.create(vehicle)).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting("fastest").setTurnCosts(false)).
                 importOrLoad();
     }
diff --git a/reader-osm/src/test/java/com/graphhopper/GraphHopperTest.java b/reader-osm/src/test/java/com/graphhopper/GraphHopperTest.java
index 3df4a2dd6..bc71279fe 100644
--- a/reader-osm/src/test/java/com/graphhopper/GraphHopperTest.java
+++ b/reader-osm/src/test/java/com/graphhopper/GraphHopperTest.java
@@ -28,7 +28,6 @@ import com.graphhopper.reader.dem.SkadiProvider;
 import com.graphhopper.routing.util.AllEdgesIterator;
 import com.graphhopper.routing.util.CarFlagEncoder;
 import com.graphhopper.routing.util.DefaultFlagEncoderFactory;
-import com.graphhopper.routing.util.EncodingManager;
 import com.graphhopper.routing.util.parsers.OSMMaxSpeedParser;
 import com.graphhopper.routing.util.parsers.OSMRoadEnvironmentParser;
 import com.graphhopper.routing.weighting.Weighting;
@@ -99,7 +98,8 @@ public class GraphHopperTest {
     public void testMonacoDifferentAlgorithms(String algo, boolean withCH, int expectedVisitedNodes) {
         final String vehicle = "car";
         final String weighting = "fastest";
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
                 setProfiles(new Profile("profile").setVehicle(vehicle).setWeighting(weighting)).
                 setStoreOnFlush(true);
@@ -129,7 +129,8 @@ public class GraphHopperTest {
         final String profile = "profile";
         final String vehicle = "foot";
         final String weighting = "shortest";
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setStoreOnFlush(true).
@@ -181,7 +182,8 @@ public class GraphHopperTest {
         final String profile = "profile";
         final String vehicle = "foot";
         final String weighting = "shortest";
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setStoreOnFlush(true).
@@ -206,7 +208,8 @@ public class GraphHopperTest {
         final String profile = "profile";
         final String vehicle = "car";
         final String weighting = "shortest";
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting));
         hopper.importOrLoad();
@@ -235,7 +238,8 @@ public class GraphHopperTest {
     private void testImportCloseAndLoad(boolean ch, boolean lm, boolean sort, boolean custom) {
         final String vehicle = "foot";
         final String profileName = "profile";
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
                 setStoreOnFlush(true).
                 setSortGraph(sort);
@@ -253,7 +257,7 @@ public class GraphHopperTest {
             customModel.getAreas().put("area51", area51Feature);
             profile = new CustomProfile(profileName).setCustomModel(customModel).setVehicle(vehicle);
         }
-        hopper.setProfiles(Collections.singletonList(profile));
+        hopper.setProfiles(profile);
 
         if (ch) {
             hopper.getCHPreparationHandler()
@@ -264,9 +268,10 @@ public class GraphHopperTest {
                     .setLMProfiles(new LMProfile(profileName));
         }
         hopper.importAndClose();
-        hopper = createGraphHopper(vehicle).
+        hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
-                setProfiles(Collections.singletonList(profile)).
+                setProfiles(profile).
                 setStoreOnFlush(true);
         if (ch) {
             hopper.getCHPreparationHandler()
@@ -365,7 +370,8 @@ public class GraphHopperTest {
         final String profile = "profile";
         final String vehicle = "foot";
         final String weighting = "shortest";
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setStoreOnFlush(true).
@@ -398,7 +404,8 @@ public class GraphHopperTest {
         final String vehicle = "bike";
         final String weighting = "fastest";
 
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(BAYREUTH).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting));
         hopper.importOrLoad();
@@ -424,7 +431,8 @@ public class GraphHopperTest {
         final String vehicle = "car";
         final String weighting = "fastest";
 
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(BAYREUTH).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting));
         hopper.importOrLoad();
@@ -450,7 +458,8 @@ public class GraphHopperTest {
         final String vehicle = "car";
         final String weighting = "fastest";
 
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(LAUF).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting));
         hopper.importOrLoad();
@@ -487,7 +496,8 @@ public class GraphHopperTest {
         final String vehicle = "car";
         final String weighting = "fastest";
 
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(BAYREUTH).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting));
         hopper.importOrLoad();
@@ -506,7 +516,8 @@ public class GraphHopperTest {
         final String vehicle = "car";
         final String weighting = "fastest";
 
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(BAYREUTH).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting));
         hopper.importOrLoad();
@@ -602,13 +613,14 @@ public class GraphHopperTest {
         final String emptyCar = "empty_car";
         CustomModel customModel = new CustomModel();
         customModel.addToSpeed(Statement.If("road_class == TERTIARY", Statement.Op.MULTIPLY, 0.1));
-        GraphHopper hopper = createGraphHopper(vehicle)
-                .setOSMFile(BAYREUTH)
-                .setProfiles(
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
+                setOSMFile(BAYREUTH).
+                setProfiles(
                         new CustomProfile(emptyCar).setCustomModel(new CustomModel()).setVehicle(vehicle),
                         new CustomProfile(customCar).setCustomModel(customModel).setVehicle(vehicle)
-                )
-                .importOrLoad();
+                ).
+                importOrLoad();
 
         // standard car route
         assertDistance(hopper, emptyCar, null, 8725);
@@ -646,7 +658,8 @@ public class GraphHopperTest {
         final String profile = "profile";
         final String vehicle = "foot";
         final String weighting = "shortest";
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setStoreOnFlush(true).
@@ -731,7 +744,8 @@ public class GraphHopperTest {
         final String profile = "profile";
         final String vehicle = "foot";
         final String weighting = "shortest";
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setStoreOnFlush(true).
@@ -762,7 +776,8 @@ public class GraphHopperTest {
         final String profile = "profile";
         final String vehicle = "foot";
         final String weighting = "fastest";
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setStoreOnFlush(true).
@@ -809,7 +824,8 @@ public class GraphHopperTest {
         final String profile = "profile";
         final String vehicle = "foot";
         final String weighting = "fastest";
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setStoreOnFlush(true).
@@ -835,7 +851,8 @@ public class GraphHopperTest {
         final String profile = "profile";
         final String vehicle = "foot";
         final String weighting = "fastest";
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setStoreOnFlush(true).
@@ -866,7 +883,8 @@ public class GraphHopperTest {
         final String profile = "profile";
         final String vehicle = "foot";
         final String weighting = "fastest";
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setStoreOnFlush(true).
@@ -904,7 +922,8 @@ public class GraphHopperTest {
         final String profile = "profile";
         final String vehicle = "foot";
         final String weighting = "fastest";
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setStoreOnFlush(true).
@@ -939,7 +958,8 @@ public class GraphHopperTest {
         final String vehicle = "foot";
         final String weighting = "shortest";
 
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setStoreOnFlush(true);
@@ -992,18 +1012,18 @@ public class GraphHopperTest {
         final String vehicle = "foot";
         final String weighting = "shortest";
 
-        GraphHopper hopper = new GraphHopper()
-                .setOSMFile(MONACO)
+        GraphHopper hopper = new GraphHopper();
+        hopper.getEncodingManagerBuilder().add(new OSMRoadEnvironmentParser() {
+            @Override
+            public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, boolean ferry, IntsRef relationFlags) {
+                // do not change RoadEnvironment to avoid triggering tunnel interpolation
+                return edgeFlags;
+            }
+        }).addIfAbsent(new DefaultFlagEncoderFactory(), vehicle);
+        hopper.setOSMFile(MONACO)
                 .setStoreOnFlush(true)
                 .setGraphHopperLocation(GH_LOCATION)
-                .setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting))
-                .setEncodingManager(EncodingManager.start().add(new OSMRoadEnvironmentParser() {
-                    @Override
-                    public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, boolean ferry, IntsRef relationFlags) {
-                        // do not change RoadEnvironment to avoid triggering tunnel interpolation
-                        return edgeFlags;
-                    }
-                }).addAll(new DefaultFlagEncoderFactory(), vehicle).build());
+                .setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting));
 
         hopper.setElevationProvider(new SRTMProvider(DIR));
         hopper.importOrLoad();
@@ -1031,10 +1051,12 @@ public class GraphHopperTest {
         final String vehicle = "foot";
         final String weighting = "shortest";
 
-        GraphHopper hopper = createGraphHopper("car,foot")
-                .setOSMFile(MONACO)
-                .setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting))
-                .setStoreOnFlush(true);
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
+                setOSMFile(MONACO).
+                setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting),
+                        new Profile("car").setVehicle("foot").setWeighting(weighting)).
+                setStoreOnFlush(true);
 
         hopper.setElevationProvider(new SRTMProvider(DIR));
         hopper.importOrLoad();
@@ -1063,7 +1085,8 @@ public class GraphHopperTest {
         final String vehicle = "foot";
         final String weighting = "shortest";
 
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
                 setStoreOnFlush(true).
                 setElevationWayPointMaxDistance(1).
@@ -1107,7 +1130,8 @@ public class GraphHopperTest {
         final String vehicle = "foot";
         final String weighting = "shortest";
 
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
                 setProfiles(
                         new Profile(profile).setVehicle(vehicle).setWeighting(weighting)
@@ -1137,7 +1161,8 @@ public class GraphHopperTest {
         final String vehicle2 = "bike";
         final String weighting = "fastest";
 
-        GraphHopper hopper = createGraphHopper(vehicle1 + "," + vehicle2).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(KREMS).
                 setProfiles(
                         new Profile(profile1).setVehicle(vehicle1).setWeighting(weighting),
@@ -1187,7 +1212,8 @@ public class GraphHopperTest {
         final String vehicle2 = "bike";
         final String weighting = "fastest";
 
-        GraphHopper hopper = createGraphHopper(vehicle1 + "," + vehicle2).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
                 setProfiles(Arrays.asList(
                         new Profile(profile1).setVehicle(vehicle1).setWeighting(weighting),
@@ -1232,7 +1258,8 @@ public class GraphHopperTest {
         String vehicle1 = "car";
         String vehicle2 = "bike";
         String weighting = "fastest";
-        GraphHopper hopper = createGraphHopper(vehicle1 + "," + vehicle2).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(BERLIN).
                 setProfiles(
                         new Profile(profile1).setVehicle(vehicle1).setWeighting(weighting),
@@ -1267,7 +1294,8 @@ public class GraphHopperTest {
                 new Profile(profile1).setVehicle(vehicle1).setWeighting(weighting),
                 new Profile(profile2).setVehicle(vehicle2).setWeighting(weighting)
         );
-        GraphHopper hopper = createGraphHopper(vehicle1 + "," + vehicle2).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
                 setProfiles(profiles).
                 setStoreOnFlush(true);
@@ -1318,9 +1346,10 @@ public class GraphHopperTest {
         final String profile = "profile";
         final String vehicle = "foot";
         final String weighting = "shortest";
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
-                setProfiles(Collections.singletonList(new Profile(profile).setVehicle(vehicle).setWeighting(weighting))).
+                setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setStoreOnFlush(true).
                 setSortGraph(sort);
         hopper.getCHPreparationHandler().setCHProfiles(new CHProfile(profile));
@@ -1355,7 +1384,8 @@ public class GraphHopperTest {
         final String profile = "profile";
         final String vehicle = "foot";
         final String weighting = "fastest";
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setStoreOnFlush(true).
@@ -1384,7 +1414,8 @@ public class GraphHopperTest {
         final String vehicle = "car";
         final String weighting = "fastest";
 
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(BAYREUTH).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting));
         hopper.importOrLoad();
@@ -1408,7 +1439,8 @@ public class GraphHopperTest {
         final String profile = "profile";
         final String vehicle = "car";
         final String weighting = "fastest";
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(BAYREUTH).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting));
         hopper.importOrLoad();
@@ -1429,7 +1461,8 @@ public class GraphHopperTest {
         final String profile = "car_profile";
         final String vehicle = "car";
         final String weighting = "fastest";
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setStoreOnFlush(true);
@@ -1490,7 +1523,8 @@ public class GraphHopperTest {
         final String profile2 = "p2";
         final String profile3 = "p3";
         final String vehicle = "car";
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
                 setProfiles(
                         new Profile(profile1).setVehicle("car").setWeighting("short_fastest").putHint("short_fastest.distance_factor", 0.07),
@@ -1538,7 +1572,8 @@ public class GraphHopperTest {
         final String vehicle = "mtb";
         final String weighting = "shortest";
 
-        GraphHopper hopper = createGraphHopper(vehicle + "|turn_costs=true").
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting).setTurnCosts(true).putHint(U_TURN_COSTS, 123));
         hopper.importOrLoad();
@@ -1560,7 +1595,8 @@ public class GraphHopperTest {
         final String weighting1 = "fastest";
         final String weighting2 = "short_fastest";
 
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
                 setProfiles(
                         new Profile(profile1).setVehicle(vehicle).setWeighting(weighting1),
@@ -1607,11 +1643,13 @@ public class GraphHopperTest {
         final String profile = "profile";
         final String vehicle = "car";
         final String weighting = "fastest";
-        // note that the pure presence of the bike encoder leads to 'ghost' junctions with the bike network even for
-        // cars such that the number of visited nodes depends on the bike encoder added here or not, #1910
-        GraphHopper hopper = createGraphHopper(vehicle + ",bike").
+        // note that the pure presence of the bike profile leads to 'ghost' junctions with the bike network even for
+        // cars such that the number of visited nodes depends on the bike profile added here or not, #1910
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
-                setProfiles(Collections.singletonList(new Profile(profile).setVehicle(vehicle).setWeighting(weighting))).
+                setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting),
+                        new Profile("bike").setVehicle("bike").setWeighting(weighting)).
                 setStoreOnFlush(true);
         hopper.getLMPreparationHandler().
                 setLMProfiles(new LMProfile(profile).setMaximumLMWeight(2000));
@@ -1636,11 +1674,10 @@ public class GraphHopperTest {
         final String profile = "car";
         final String vehicle = "car";
         final String weighting = "fastest";
-        GraphHopper hopper = createGraphHopper("car|turn_costs=true").
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MOSCOW).
-                setProfiles(Collections.singletonList(
-                        new Profile(profile).setVehicle(vehicle).setWeighting(weighting).setTurnCosts(turnCosts)
-                ));
+                setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting).setTurnCosts(turnCosts));
         hopper.getCHPreparationHandler().setCHProfiles(new CHProfile(profile));
         hopper.getLMPreparationHandler().setLMProfiles(new LMProfile(profile));
         hopper.importOrLoad();
@@ -1682,11 +1719,10 @@ public class GraphHopperTest {
         final String profile = "car";
         final String vehicle = "car";
         final String weighting = "fastest";
-        GraphHopper hopper = createGraphHopper("car|turn_costs=true").
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MOSCOW).
-                setProfiles(Collections.singletonList(
-                        new Profile(profile).setVehicle(vehicle).setWeighting(weighting).setTurnCosts(turnCosts)
-                ));
+                setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting).setTurnCosts(turnCosts));
         hopper.getCHPreparationHandler().setCHProfiles(new CHProfile(profile));
         hopper.importOrLoad();
 
@@ -1708,11 +1744,10 @@ public class GraphHopperTest {
         final String profile = "car";
         final String vehicle = "car";
         final String weighting = "fastest";
-        GraphHopper hopper = createGraphHopper("car|turn_costs=true").
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MOSCOW).
-                setProfiles(Collections.singletonList(
-                        new Profile(profile).setVehicle(vehicle).setWeighting(weighting).setTurnCosts(true)
-                ));
+                setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting).setTurnCosts(true));
         hopper.getCHPreparationHandler().setCHProfiles(new CHProfile(profile));
         hopper.getLMPreparationHandler().setLMProfiles(new LMProfile(profile));
 
@@ -1742,13 +1777,15 @@ public class GraphHopperTest {
         final String profile2 = "profile_turn_costs";
         final String vehicle = "car";
         final String weighting = "fastest";
-        GraphHopper hopper = createGraphHopper("car|turn_costs=true").
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MOSCOW).
-                setProfiles(
-                        new Profile(profile1).setVehicle(vehicle).setWeighting(weighting).setTurnCosts(false),
-                        new Profile(profile2).setVehicle(vehicle).setWeighting(weighting).setTurnCosts(true)
+                // add profile with turn costs first when no flag encoder is explicitly added
+                        setProfiles(
+                        new Profile(profile2).setVehicle(vehicle).setWeighting(weighting).setTurnCosts(true),
+                        new Profile(profile1).setVehicle(vehicle).setWeighting(weighting).setTurnCosts(false)
                 ).
-                setStoreOnFlush(true);
+                        setStoreOnFlush(true);
         hopper.importOrLoad();
 
         GHRequest req = new GHRequest(55.813357, 37.5958585, 55.811042, 37.594689);
@@ -1764,7 +1801,8 @@ public class GraphHopperTest {
         final String profile2 = "profile_no_turn_costs";
         final String vehicle = "car";
         final String weighting = "fastest";
-        GraphHopper hopper = createGraphHopper("car|turn_costs=true").
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MOSCOW).
                 setProfiles(Arrays.asList(
                         new Profile(profile1).setVehicle(vehicle).setWeighting(weighting).setTurnCosts(true),
@@ -1789,11 +1827,10 @@ public class GraphHopperTest {
         final String profile = "my_car";
         final String vehicle = "car";
         final String weighting = "fastest";
-        GraphHopper hopper = createGraphHopper("car|turn_costs=true").
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MOSCOW).
-                setProfiles(Collections.singletonList(
-                        new Profile(profile).setVehicle(vehicle).setWeighting(weighting).setTurnCosts(true))
-                ).
+                setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting).setTurnCosts(true)).
                 setStoreOnFlush(true);
         hopper.getCHPreparationHandler()
                 .setCHProfiles(new CHProfile(profile));
@@ -1819,7 +1856,8 @@ public class GraphHopperTest {
         final String profile2 = "car_profile_notc";
         final String weighting = "fastest";
         // before edge-based CH was added a common case was to use edge-based without CH and CH for node-based
-        GraphHopper hopper = createGraphHopper("car|turn_costs=true").
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MOSCOW).
                 setProfiles(Arrays.asList(
                         new Profile(profile1).setVehicle("car").setWeighting(weighting).setTurnCosts(true),
@@ -1858,9 +1896,11 @@ public class GraphHopperTest {
         final String profile = "profile";
         final String vehicle = "foot";
         final String weighting = "fastest";
-        GraphHopper hopper = createGraphHopper("foot,car|turn_costs=true").
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MOSCOW).
-                setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting));
+                setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting),
+                        new Profile("car").setVehicle("car").setWeighting(weighting).setTurnCosts(true));
 
         hopper.importOrLoad();
         GHPoint p = new GHPoint(55.813357, 37.5958585);
@@ -1877,7 +1917,8 @@ public class GraphHopperTest {
         // turning onto Gudulastraße. However, Gudulastraße can also not be accessed from the south/west, because
         // its a one-way. This creates a subnetwork that is not accessible at all. We can only detect this if we
         // consider the turn restrictions during the subnetwork search.
-        GraphHopper hopper = createGraphHopper("foot,car|turn_costs=true").
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(ESSEN).
                 setMinNetworkSize(50).
                 setProfiles(
@@ -1905,7 +1946,8 @@ public class GraphHopperTest {
 
     @Test
     public void testEdgeCount() {
-        GraphHopper hopper = createGraphHopper("car").
+        GraphHopper hopper = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(BAYREUTH).
                 setMinNetworkSize(50).
                 setProfiles(new Profile("car").setVehicle("car").setWeighting("fastest"));
@@ -1919,10 +1961,10 @@ public class GraphHopperTest {
 
     @Test
     public void testCurbsides() {
-        GraphHopper h = createGraphHopper("car|turn_costs=true").
+        GraphHopper h = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(BAYREUTH).
-                setProfiles(Collections.singletonList(
-                        new Profile("my_profile").setVehicle("car").setWeighting("fastest").setTurnCosts(true)));
+                setProfiles(new Profile("my_profile").setVehicle("car").setWeighting("fastest").setTurnCosts(true));
         h.getCHPreparationHandler()
                 .setCHProfiles(new CHProfile("my_profile"));
         h.importOrLoad();
@@ -1969,11 +2011,10 @@ public class GraphHopperTest {
         final String profile = "my_profile";
         final String vehicle = "car";
         final String weighting = "fastest";
-        GraphHopper h = createGraphHopper("car|turn_costs=true").
+        GraphHopper h = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
-                setProfiles(Collections.singletonList(
-                        new Profile(profile).setVehicle(vehicle).setWeighting(weighting).setTurnCosts(true))
-                );
+                setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting).setTurnCosts(true));
         h.getCHPreparationHandler()
                 .setCHProfiles(new CHProfile(profile));
         h.importOrLoad();
@@ -2035,13 +2076,11 @@ public class GraphHopperTest {
 
     @Test
     public void testCHWithFiniteUTurnCosts() {
-        GraphHopper h = createGraphHopper("car|turn_costs=true").
+        GraphHopper h = new GraphHopper().
+                setGraphHopperLocation(GH_LOCATION).
                 setOSMFile(MONACO).
-                setProfiles(Collections.singletonList(
-                        new Profile("my_profile").setVehicle("car").setWeighting("fastest")
-                                .setTurnCosts(true)
-                                .putHint(U_TURN_COSTS, 40))
-                );
+                setProfiles(new Profile("my_profile").setVehicle("car").setWeighting("fastest").
+                        setTurnCosts(true).putHint(U_TURN_COSTS, 40));
         h.getCHPreparationHandler()
                 .setCHProfiles(new CHProfile("my_profile"));
         h.importOrLoad();
@@ -2063,16 +2102,13 @@ public class GraphHopperTest {
     @Test
     public void simplifyWithInstructionsAndPathDetails() {
         final String profile = "profile";
-        GraphHopper hopper = new GraphHopper().
-                setOSMFile(BAYREUTH).
+        GraphHopper hopper = new GraphHopper();
+        hopper.getEncodingManagerBuilder().setEnableInstructions(true)
+                .add(new OSMMaxSpeedParser())
+                .add(new CarFlagEncoder());
+        hopper.setOSMFile(BAYREUTH).
                 setProfiles(new Profile(profile).setVehicle("car").setWeighting("fastest")).
                 setGraphHopperLocation(GH_LOCATION);
-        EncodingManager em = new EncodingManager.Builder()
-                .setEnableInstructions(true)
-                .add(new OSMMaxSpeedParser())
-                .add(new CarFlagEncoder())
-                .build();
-        hopper.setEncodingManager(em);
         hopper.importOrLoad();
 
         GHRequest req = new GHRequest()
@@ -2140,12 +2176,4 @@ public class GraphHopperTest {
     private void assertDetail(PathDetail detail, String expected) {
         assertEquals(expected, detail.toString());
     }
-
-    private static GraphHopper createGraphHopper(String encodingManagerString) {
-        GraphHopper hopper = new GraphHopper();
-        hopper.setEncodingManager(EncodingManager.create(encodingManagerString));
-        hopper.setGraphHopperLocation(GH_LOCATION);
-        return hopper;
-    }
-
 }
diff --git a/reader-osm/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java b/reader-osm/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java
index 0778273e1..4f23e780d 100644
--- a/reader-osm/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java
+++ b/reader-osm/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java
@@ -81,7 +81,7 @@ public class GraphHopperOSMTest {
         String profile = "car_profile";
         String vehicle = "car";
         String weighting = "fastest";
-        GraphHopper hopper = createGraphHopper(vehicle).
+        GraphHopper hopper = new GraphHopper().
                 setStoreOnFlush(true).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setGraphHopperLocation(ghLoc).
@@ -128,7 +128,7 @@ public class GraphHopperOSMTest {
         final String profile = "profile";
         final String vehicle = "car";
         final String weighting = "fastest";
-        GraphHopper gh = createGraphHopper(vehicle).
+        GraphHopper gh = new GraphHopper().
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setStoreOnFlush(true).
                 setGraphHopperLocation(ghLoc).
@@ -143,7 +143,7 @@ public class GraphHopperOSMTest {
         assertEquals(3, rsp.getBest().getPoints().getSize());
 
         gh.close();
-        gh = createGraphHopper(vehicle).
+        gh = new GraphHopper().
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setStoreOnFlush(true);
         assertTrue(gh.load(ghLoc));
@@ -154,7 +154,7 @@ public class GraphHopperOSMTest {
 
         gh.close();
 
-        gh = createGraphHopper(vehicle).
+        gh = new GraphHopper().
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setGraphHopperLocation(ghLoc).
                 setOSMFile(testOsm);
@@ -165,7 +165,8 @@ public class GraphHopperOSMTest {
 
     @Test
     public void testQueryLocationIndexWithBBox() {
-        final GraphHopper gh = createGraphHopper("car").
+        final GraphHopper gh = new GraphHopper().
+                setProfiles(new Profile("car").setVehicle("car").setWeighting("fastest")).
                 setStoreOnFlush(true).
                 setGraphHopperLocation(ghLoc).
                 setOSMFile("../core/files/monaco.osm.gz");
@@ -229,9 +230,9 @@ public class GraphHopperOSMTest {
         final String profile = "profile";
         final String vehicle = "car";
         final String weighting = "fastest";
-        GraphHopper gh = createGraphHopper(vehicle).
+        GraphHopper gh = new GraphHopper().
                 setStoreOnFlush(true).
-                setProfiles(Collections.singletonList(new Profile(profile).setVehicle(vehicle).setWeighting(weighting))).
+                setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setGraphHopperLocation(ghLoc).
                 setOSMFile(testOsm);
         gh.getCHPreparationHandler().setCHProfiles(new CHProfile(profile));
@@ -242,7 +243,8 @@ public class GraphHopperOSMTest {
         gh.close();
 
         // now load GH without CH profile
-        gh = createGraphHopper(vehicle).
+        gh = new GraphHopper().
+                setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setStoreOnFlush(true);
         gh.load(ghLoc);
         // no error
@@ -250,9 +252,9 @@ public class GraphHopperOSMTest {
         Helper.removeDir(new File(ghLoc));
 
         // when there is no CH preparation we get an error if we try to load GH with a CH profile
-        gh = createGraphHopper(vehicle).
+        gh = new GraphHopper().
                 setStoreOnFlush(true).
-                setProfiles(Collections.singletonList(new Profile(profile).setVehicle(vehicle).setWeighting(weighting))).
+                setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setGraphHopperLocation(ghLoc).
                 setOSMFile(testOsm);
         gh.importOrLoad();
@@ -261,7 +263,7 @@ public class GraphHopperOSMTest {
         assertEquals(3, rsp.getBest().getPoints().getSize());
         gh.close();
 
-        gh = createGraphHopper("car").
+        gh = new GraphHopper().
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setStoreOnFlush(true);
         gh.getCHPreparationHandler().setCHProfiles(new CHProfile("profile"));
@@ -277,18 +279,19 @@ public class GraphHopperOSMTest {
     @Test
     public void testAllowMultipleReadingInstances() {
         String vehicle = "car";
-        GraphHopper instance1 = createGraphHopper(vehicle).
+        GraphHopper instance1 = new GraphHopper().
+                setProfiles(new Profile(vehicle).setVehicle(vehicle).setWeighting("fastest")).
                 setStoreOnFlush(true).
                 setGraphHopperLocation(ghLoc).
                 setOSMFile(testOsm);
         instance1.importOrLoad();
 
-        GraphHopper instance2 = createGraphHopper(vehicle).
+        GraphHopper instance2 = new GraphHopper().
                 setStoreOnFlush(true).
                 setOSMFile(testOsm);
         instance2.load(ghLoc);
 
-        GraphHopper instance3 = createGraphHopper(vehicle).
+        GraphHopper instance3 = new GraphHopper().
                 setStoreOnFlush(true).
                 setOSMFile(testOsm);
         instance3.load(ghLoc);
@@ -314,7 +317,6 @@ public class GraphHopperOSMTest {
                 super.importOSM();
             }
         }.setStoreOnFlush(true).
-                setEncodingManager(EncodingManager.create("car")).
                 setGraphHopperLocation(ghLoc).
                 setProfiles(new Profile("car").setVehicle("car").setWeighting("fastest")).
                 setOSMFile(testOsm);
@@ -331,7 +333,8 @@ public class GraphHopperOSMTest {
         };
         thread.start();
 
-        GraphHopper instance2 = createGraphHopper("car").
+        GraphHopper instance2 = new GraphHopper().
+                setProfiles(new Profile("car").setVehicle("car").setWeighting("fastest")).
                 setStoreOnFlush(true).
                 setOSMFile(testOsm);
         try {
@@ -361,9 +364,9 @@ public class GraphHopperOSMTest {
         final String vehicle = "car";
         final String weighting = "shortest";
 
-        instance = createGraphHopper(vehicle).
+        instance = new GraphHopper().
                 setStoreOnFlush(false).
-                setProfiles(Collections.singletonList(new Profile(profile).setVehicle(vehicle).setWeighting(weighting))).
+                setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setGraphHopperLocation(ghLoc).
                 setOSMFile(testOsm);
         instance.getCHPreparationHandler().setCHProfiles(new CHProfile(profile));
@@ -381,7 +384,7 @@ public class GraphHopperOSMTest {
         final String profile = "profile";
         final String vehicle = "car";
         final String weighting = "fastest";
-        instance = createGraphHopper(vehicle).
+        instance = new GraphHopper().
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setStoreOnFlush(false).
                 setSortGraph(true).
@@ -418,7 +421,7 @@ public class GraphHopperOSMTest {
         final String weighting = "fastest";
 
         // now all ways are imported
-        instance = createGraphHopper(vehicle1 + "," + vehicle2).
+        instance = new GraphHopper().
                 setProfiles(
                         new Profile(profile1).setVehicle(vehicle1).setWeighting(weighting),
                         new Profile(profile2).setVehicle(vehicle2).setWeighting(weighting)
@@ -477,12 +480,12 @@ public class GraphHopperOSMTest {
                 new GraphHopperConfig().
                         putObject("datareader.file", testOsm3).
                         putObject("datareader.dataaccess", "RAM").
-                        putObject("graph.flag_encoders", "foot,car")).
-                setGraphHopperLocation(ghLoc).
-                setProfiles(Arrays.asList(
-                        new Profile("foot").setVehicle("foot").setWeighting("fastest"),
-                        new Profile("car").setVehicle("car").setWeighting("fastest")
-                ));
+                        putObject("graph.flag_encoders", "foot,car").
+                        setProfiles(Arrays.asList(
+                                new Profile("foot").setVehicle("foot").setWeighting("fastest"),
+                                new Profile("car").setVehicle("car").setWeighting("fastest")
+                        ))).
+                setGraphHopperLocation(ghLoc);
         instance.importOrLoad();
         assertEquals(5, instance.getGraphHopperStorage().getNodes());
         instance.close();
@@ -493,11 +496,11 @@ public class GraphHopperOSMTest {
                     new GraphHopperConfig().
                             putObject("datareader.file", testOsm3).
                             putObject("datareader.dataaccess", "RAM").
-                            putObject("graph.flag_encoders", "foot")).
-                    setOSMFile(testOsm3).
-                    setProfiles(Collections.singletonList(
-                            new Profile("foot").setVehicle("foot").setWeighting("fastest")
-                    ));
+                            putObject("graph.flag_encoders", "foot").
+                            setProfiles(Collections.singletonList(
+                                    new Profile("foot").setVehicle("foot").setWeighting("fastest")
+                            ))).
+                    setOSMFile(testOsm3);
             tmpGH.load(ghLoc);
             fail();
         } catch (Exception ex) {
@@ -509,12 +512,12 @@ public class GraphHopperOSMTest {
             GraphHopper tmpGH = new GraphHopper().init(new GraphHopperConfig().
                     putObject("datareader.file", testOsm3).
                     putObject("datareader.dataaccess", "RAM").
-                    putObject("graph.flag_encoders", "car,foot")).
-                    setOSMFile(testOsm3).
+                    putObject("graph.flag_encoders", "car,foot").
                     setProfiles(Arrays.asList(
                             new Profile("car").setVehicle("car").setWeighting("fastest"),
                             new Profile("foot").setVehicle("foot").setWeighting("fastest")
-                    ));
+                    ))).
+                    setOSMFile(testOsm3);
             tmpGH.load(ghLoc);
             fail();
         } catch (Exception ex) {
@@ -527,12 +530,12 @@ public class GraphHopperOSMTest {
                         putObject("datareader.file", testOsm3).
                         putObject("datareader.dataaccess", "RAM").
                         putObject("graph.encoded_values", "road_class").
-                        putObject("graph.flag_encoders", "foot,car")).
-                setOSMFile(testOsm3).
-                setProfiles(Arrays.asList(
-                        new Profile("foot").setVehicle("foot").setWeighting("fastest"),
-                        new Profile("car").setVehicle("car").setWeighting("fastest")
-                ));
+                        putObject("graph.flag_encoders", "foot,car").
+                        setProfiles(Arrays.asList(
+                                new Profile("foot").setVehicle("foot").setWeighting("fastest"),
+                                new Profile("car").setVehicle("car").setWeighting("fastest")
+                        ))).
+                setOSMFile(testOsm3);
         try {
             instance.load(ghLoc);
             fail();
@@ -541,18 +544,19 @@ public class GraphHopperOSMTest {
         }
 
         // different version for car should fail
-        instance = new GraphHopper().setEncodingManager(EncodingManager.create(new FootFlagEncoder(), new CarFlagEncoder() {
-            @Override
-            public int getVersion() {
-                return 0;
-            }
-        })).init(new GraphHopperConfig().
+        instance = new GraphHopper();
+        instance.getEncodingManagerBuilder().add(new FootFlagEncoder()).
+                add(new CarFlagEncoder() {
+                    @Override
+                    public int getVersion() {
+                        return 0;
+                    }
+                });
+        instance.init(new GraphHopperConfig().
                 putObject("datareader.file", testOsm3).
-                putObject("datareader.dataaccess", "RAM")).
-                setOSMFile(testOsm3).
-                setProfiles(Collections.singletonList(
-                        new Profile("car").setVehicle("car").setWeighting("fastest")
-                ));
+                putObject("datareader.dataaccess", "RAM").
+                setProfiles(Collections.singletonList(new Profile("car").setVehicle("car").setWeighting("fastest")))).
+                setOSMFile(testOsm3);
         try {
             instance.load(ghLoc);
             fail();
@@ -567,11 +571,11 @@ public class GraphHopperOSMTest {
                 new GraphHopperConfig().
                         putObject("datareader.file", testOsm3).
                         putObject("datareader.dataaccess", "RAM").
-                        putObject("graph.flag_encoders", "foot,car")).
-                setProfiles(Arrays.asList(
-                        new Profile("foot").setVehicle("foot").setWeighting("fastest"),
-                        new Profile("car").setVehicle("car").setWeighting("fastest")
-                )).
+                        putObject("graph.flag_encoders", "foot,car").
+                        setProfiles(Arrays.asList(
+                                new Profile("foot").setVehicle("foot").setWeighting("fastest"),
+                                new Profile("car").setVehicle("car").setWeighting("fastest")
+                        ))).
                 setGraphHopperLocation(ghLoc);
         instance.importOrLoad();
         // older versions <= 0.12 did not store this property, ensure that we fail to load it
@@ -586,11 +590,11 @@ public class GraphHopperOSMTest {
                         putObject("datareader.file", testOsm3).
                         putObject("datareader.dataaccess", "RAM").
                         putObject("graph.encoded_values", "road_environment,road_class").
-                        putObject("graph.flag_encoders", "foot,car")).
-                setProfiles(Arrays.asList(
-                        new Profile("foot").setVehicle("foot").setWeighting("fastest"),
-                        new Profile("car").setVehicle("car").setWeighting("fastest")
-                )).
+                        putObject("graph.flag_encoders", "foot,car").
+                        setProfiles(Arrays.asList(
+                                new Profile("foot").setVehicle("foot").setWeighting("fastest"),
+                                new Profile("car").setVehicle("car").setWeighting("fastest")
+                        ))).
                 setOSMFile(testOsm3);
         try {
             instance.load(ghLoc);
@@ -605,7 +609,7 @@ public class GraphHopperOSMTest {
         String profile = "profile";
         String vehicle = "car";
         String weighting = "fastest";
-        instance = createGraphHopper(vehicle).
+        instance = new GraphHopper().
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setStoreOnFlush(true);
         try {
@@ -621,7 +625,8 @@ public class GraphHopperOSMTest {
 
     @Test
     public void testDoesNotCreateEmptyFolderIfLoadingFromNonExistingPath() {
-        instance = createGraphHopper("car");
+        instance = new GraphHopper();
+        instance.setProfiles(new Profile("car").setVehicle("car").setWeighting("fastest"));
         assertFalse(instance.load(ghLoc));
         assertFalse(new File(ghLoc).exists());
     }
@@ -648,7 +653,8 @@ public class GraphHopperOSMTest {
         }
 
         // missing OSM file to import
-        instance = createGraphHopper("car").
+        instance = new GraphHopper().
+                setProfiles(new Profile("car").setVehicle("car").setWeighting("fastest")).
                 setStoreOnFlush(true).
                 setGraphHopperLocation(ghLoc);
         try {
@@ -668,11 +674,12 @@ public class GraphHopperOSMTest {
             instance.importOrLoad();
             fail();
         } catch (IllegalStateException ex) {
-            assertTrue(ex.getMessage(), ex.getMessage().startsWith("Cannot load properties to fetch EncodingManager"));
+            assertTrue(ex.getMessage(), ex.getMessage().startsWith("no profiles exist but assumed to create EncodingManager"));
         }
 
         // Import is possible even if no storeOnFlush is specified BUT here we miss the OSM file
-        instance = createGraphHopper("car").
+        instance = new GraphHopper().
+                setProfiles(new Profile("car").setVehicle("car").setWeighting("fastest")).
                 setStoreOnFlush(false).
                 setGraphHopperLocation(ghLoc);
         try {
@@ -690,7 +697,7 @@ public class GraphHopperOSMTest {
         final String profile = "foot_profile";
         final String vehicle = "foot";
         final String weighting = "fastest";
-        instance = createGraphHopper(vehicle).
+        instance = new GraphHopper().
                 setStoreOnFlush(false).
                 setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).
                 setGraphHopperLocation(ghLoc).
@@ -720,9 +727,9 @@ public class GraphHopperOSMTest {
                 init(new GraphHopperConfig().
                         putObject("datareader.file", testOsm3).
                         putObject("prepare.min_network_size", 0).
-                        putObject("graph.flag_encoders", vehicle)
-                        .setProfiles(Collections.singletonList(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)))
-                        .setCHProfiles(Collections.singletonList(new CHProfile(profile)))
+                        putObject("graph.flag_encoders", vehicle).
+                        setProfiles(Collections.singletonList(new Profile(profile).setVehicle(vehicle).setWeighting(weighting))).
+                        setCHProfiles(Collections.singletonList(new CHProfile(profile)))
                 ).
                 setGraphHopperLocation(ghLoc);
         instance.importOrLoad();
@@ -882,7 +889,7 @@ public class GraphHopperOSMTest {
         CarFlagEncoder carEncoder = new CarFlagEncoder();
         EncodingManager encodingManager = EncodingManager.create(carEncoder);
         Weighting weighting = new FastestWeighting(carEncoder);
-        GraphHopperStorage g = new GraphBuilder(encodingManager).setCHConfigs(CHConfig.nodeBased("p", weighting)).setBytes(20).create();
+        GraphHopperStorage g = new GraphBuilder(encodingManager).setCHConfigs(CHConfig.nodeBased("p", weighting)).create();
 
         //   2---3---4
         //  /    |    \
@@ -914,11 +921,12 @@ public class GraphHopperOSMTest {
         GHUtility.setSpeed(60, true, true, carEncoder, g.edge(5, 8).setDistance(110));
         GHUtility.setSpeed(60, true, true, carEncoder, g.edge(7, 8).setDistance(110));
 
-        GraphHopper tmp = new GraphHopper().
-                setEncodingManager(encodingManager).
+        GraphHopper tmp = new GraphHopper() {
+            {
                 setProfiles(new Profile("profile").setVehicle("car").setWeighting("fastest"));
-        tmp.setGraphHopperStorage(g);
-        tmp.postProcessing();
+                loadGraph(g, encodingManager);
+            }
+        };
         return tmp;
     }
 
@@ -927,16 +935,8 @@ public class GraphHopperOSMTest {
         HashMap<String, Long> shortcutCountMap = new HashMap<>();
         // try all parallelization modes        
         for (int threadCount = 1; threadCount < 6; threadCount++) {
-            EncodingManager em = EncodingManager.create(Arrays.asList(
-                    new CarFlagEncoder(),
-                    new MotorcycleFlagEncoder(),
-                    new MountainBikeFlagEncoder(),
-                    new RacingBikeFlagEncoder(),
-                    new FootFlagEncoder()));
-
             GraphHopper hopper = new GraphHopper().
                     setStoreOnFlush(false).
-                    setEncodingManager(em).
                     setProfiles(
                             new Profile("car_profile").setVehicle("car").setWeighting("fastest"),
                             new Profile("moto_profile").setVehicle("motorcycle").setWeighting("fastest"),
@@ -986,16 +986,8 @@ public class GraphHopperOSMTest {
         HashMap<String, Integer> landmarkCount = new HashMap<>();
         // try all parallelization modes
         for (int threadCount = 1; threadCount < 6; threadCount++) {
-            EncodingManager em = EncodingManager.create(Arrays.asList(
-                    new CarFlagEncoder(),
-                    new MotorcycleFlagEncoder(),
-                    new MountainBikeFlagEncoder(),
-                    new RacingBikeFlagEncoder(),
-                    new FootFlagEncoder()));
-
             GraphHopper hopper = new GraphHopper().
                     setStoreOnFlush(false).
-                    setEncodingManager(em).
                     setProfiles(Arrays.asList(
                             new Profile("car_profile").setVehicle("car").setWeighting("fastest"),
                             new Profile("moto_profile").setVehicle("motorcycle").setWeighting("fastest"),
@@ -1083,7 +1075,6 @@ public class GraphHopperOSMTest {
 
     @Test
     public void testGetMultipleWeightingsForCH() {
-        EncodingManager em = EncodingManager.create("car");
         GraphHopper hopper = new GraphHopper().
                 setProfiles(
                         new Profile("profile1").setVehicle("car").setWeighting("fastest"),
@@ -1091,8 +1082,7 @@ public class GraphHopperOSMTest {
                 ).
                 setStoreOnFlush(false).
                 setGraphHopperLocation(ghLoc).
-                setOSMFile(testOsm).
-                setEncodingManager(em);
+                setOSMFile(testOsm);
         hopper.getCHPreparationHandler().setCHProfiles(
                 new CHProfile("profile1"), new CHProfile("profile2")
         );
@@ -1103,23 +1093,11 @@ public class GraphHopperOSMTest {
         }
     }
 
-    private GraphHopper createGraphHopper(String vehicles) {
-        EncodingManager em = EncodingManager.create(vehicles);
-        List<Profile> profiles = new ArrayList<>();
-        for (FlagEncoder enc : em.fetchEdgeEncoders()) {
-            profiles.add(new Profile(enc.toString()).setVehicle(enc.toString()).setWeighting("fastest"));
-        }
-        return new GraphHopper().
-                setEncodingManager(em).
-                setProfiles(profiles);
-    }
-
     @Test
     public void testLoadingLMAndCHProfiles() {
         GraphHopper hopper = new GraphHopper()
                 .setGraphHopperLocation(ghLoc)
                 .setOSMFile(testOsm)
-                .setEncodingManager(EncodingManager.create("car"))
                 .setProfiles(new Profile("car").setVehicle("car").setWeighting("fastest"));
         hopper.getLMPreparationHandler().setLMProfiles(new LMProfile("car"));
         hopper.getCHPreparationHandler().setCHProfiles(new CHProfile("car"));
@@ -1128,7 +1106,6 @@ public class GraphHopperOSMTest {
 
         // load without problem
         hopper = new GraphHopper()
-                .setEncodingManager(EncodingManager.create("car"))
                 .setProfiles(new Profile("car").setVehicle("car").setWeighting("fastest"));
         hopper.getLMPreparationHandler().setLMProfiles(new LMProfile("car"));
         hopper.getCHPreparationHandler().setCHProfiles(new CHProfile("car"));
@@ -1137,7 +1114,6 @@ public class GraphHopperOSMTest {
 
         // problem: changed weighting in profile although LM preparation was enabled
         hopper = new GraphHopper()
-                .setEncodingManager(EncodingManager.create("car"))
                 .setProfiles(new Profile("car").setVehicle("car").setWeighting("shortest"));
         hopper.getLMPreparationHandler().setLMProfiles(new LMProfile("car"));
         // do not load CH
@@ -1152,7 +1128,6 @@ public class GraphHopperOSMTest {
 
         // problem: changed weighting in profile although CH preparation was enabled
         hopper = new GraphHopper()
-                .setEncodingManager(EncodingManager.create("car"))
                 .setProfiles(new Profile("car").setVehicle("car").setWeighting("shortest"));
         hopper.getCHPreparationHandler().setCHProfiles(new CHProfile("car"));
         // do not load LM
@@ -1172,7 +1147,6 @@ public class GraphHopperOSMTest {
         GraphHopper hopper = new GraphHopper()
                 .setGraphHopperLocation(ghLoc)
                 .setOSMFile(testOsm)
-                .setEncodingManager(EncodingManager.create("car"))
                 .setProfiles(new CustomProfile("car").setCustomModel(customModel));
         hopper.getLMPreparationHandler().setLMProfiles(new LMProfile("car"));
         hopper.importOrLoad();
@@ -1180,7 +1154,6 @@ public class GraphHopperOSMTest {
 
         // load without problem
         hopper = new GraphHopper()
-                .setEncodingManager(EncodingManager.create("car"))
                 .setProfiles(new CustomProfile("car").setCustomModel(customModel));
         hopper.getLMPreparationHandler().setLMProfiles(new LMProfile("car"));
         assertTrue(hopper.load(ghLoc));
@@ -1189,7 +1162,6 @@ public class GraphHopperOSMTest {
         // do not load changed CustomModel
         customModel.setDistanceInfluence(100);
         hopper = new GraphHopper()
-                .setEncodingManager(EncodingManager.create("car"))
                 .setProfiles(new CustomProfile("car").setCustomModel(customModel));
         hopper.getLMPreparationHandler().setLMProfiles(new LMProfile("car"));
         try {
@@ -1204,7 +1176,7 @@ public class GraphHopperOSMTest {
 
     private int[] calcNodes(GraphHopper instance, ResponsePath responsePath) {
         List<PathDetail> edgeKeys = responsePath.getPathDetails().get("edge_key");
-        int[] result = new int[edgeKeys.size()+1];
+        int[] result = new int[edgeKeys.size() + 1];
         for (int i = 0; i < edgeKeys.size(); i++) {
             int edgeKey = (int) edgeKeys.get(i).getValue();
             int edgeId = edgeKey / 2;
diff --git a/reader-osm/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java b/reader-osm/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java
index 54d1f1300..599a43095 100644
--- a/reader-osm/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java
+++ b/reader-osm/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java
@@ -550,11 +550,7 @@ public class OSMReaderTest {
     public void testRoadAttributes() {
         String fileRoadAttributes = "test-road-attributes.xml";
         GraphHopper hopper = new GraphHopperFacade(fileRoadAttributes);
-        CarFlagEncoder encoder = new CarFlagEncoder();
-        hopper.setEncodingManager(new EncodingManager.Builder().
-                add(new OSMMaxWidthParser()).add(new OSMMaxHeightParser()).add(new OSMMaxWeightParser()).
-                add(encoder).build());
-        hopper.setProfiles(new Profile("car").setVehicle("car").setWeighting("fastest"));
+        hopper.getEncodingManagerBuilder().add(new OSMMaxWidthParser()).add(new OSMMaxHeightParser()).add(new OSMMaxWeightParser());
         hopper.importOrLoad();
 
         DecimalEncodedValue widthEnc = hopper.getEncodingManager().getDecimalEncodedValue(MaxWidth.KEY);
@@ -682,18 +678,18 @@ public class OSMReaderTest {
             }
         };
         BikeFlagEncoder bike = new BikeFlagEncoder(4, 2, 24);
-        EncodingManager manager = new EncodingManager.Builder().add(bike).add(truck).add(car).build();
 
-        GraphHopper hopper = new GraphHopper().
-                setOSMFile(getClass().getResource("test-multi-profile-turn-restrictions.xml").getFile()).
-                setGraphHopperLocation(dir).setEncodingManager(manager).
+        GraphHopper hopper = new GraphHopper();
+        hopper.getEncodingManagerBuilder().add(bike).add(truck).add(car);
+        hopper.setOSMFile(getClass().getResource("test-multi-profile-turn-restrictions.xml").getFile()).
+                setGraphHopperLocation(dir).
                 setProfiles(
                         new Profile("bike").setVehicle("bike").setWeighting("fastest"),
                         new Profile("car").setVehicle("car").setWeighting("fastest"),
                         new Profile("truck").setVehicle("truck").setWeighting("fastest")
                 ).
                 importOrLoad();
-
+        EncodingManager manager = hopper.getEncodingManager();
         DecimalEncodedValue carTCEnc = manager.getDecimalEncodedValue(TurnCost.key("car"));
         DecimalEncodedValue truckTCEnc = manager.getDecimalEncodedValue(TurnCost.key("truck"));
         DecimalEncodedValue bikeTCEnc = manager.getDecimalEncodedValue(TurnCost.key("bike"));
@@ -836,14 +832,16 @@ public class OSMReaderTest {
 
     @Test
     public void testPreferredLanguage() {
-        GraphHopper hopper = new GraphHopperFacade(file1, false, "de").importOrLoad();
+        GraphHopper hopper = new GraphHopperFacade(file1, false, "de").
+                importOrLoad();
         GraphHopperStorage graph = hopper.getGraphHopperStorage();
         int n20 = AbstractGraphStorageTester.getIdOf(graph, 52);
         EdgeIterator iter = carOutExplorer.setBaseNode(n20);
         assertTrue(iter.next());
         assertEquals("straße 123, B 122", iter.getName());
 
-        hopper = new GraphHopperFacade(file1, false, "el").importOrLoad();
+        hopper = new GraphHopperFacade(file1, false, "el").
+                importOrLoad();
         graph = hopper.getGraphHopperStorage();
         n20 = AbstractGraphStorageTester.getIdOf(graph, 52);
         iter = carOutExplorer.setBaseNode(n20);
@@ -882,7 +880,6 @@ public class OSMReaderTest {
     public void testRoutingRequestFails_issue665() {
         GraphHopper hopper = new GraphHopper()
                 .setOSMFile(getClass().getResource(file7).getFile())
-                .setEncodingManager(EncodingManager.create("car,motorcycle"))
                 .setProfiles(
                         new Profile("profile1").setVehicle("car").setWeighting("fastest"),
                         new Profile("profile2").setVehicle("motorcycle").setWeighting("curvature")
@@ -904,7 +901,6 @@ public class OSMReaderTest {
                 return new File(getClass().getResource(file2).getFile());
             }
         }.setOSMFile("dummy").
-                setEncodingManager(EncodingManager.create("car,bike")).
                 setProfiles(new Profile("profile").setVehicle("car").setWeighting("fastest")).
                 setMinNetworkSize(0).
                 setGraphHopperLocation(dir).
@@ -933,6 +929,11 @@ public class OSMReaderTest {
             setStoreOnFlush(false);
             setOSMFile(osmFile);
             setGraphHopperLocation(dir);
+            setProfiles(
+                    new Profile("foot").setVehicle("foot").setWeighting("fastest"),
+                    new Profile("car").setVehicle("car").setWeighting("fastest"),
+                    new Profile("bike").setVehicle("bike").setWeighting("fastest")
+            );
 
             BikeFlagEncoder bikeEncoder;
             if (turnCosts) {
@@ -944,14 +945,8 @@ public class OSMReaderTest {
             }
 
             footEncoder = new FootFlagEncoder();
-            setEncodingManager(new EncodingManager.Builder().add(footEncoder).add(carEncoder).add(bikeEncoder).
-                    setPreferredLanguage(prefLang).build());
-            setProfiles(
-                    new Profile("foot").setVehicle("foot").setWeighting("fastest"),
-                    new Profile("car").setVehicle("car").setWeighting("fastest"),
-                    new Profile("bike").setVehicle("bike").setWeighting("fastest")
-            );
-            carAccessEnc = carEncoder.getAccessEnc();
+            getEncodingManagerBuilder().add(footEncoder).add(carEncoder).add(bikeEncoder).
+                    setPreferredLanguage(prefLang);
         }
 
         @Override
@@ -960,8 +955,9 @@ public class OSMReaderTest {
                     getEncodingManager().needsTurnCostsSupport());
             setGraphHopperStorage(tmpGraph);
             super.importOSM();
-            carOutExplorer = getGraphHopperStorage().createEdgeExplorer(DefaultEdgeFilter.outEdges(carEncoder.getAccessEnc()));
-            carAllExplorer = getGraphHopperStorage().createEdgeExplorer(DefaultEdgeFilter.allEdges(carEncoder.getAccessEnc()));
+            carAccessEnc = carEncoder.getAccessEnc();
+            carOutExplorer = getGraphHopperStorage().createEdgeExplorer(DefaultEdgeFilter.outEdges(carAccessEnc));
+            carAllExplorer = getGraphHopperStorage().createEdgeExplorer(DefaultEdgeFilter.allEdges(carAccessEnc));
         }
 
         @Override
diff --git a/reader-osm/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java b/reader-osm/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java
index dc540eda3..a08674bac 100644
--- a/reader-osm/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java
+++ b/reader-osm/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java
@@ -44,7 +44,6 @@ import java.io.File;
 import java.io.IOException;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.Collectors;
 import java.util.zip.GZIPInputStream;
 
 import static com.graphhopper.GraphHopperTest.DIR;
@@ -637,14 +636,11 @@ public class RoutingAlgorithmWithOSMTest {
         try {
             Profile queryProfile = profiles[0];
             Helper.removeDir(new File(graphFile));
-            String encodersString = Arrays.stream(profiles).map(p -> p.getVehicle() + (p.isTurnCosts() ? "|turn_costs=true" : "")).collect(Collectors.joining(","));
-            EncodingManager em = EncodingManager.create(encodersString);
             GraphHopper hopper = new GraphHopper().
                     setStoreOnFlush(true).
                     setOSMFile(osmFile).
                     setProfiles(profiles).
-                    setGraphHopperLocation(graphFile).
-                    setEncodingManager(em);
+                    setGraphHopperLocation(graphFile);
             hopper.setMinNetworkSize(0);
 
             if (osmFile.contains("moscow"))
@@ -700,10 +696,8 @@ public class RoutingAlgorithmWithOSMTest {
         System.out.println("testMonacoParallel takes a bit time...");
         String graphFile = "target/monaco-gh";
         Helper.removeDir(new File(graphFile));
-        final EncodingManager encodingManager = EncodingManager.create("car");
         final GraphHopper hopper = new GraphHopper().
                 setStoreOnFlush(true).
-                setEncodingManager(encodingManager).
                 setWayPointMaxDistance(0).
                 setOSMFile(DIR + "/monaco.osm.gz").
                 setGraphHopperLocation(graphFile).
@@ -716,6 +710,7 @@ public class RoutingAlgorithmWithOSMTest {
         List<Thread> threads = new ArrayList<>();
         final AtomicInteger integ = new AtomicInteger(0);
         int MAX = 100;
+        EncodingManager encodingManager = hopper.getEncodingManager();
         final FlagEncoder carEncoder = encodingManager.getEncoder("car");
 
         // testing if algorithms are independent. should be. so test only two algorithms. 
@@ -773,8 +768,7 @@ public class RoutingAlgorithmWithOSMTest {
         new PrincetonReader(graph, eManager.getEncoder("car")).setStream(new GZIPInputStream(PrincetonReader.class.getResourceAsStream(bigFile))).read();
         GraphHopper hopper = new GraphHopper() {
             {
-                setEncodingManager(eManager);
-                loadGraph(graph);
+                loadGraph(graph, eManager);
             }
 
             @Override
diff --git a/web/src/test/java/com/graphhopper/http/MapMatching2Test.java b/web/src/test/java/com/graphhopper/http/MapMatching2Test.java
index efbc5976c..4293f0fac 100644
--- a/web/src/test/java/com/graphhopper/http/MapMatching2Test.java
+++ b/web/src/test/java/com/graphhopper/http/MapMatching2Test.java
@@ -58,11 +58,9 @@ public class MapMatching2Test {
 
     @Test
     public void testIssue13() throws IOException {
-        CarFlagEncoder encoder = new CarFlagEncoder();
         GraphHopper hopper = new GraphHopper();
         hopper.setOSMFile("../map-matching/files/map-issue13.osm.gz");
         hopper.setGraphHopperLocation(GH_LOCATION);
-        hopper.setEncodingManager(EncodingManager.create(encoder));
         hopper.setProfiles(new Profile("my_profile").setVehicle("car").setWeighting("fastest"));
         hopper.getLMPreparationHandler().setLMProfiles(new LMProfile("my_profile"));
         hopper.importOrLoad();
@@ -86,11 +84,9 @@ public class MapMatching2Test {
 
     @Test
     public void testIssue70() throws IOException {
-        CarFlagEncoder encoder = new CarFlagEncoder();
         GraphHopper hopper = new GraphHopper();
         hopper.setOSMFile("../map-matching/files/issue-70.osm.gz");
         hopper.setGraphHopperLocation(GH_LOCATION);
-        hopper.setEncodingManager(EncodingManager.create(encoder));
         hopper.setProfiles(new Profile("my_profile").setVehicle("car").setWeighting("fastest"));
         hopper.getLMPreparationHandler().setLMProfiles(new LMProfile("my_profile"));
         hopper.importOrLoad();
@@ -108,11 +104,9 @@ public class MapMatching2Test {
 
     @Test
     public void testIssue127() throws IOException {
-        CarFlagEncoder encoder = new CarFlagEncoder();
         GraphHopper hopper = new GraphHopper();
         hopper.setOSMFile("../map-matching/files/map-issue13.osm.gz");
         hopper.setGraphHopperLocation(GH_LOCATION);
-        hopper.setEncodingManager(EncodingManager.create(encoder));
         hopper.setProfiles(new Profile("my_profile").setVehicle("car").setWeighting("fastest"));
         hopper.getLMPreparationHandler().setLMProfiles(new LMProfile("my_profile"));
         hopper.importOrLoad();
diff --git a/web/src/test/java/com/graphhopper/http/MapMatchingTest.java b/web/src/test/java/com/graphhopper/http/MapMatchingTest.java
index 92a6df362..01910b766 100644
--- a/web/src/test/java/com/graphhopper/http/MapMatchingTest.java
+++ b/web/src/test/java/com/graphhopper/http/MapMatchingTest.java
@@ -71,11 +71,9 @@ public class MapMatchingTest {
     @BeforeClass
     public static void setup() {
         Helper.removeDir(new File(GH_LOCATION));
-        CarFlagEncoder encoder = new CarFlagEncoder();
         graphHopper = new GraphHopper();
         graphHopper.setOSMFile("../map-matching/files/leipzig_germany.osm.pbf");
         graphHopper.setGraphHopperLocation(GH_LOCATION);
-        graphHopper.setEncodingManager(EncodingManager.create(encoder));
         graphHopper.setProfiles(new Profile("my_profile").setVehicle("car").setWeighting("fastest"));
         graphHopper.getLMPreparationHandler().setLMProfiles(new LMProfile("my_profile"));
         graphHopper.importOrLoad();
diff --git a/web/src/test/java/com/graphhopper/http/RoutingAdditivityTest.java b/web/src/test/java/com/graphhopper/http/RoutingAdditivityTest.java
index 96a7fd96c..c75583f98 100644
--- a/web/src/test/java/com/graphhopper/http/RoutingAdditivityTest.java
+++ b/web/src/test/java/com/graphhopper/http/RoutingAdditivityTest.java
@@ -47,11 +47,9 @@ public class RoutingAdditivityTest {
     @BeforeAll
     public static void setup() {
         Helper.removeDir(new File(GH_LOCATION));
-        CarFlagEncoder encoder = new CarFlagEncoder();
         graphHopper = new GraphHopper();
         graphHopper.setOSMFile("../map-matching/files/leipzig_germany.osm.pbf");
         graphHopper.setGraphHopperLocation(GH_LOCATION);
-        graphHopper.setEncodingManager(EncodingManager.create(encoder));
         graphHopper.setProfiles(new Profile("my_profile").setVehicle("car").setWeighting("fastest"));
         graphHopper.getLMPreparationHandler().setLMProfiles(new LMProfile("my_profile"));
         graphHopper.importOrLoad();
@@ -62,7 +60,6 @@ public class RoutingAdditivityTest {
         graphHopper = null;
     }
 
-
     @Test
     public void testBoundedAdditivityOfGraphhopperTravelTimes() {
         ResponsePath route1 = graphHopper.route(new GHRequest(
diff --git a/web/src/test/java/com/graphhopper/http/resources/GpxTravelTimeConsistencyTest.java b/web/src/test/java/com/graphhopper/http/resources/GpxTravelTimeConsistencyTest.java
index 8bf11b23c..e4ef5e3a1 100644
--- a/web/src/test/java/com/graphhopper/http/resources/GpxTravelTimeConsistencyTest.java
+++ b/web/src/test/java/com/graphhopper/http/resources/GpxTravelTimeConsistencyTest.java
@@ -50,7 +50,6 @@ public class GpxTravelTimeConsistencyTest {
                 setProfiles(new Profile("profile").setVehicle("foot").setWeighting("fastest")).
                 setStoreOnFlush(true).
                 setGraphHopperLocation(graphFileFoot).
-                setEncodingManager(EncodingManager.create("foot")).
                 importOrLoad();
     }