/**
   * Load step attributes.
   *
   * @throws KettleException the kettle exception
   */
  protected void loadStepAttributes() throws KettleException {
    try {
      InputStream inputStream = getClass().getResourceAsStream(STEP_ATTRIBUTES_FILE);
      if (inputStream != null) {
        Document document = XMLHandler.loadXMLFile(inputStream);
        Node attrsNode = XMLHandler.getSubNode(document, "attributes");
        List<Node> nodes = XMLHandler.getNodes(attrsNode, "attribute");
        attributes = new ArrayList<KettleAttributeInterface>();
        for (Node node : nodes) {
          String key = XMLHandler.getTagAttribute(node, "id");
          String xmlCode = XMLHandler.getTagValue(node, "xmlcode");
          String repCode = XMLHandler.getTagValue(node, "repcode");
          String description = XMLHandler.getTagValue(node, "description");
          String tooltip = XMLHandler.getTagValue(node, "tooltip");
          int valueType = ValueMeta.getType(XMLHandler.getTagValue(node, "valuetype"));
          String parentId = XMLHandler.getTagValue(node, "parentid");

          KettleAttribute attribute =
              new KettleAttribute(
                  key,
                  xmlCode,
                  repCode,
                  description,
                  tooltip,
                  valueType,
                  findParent(attributes, parentId));
          attributes.add(attribute);
        }
      }
    } catch (Exception e) {
      throw new KettleException("Unable to load file " + STEP_ATTRIBUTES_FILE, e);
    }
  }
  private static List<FieldVariableMapping> extractFieldVariableMapping(Node serviceNode) {
    List<FieldVariableMapping> map = new ArrayList<FieldVariableMapping>();

    List<Node> nodes =
        XMLHandler.getNodes(
            XMLHandler.getSubNode(serviceNode, XML_TAG_VARIABLE_MAPS), XML_TAG_VARIABLE_MAP);
    for (Node node : nodes) {
      String field = XMLHandler.getTagValue(node, "field");
      String target = XMLHandler.getTagValue(node, "target");
      String variable = XMLHandler.getTagValue(node, "variable");
      MappingType mappingType =
          FieldVariableMapping.MappingType.getMappingType(XMLHandler.getTagValue(node, "type"));
      map.add(new FieldVariableMapping(field, target, variable, mappingType));
    }

    return map;
  }
  /** Scan & register internal step plugins */
  protected void registerNatives() throws KettlePluginException {
    // Scan the native steps...
    //
    String kettleStepsXmlFile = Const.XML_FILE_KETTLE_STEPS;
    String alternative = System.getProperty(Const.KETTLE_CORE_STEPS_FILE, null);
    if (!Const.isEmpty(alternative)) {
      kettleStepsXmlFile = alternative;
    }

    // Load the plugins for this file...
    //
    try {
      InputStream inputStream = getClass().getResourceAsStream(kettleStepsXmlFile);
      if (inputStream == null) {
        inputStream = getClass().getResourceAsStream("/" + kettleStepsXmlFile);
      }
      // Retry to load a regular file...
      if (inputStream == null && !Const.isEmpty(alternative)) {
        try {
          inputStream = new FileInputStream(kettleStepsXmlFile);
        } catch (Exception e) {
          throw new KettlePluginException(
              "Unable to load native step plugins '" + kettleStepsXmlFile + "'", e);
        }
      }
      if (inputStream == null) {
        throw new KettlePluginException(
            "Unable to find native step definition file: " + Const.XML_FILE_KETTLE_STEPS);
      }
      Document document = XMLHandler.loadXMLFile(inputStream, null, true, false);

      // Document document = XMLHandler.loadXMLFile(kettleStepsXmlFile);

      Node stepsNode = XMLHandler.getSubNode(document, "steps");
      List<Node> stepNodes = XMLHandler.getNodes(stepsNode, "step");
      for (Node stepNode : stepNodes) {
        registerPluginFromXmlResource(stepNode, null, this.getClass(), true, null);
      }

    } catch (KettleXMLException e) {
      throw new KettlePluginException(
          "Unable to read the kettle steps XML config file: " + kettleStepsXmlFile, e);
    }
  }