@Override
  public void configure(final Map<String, Object> config, final Map<String, Graph> graphs) {
    final GryoMapper.Builder builder;
    final Object graphToUseForMapper = config.get(TOKEN_USE_MAPPER_FROM_GRAPH);
    if (graphToUseForMapper != null) {
      if (null == graphs)
        throw new IllegalStateException(
            String.format(
                "No graphs have been provided to the serializer and therefore %s is not a valid configuration",
                TOKEN_USE_MAPPER_FROM_GRAPH));

      final Graph g = graphs.get(graphToUseForMapper.toString());
      if (null == g)
        throw new IllegalStateException(
            String.format(
                "There is no graph named [%s] configured to be used in the %s setting",
                graphToUseForMapper, TOKEN_USE_MAPPER_FROM_GRAPH));

      // a graph was found so use the mapper it constructs.  this allows gryo to be auto-configured
      // with any
      // custom classes that the implementation allows for
      builder = g.io(GryoIo.build()).mapper();
    } else {
      // no graph was supplied so just use the default - this will likely be the case when using a
      // graph
      // with no custom classes or a situation where the user needs complete control like when using
      // two
      // distinct implementations each with their own custom classes.
      builder = GryoMapper.build();
    }

    addIoRegistries(config, builder);
    addCustomClasses(config, builder);

    this.serializeToString =
        Boolean.parseBoolean(
            config.getOrDefault(TOKEN_SERIALIZE_RESULT_TO_STRING, "false").toString());

    this.gryoMapper = builder.create();
  }
  private void addCustomClasses(
      final Map<String, Object> config, final GryoMapper.Builder builder) {
    final List<String> classNameList = getClassNamesFromConfig(TOKEN_CUSTOM, config);

    classNameList
        .stream()
        .forEach(
            serializerDefinition -> {
              String className;
              Optional<String> serializerName;
              if (serializerDefinition.contains(";")) {
                final String[] split = serializerDefinition.split(";");
                if (split.length != 2)
                  throw new IllegalStateException(
                      String.format(
                          "Invalid format for serializer definition [%s] - expected <class>;<serializer-class>",
                          serializerDefinition));

                className = split[0];
                serializerName = Optional.of(split[1]);
              } else {
                serializerName = Optional.empty();
                className = serializerDefinition;
              }

              try {
                final Class clazz = Class.forName(className);
                final Serializer serializer;
                if (serializerName.isPresent()) {
                  final Class serializerClazz = Class.forName(serializerName.get());
                  serializer = (Serializer) serializerClazz.newInstance();
                  builder.addCustom(clazz, kryo -> serializer);
                } else builder.addCustom(clazz);
              } catch (Exception ex) {
                throw new IllegalStateException("Class could not be found", ex);
              }
            });
  }
  private void addIoRegistries(final Map<String, Object> config, final GryoMapper.Builder builder) {
    final List<String> classNameList = getClassNamesFromConfig(TOKEN_IO_REGISTRIES, config);

    classNameList
        .stream()
        .forEach(
            className -> {
              try {
                final Class<?> clazz = Class.forName(className);
                try {
                  final Method instanceMethod = clazz.getDeclaredMethod("getInstance");
                  if (IoRegistry.class.isAssignableFrom(instanceMethod.getReturnType()))
                    builder.addRegistry((IoRegistry) instanceMethod.invoke(null));
                  else throw new Exception();
                } catch (Exception methodex) {
                  // tried getInstance() and that failed so try newInstance() no-arg constructor
                  builder.addRegistry((IoRegistry) clazz.newInstance());
                }
              } catch (Exception ex) {
                throw new IllegalStateException(ex);
              }
            });
  }