/**
   * helper to load nodes relation to document
   *
   * @param document relationLink document/link
   * @param direction "in" or "out"
   * @return INode instance or null
   */
  private @Nullable INode getRelatedEntity(ODocument document, String direction) {
    Object nodeO = document.field(direction, ORecordId.class);
    if (nodeO == null) {
      logger.error(
          "Could not create related entity while converting relation with direction " + direction);
      return null;
    }
    if (nodeO instanceof ORecordId) nodeO = repositoryFactory.getDb().load((ORecordId) nodeO);
    if (nodeO == null) {
      logger.error("Invalid record in direction " + direction + ": " + document.toString());
      return null;
    }

    // convert
    ODocument nodeDoc = (ODocument) nodeO;

    // slim node: just set title and id
    INode node = new Node();
    node.setTitle(nodeDoc.field("title"));
    node.setId(nodeDoc.getIdentity().toString());

    return node;

    /*
    old -not performant
    String id;
    if (relationO instanceof OIdentifiable) id = ((ORecordId)relationO).getIdentity().toString();
    else {
    	logger.error("Invalid class type: " + relationO.getClass().getName());
    	return null;
    }

    return nodeRepository.find(id);*/
  }
  @Override
  public boolean save(IRelation entity) {
    try {
      // sanity: we need from and to entity to do this!
      if (entity.getFromEntity() == null || entity.getToEntity() == null) {
        logger.error("From and/or to-entity not set in relation: Not saving!");
        return false;
      }

      initDb();

      // process before saving
      entity = processBeforeSaving(entity);

      // create document - call special method
      ODocument document = reallyConvertToDocument(entity);

      ODocument relationLink = getRelationLink(document, false);
      if (relationLink == null) { // no relation yet => create new one
        // create edge and set it to document
        List<OIdentifiable> edgeList =
            repositoryFactory
                .getDb()
                .command(
                    new OCommandSQL(
                        "create edge IsRelation from "
                            + entity.getFromEntity().getId()
                            + " to "
                            + entity.getToEntity().getId()))
                .execute();
        document.field("relationLink", (ORecordId) edgeList.get(0).getIdentity());

        if (logger.isTraceEnabled())
          logger.trace("Created brank new IsRelation edge: " + edgeList.get(0).toString());
      } else {
        // check whether relation has changed
        String oldFromId = relationLink.field("out", ORecordId.class).toString();
        String oldToId = relationLink.field("in", ORecordId.class).toString();

        String newFromId = entity.getFromEntity().getId();
        String newToId = entity.getToEntity().getId();

        // check equality
        if (!oldFromId.equals(newFromId) || !oldToId.equals(newToId)) {
          // delete old edge and create new one
          relationLink.delete();

          List<OrientEdge> edgeList =
              repositoryFactory
                  .getDb()
                  .command(
                      new OCommandSQL(
                          "create edge IsRelation from "
                              + entity.getFromEntity().getId()
                              + " to "
                              + entity.getToEntity().getId()))
                  .execute();
          document.field("relationLink", (ORecordId) edgeList.get(0).getId());

          if (logger.isTraceEnabled())
            logger.trace(
                "Replace IsRelation edge: "
                    + edgeList.get(0).toString()
                    + " (was: "
                    + relationLink.toString()
                    + ")");
        }
      }

      // save
      ODocument updated = db.save(document);

      // process after saving
      processAfterSaving(updated, entity);

      if (logger.isInfoEnabled()) logger.info("Saved entity: " + entity.toString());

      return true;
    } catch (Exception e) {
      logger.error("Exception thrown while saving entity.", e);
    }

    return false;
  }