private void saveTransformationDetails(final DataNode rootNode, final TransMeta transMeta)
      throws KettleException {

    rootNode.setProperty(PROP_EXTENDED_DESCRIPTION, transMeta.getExtendedDescription());
    rootNode.setProperty(PROP_TRANS_VERSION, transMeta.getTransversion());
    rootNode.setProperty(
        PROP_TRANS_STATUS, transMeta.getTransstatus() < 0 ? -1L : transMeta.getTransstatus());

    rootNode.setProperty(PROP_STEP_READ, transMeta.getTransLogTable().getStepnameRead());
    rootNode.setProperty(PROP_STEP_WRITE, transMeta.getTransLogTable().getStepnameWritten());
    rootNode.setProperty(PROP_STEP_INPUT, transMeta.getTransLogTable().getStepnameInput());
    rootNode.setProperty(PROP_STEP_OUTPUT, transMeta.getTransLogTable().getStepnameOutput());
    rootNode.setProperty(PROP_STEP_UPDATE, transMeta.getTransLogTable().getStepnameUpdated());
    rootNode.setProperty(PROP_STEP_REJECTED, transMeta.getTransLogTable().getStepnameRejected());

    if (transMeta.getTransLogTable().getDatabaseMeta() != null) {
      DataNodeRef ref =
          new DataNodeRef(transMeta.getTransLogTable().getDatabaseMeta().getObjectId().getId());
      rootNode.setProperty(PROP_DATABASE_LOG, ref);
    }

    rootNode.setProperty(PROP_TABLE_NAME_LOG, transMeta.getTransLogTable().getTableName());

    rootNode.setProperty(
        PROP_USE_BATCHID, Boolean.valueOf(transMeta.getTransLogTable().isBatchIdUsed()));
    rootNode.setProperty(
        PROP_USE_LOGFIELD, Boolean.valueOf(transMeta.getTransLogTable().isLogFieldUsed()));

    if (transMeta.getMaxDateConnection() != null) {
      DataNodeRef ref = new DataNodeRef(transMeta.getMaxDateConnection().getObjectId().getId());
      rootNode.setProperty(PROP_ID_DATABASE_MAXDATE, ref);
    }

    rootNode.setProperty(PROP_TABLE_NAME_MAXDATE, transMeta.getMaxDateTable());
    rootNode.setProperty(PROP_FIELD_NAME_MAXDATE, transMeta.getMaxDateField());
    rootNode.setProperty(PROP_OFFSET_MAXDATE, new Double(transMeta.getMaxDateOffset()));
    rootNode.setProperty(PROP_DIFF_MAXDATE, new Double(transMeta.getMaxDateDifference()));

    rootNode.setProperty(PROP_CREATED_USER, transMeta.getCreatedUser());
    rootNode.setProperty(PROP_CREATED_DATE, transMeta.getCreatedDate());

    rootNode.setProperty(PROP_MODIFIED_USER, transMeta.getModifiedUser());
    rootNode.setProperty(PROP_MODIFIED_DATE, transMeta.getModifiedDate());

    rootNode.setProperty(PROP_SIZE_ROWSET, transMeta.getSizeRowset());

    rootNode.setProperty(PROP_UNIQUE_CONNECTIONS, transMeta.isUsingUniqueConnections());
    rootNode.setProperty(PROP_FEEDBACK_SHOWN, transMeta.isFeedbackShown());
    rootNode.setProperty(PROP_FEEDBACK_SIZE, transMeta.getFeedbackSize());
    rootNode.setProperty(PROP_USING_THREAD_PRIORITIES, transMeta.isUsingThreadPriorityManagment());
    rootNode.setProperty(PROP_SHARED_FILE, transMeta.getSharedObjectsFile());

    rootNode.setProperty(
        PROP_CAPTURE_STEP_PERFORMANCE, transMeta.isCapturingStepPerformanceSnapShots());
    rootNode.setProperty(
        PROP_STEP_PERFORMANCE_CAPTURING_DELAY, transMeta.getStepPerformanceCapturingDelay());
    rootNode.setProperty(
        PROP_STEP_PERFORMANCE_CAPTURING_SIZE_LIMIT,
        transMeta.getStepPerformanceCapturingSizeLimit());
    rootNode.setProperty(
        PROP_STEP_PERFORMANCE_LOG_TABLE, transMeta.getPerformanceLogTable().getTableName());

    rootNode.setProperty(PROP_LOG_SIZE_LIMIT, transMeta.getTransLogTable().getLogSizeLimit());
    rootNode.setProperty(PROP_LOG_INTERVAL, transMeta.getTransLogTable().getLogInterval());

    rootNode.setProperty(PROP_TRANSFORMATION_TYPE, transMeta.getTransformationType().getCode());

    // Save the logging tables too..
    //
    RepositoryAttributeInterface attributeInterface =
        new PurRepositoryAttribute(rootNode, transMeta.getDatabases());
    for (LogTableInterface logTable : transMeta.getLogTables()) {
      logTable.saveToRepository(attributeInterface);
    }

    // Save the transformation attribute groups map
    //
    AttributesMapUtil.saveAttributesMap(rootNode, transMeta);
  }
  protected void loadTransformationDetails(final DataNode rootNode, final TransMeta transMeta)
      throws KettleException {
    transMeta.setExtendedDescription(getString(rootNode, PROP_EXTENDED_DESCRIPTION));
    transMeta.setTransversion(getString(rootNode, PROP_TRANS_VERSION));
    transMeta.setTransstatus((int) rootNode.getProperty(PROP_TRANS_STATUS).getLong());

    if (rootNode.hasProperty(PROP_STEP_READ)) {
      transMeta
          .getTransLogTable()
          .setStepRead(
              StepMeta.findStep(transMeta.getSteps(), getString(rootNode, PROP_STEP_READ)));
    }
    if (rootNode.hasProperty(PROP_STEP_WRITE)) {
      transMeta
          .getTransLogTable()
          .setStepWritten(
              StepMeta.findStep(transMeta.getSteps(), getString(rootNode, PROP_STEP_WRITE)));
    }
    if (rootNode.hasProperty(PROP_STEP_INPUT)) {
      transMeta
          .getTransLogTable()
          .setStepInput(
              StepMeta.findStep(transMeta.getSteps(), getString(rootNode, PROP_STEP_INPUT)));
    }
    if (rootNode.hasProperty(PROP_STEP_OUTPUT)) {
      transMeta
          .getTransLogTable()
          .setStepOutput(
              StepMeta.findStep(transMeta.getSteps(), getString(rootNode, PROP_STEP_OUTPUT)));
    }
    if (rootNode.hasProperty(PROP_STEP_UPDATE)) {
      transMeta
          .getTransLogTable()
          .setStepUpdate(
              StepMeta.findStep(transMeta.getSteps(), getString(rootNode, PROP_STEP_UPDATE)));
    }
    if (rootNode.hasProperty(PROP_STEP_REJECTED)) {
      transMeta
          .getTransLogTable()
          .setStepRejected(
              StepMeta.findStep(transMeta.getSteps(), getString(rootNode, PROP_STEP_REJECTED)));
    }

    if (rootNode.hasProperty(PROP_DATABASE_LOG)) {
      String id = rootNode.getProperty(PROP_DATABASE_LOG).getRef().getId().toString();
      DatabaseMeta conn =
          DatabaseMeta.findDatabase(transMeta.getDatabases(), new StringObjectId(id));
      transMeta.getTransLogTable().setConnectionName(conn.getName());
    }
    transMeta.getTransLogTable().setTableName(getString(rootNode, PROP_TABLE_NAME_LOG));
    transMeta
        .getTransLogTable()
        .setBatchIdUsed(rootNode.getProperty(PROP_USE_BATCHID).getBoolean());
    transMeta
        .getTransLogTable()
        .setLogFieldUsed(rootNode.getProperty(PROP_USE_LOGFIELD).getBoolean());

    if (rootNode.hasProperty(PROP_ID_DATABASE_MAXDATE)) {
      String id = rootNode.getProperty(PROP_ID_DATABASE_MAXDATE).getRef().getId().toString();
      transMeta.setMaxDateConnection(
          DatabaseMeta.findDatabase(transMeta.getDatabases(), new StringObjectId(id)));
    }
    transMeta.setMaxDateTable(getString(rootNode, PROP_TABLE_NAME_MAXDATE));
    transMeta.setMaxDateField(getString(rootNode, PROP_FIELD_NAME_MAXDATE));
    transMeta.setMaxDateOffset(rootNode.getProperty(PROP_OFFSET_MAXDATE).getDouble());
    transMeta.setMaxDateDifference(rootNode.getProperty(PROP_DIFF_MAXDATE).getDouble());

    transMeta.setCreatedUser(getString(rootNode, PROP_CREATED_USER));
    transMeta.setCreatedDate(getDate(rootNode, PROP_CREATED_DATE));

    transMeta.setModifiedUser(getString(rootNode, PROP_MODIFIED_USER));
    transMeta.setModifiedDate(getDate(rootNode, PROP_MODIFIED_DATE));

    // Optional:
    transMeta.setSizeRowset(Const.ROWS_IN_ROWSET);
    long val_size_rowset = rootNode.getProperty(PROP_SIZE_ROWSET).getLong();
    if (val_size_rowset > 0) {
      transMeta.setSizeRowset((int) val_size_rowset);
    }

    if (rootNode.hasProperty(PROP_ID_DIRECTORY)) {
      String id_directory = getString(rootNode, PROP_ID_DIRECTORY);
      if (log.isDetailed()) {
        log.logDetailed(toString(), PROP_ID_DIRECTORY + "=" + id_directory); // $NON-NLS-1$
      }
      // Set right directory...
      transMeta.setRepositoryDirectory(
          repo.findDirectory(new StringObjectId(id_directory))); // always reload the
      // folder structure
    }

    transMeta.setUsingUniqueConnections(rootNode.getProperty(PROP_UNIQUE_CONNECTIONS).getBoolean());
    boolean feedbackShown = true;
    if (rootNode.hasProperty(PROP_FEEDBACK_SHOWN)) {
      feedbackShown = rootNode.getProperty(PROP_FEEDBACK_SHOWN).getBoolean();
    }
    transMeta.setFeedbackShown(feedbackShown);
    transMeta.setFeedbackSize((int) rootNode.getProperty(PROP_FEEDBACK_SIZE).getLong());
    boolean usingThreadPriorityManagement = true;
    if (rootNode.hasProperty(PROP_USING_THREAD_PRIORITIES)) {
      usingThreadPriorityManagement =
          rootNode.getProperty(PROP_USING_THREAD_PRIORITIES).getBoolean();
    }
    transMeta.setUsingThreadPriorityManagment(usingThreadPriorityManagement);
    transMeta.setSharedObjectsFile(getString(rootNode, PROP_SHARED_FILE));
    String transTypeCode = getString(rootNode, PROP_TRANSFORMATION_TYPE);
    transMeta.setTransformationType(TransformationType.getTransformationTypeByCode(transTypeCode));

    // Performance monitoring for steps...
    //
    boolean capturingStepPerformanceSnapShots = true;
    if (rootNode.hasProperty(PROP_CAPTURE_STEP_PERFORMANCE)) {
      capturingStepPerformanceSnapShots =
          rootNode.getProperty(PROP_CAPTURE_STEP_PERFORMANCE).getBoolean();
    }
    transMeta.setCapturingStepPerformanceSnapShots(capturingStepPerformanceSnapShots);
    transMeta.setStepPerformanceCapturingDelay(
        getLong(rootNode, PROP_STEP_PERFORMANCE_CAPTURING_DELAY));
    transMeta.setStepPerformanceCapturingSizeLimit(
        getString(rootNode, PROP_STEP_PERFORMANCE_CAPTURING_SIZE_LIMIT));
    transMeta
        .getPerformanceLogTable()
        .setTableName(getString(rootNode, PROP_STEP_PERFORMANCE_LOG_TABLE));
    transMeta.getTransLogTable().setLogSizeLimit(getString(rootNode, PROP_LOG_SIZE_LIMIT));

    // Load the logging tables too..
    //
    RepositoryAttributeInterface attributeInterface =
        new PurRepositoryAttribute(rootNode, transMeta.getDatabases());
    for (LogTableInterface logTable : transMeta.getLogTables()) {
      logTable.loadFromRepository(attributeInterface);
    }

    AttributesMapUtil.loadAttributesMap(rootNode, transMeta);
  }