@Override
  public <T> T transform(GraphContext ctx, final Object source, final T target) {
    // a source graph must be specified
    if (source == null) {
      throw new GraphException("No source graph to transform [null]", new NullPointerException());
    }

    // if no context is passed, a default one gets created
    if (ctx == null) {
      final NodeMapping mapping = getNodeMapping(source.getClass());
      final Class nodeType = mapping.getSourceConfig().getType();

      if (getSourceConfig().getNodes().containsKey(nodeType)) {
        ctx = this.createGraphContext();
      } else {
        if (getTargetConfig().getNodes().containsKey(nodeType)) {
          ctx = this.createSecondGraphContext();
        } else {
          throw new GraphException("Can't create a GraphContext");
        }
      }
    }

    final T result = graphProcessor.process(ctx, source, target);

    return result;
  }
  @Override
  public void addNodeMapping(final NodeMapping cfg) {
    super.addNodeMapping(cfg);

    // add bi-directional mapping
    final Class<?> src = cfg.getTargetConfig().getType();
    final Class<?> dest = cfg.getSourceConfig().getType();
    final NodeMapping targetNode = new DefaultNodeMapping(this, src, dest);

    this.nodeMappings.put(targetNode.getSourceConfig().getType(), targetNode);
  }