public static DarkClusterConfigMap toConfig(Map<String, Object> properties)
  {
    DarkClusterConfigMap configMap = new DarkClusterConfigMap();
    for (Map.Entry<String, Object> entry : properties.entrySet())
    {
      String darkClusterName = entry.getKey();
      DarkClusterConfig darkClusterConfig = new DarkClusterConfig();
      @SuppressWarnings("unchecked")
      Map<String, Object> props = (Map<String, Object>) entry.getValue();
      if (props.containsKey(PropertyKeys.DARK_CLUSTER_MULTIPLIER))
      {
        darkClusterConfig.setMultiplier(PropertyUtil.coerce(props.get(PropertyKeys.DARK_CLUSTER_MULTIPLIER), Float.class));
      }
      else
      {
        // to maintain backwards compatibility with previously ser/de, set the default on deserialization
        darkClusterConfig.setMultiplier(DARK_CLUSTER_DEFAULT_MULTIPLIER);
      }

      if (props.containsKey(PropertyKeys.DARK_CLUSTER_OUTBOUND_TARGET_RATE))
      {
        darkClusterConfig.setDispatcherOutboundTargetRate(
            PropertyUtil.coerce(props.get(PropertyKeys.DARK_CLUSTER_OUTBOUND_TARGET_RATE), Float.class));
      }
      else
      {
        darkClusterConfig.setDispatcherOutboundTargetRate(DARK_CLUSTER_DEFAULT_TARGET_RATE);
      }

      if (props.containsKey(PropertyKeys.DARK_CLUSTER_MAX_REQUESTS_TO_BUFFER))
      {
        darkClusterConfig.setDispatcherMaxRequestsToBuffer(
            PropertyUtil.coerce(props.get(PropertyKeys.DARK_CLUSTER_MAX_REQUESTS_TO_BUFFER), Integer.class));
      }
      else
      {
        darkClusterConfig.setDispatcherMaxRequestsToBuffer(DARK_CLUSTER_DEFAULT_MAX_REQUESTS_TO_BUFFER);
      }

      if (props.containsKey(PropertyKeys.DARK_CLUSTER_BUFFERED_REQUEST_EXPIRY_IN_SECONDS))
      {
        darkClusterConfig.setDispatcherBufferedRequestExpiryInSeconds(
            PropertyUtil.coerce(props.get(PropertyKeys.DARK_CLUSTER_BUFFERED_REQUEST_EXPIRY_IN_SECONDS), Integer.class));
      }
      else
      {
        darkClusterConfig.setDispatcherBufferedRequestExpiryInSeconds(DARK_CLUSTER_DEFAULT_BUFFERED_REQUEST_EXPIRY_IN_SECONDS);
      }

      if (props.containsKey(PropertyKeys.DARK_CLUSTER_STRATEGY_LIST))
      {
        DataList dataList = new DataList();
        @SuppressWarnings("unchecked")
        List<String> strategyList = (List<String>)props.get(PropertyKeys.DARK_CLUSTER_STRATEGY_LIST);
        dataList.addAll(strategyList);

        DarkClusterStrategyNameArray darkClusterStrategyNameArray = new DarkClusterStrategyNameArray(dataList);
        darkClusterConfig.setDarkClusterStrategyPrioritizedList(darkClusterStrategyNameArray);
      }

      if (props.containsKey(PropertyKeys.DARK_CLUSTER_TRANSPORT_CLIENT_PROPERTIES))
      {
        @SuppressWarnings("unchecked")
        D2TransportClientProperties transportClientProperties = TransportClientPropertiesConverter.toConfig(
          (Map<String, Object>)props.get(PropertyKeys.DARK_CLUSTER_TRANSPORT_CLIENT_PROPERTIES));
        darkClusterConfig.setTransportClientProperties(transportClientProperties);
      }
      configMap.put(darkClusterName, darkClusterConfig);
    }
    return configMap;
  }
@Test
  public void testBadStrategies()
  {
    Map<String, Object> props = new HashMap<>();
    List<String> myStrategyList = new ArrayList<>();
    myStrategyList.add("RELATIVE_TRAFFIC");
    myStrategyList.add("BLAH_BLAH");

    Map<String, Object> darkClusterMap = new HashMap<>();
    darkClusterMap.put(PropertyKeys.DARK_CLUSTER_STRATEGY_LIST, myStrategyList);
    props.put(DARK_CLUSTER_KEY, darkClusterMap);
    DarkClusterConfigMap configMap = DarkClustersConverter.toConfig(props);
    DarkClusterStrategyNameArray strategyList = configMap.get(DARK_CLUSTER_KEY).getDarkClusterStrategyPrioritizedList();
    Assert.assertEquals(strategyList.get(0), DarkClusterStrategyName.RELATIVE_TRAFFIC, "first strategy should be RELATIVE_TRAFFIC");

    // the bad strategy BLAH_BLAH gets converted to unknown on access
    Assert.assertEquals(strategyList.get(1), DarkClusterStrategyName.$UNKNOWN, "second strategy should be unknown");
  }