private void getFields(List<RpcField> fields, Iterator<?> parent) throws Exception {
    List<?> convertedIterator = null;

    SOAPElement element;
    for (RpcField field : fields) {
      if (field.getDirection() == Direction.INPUT) {
        continue;
      }

      if (field.getName().equals(WsRpcActionUtil.FORCED_CHILD)) {
        continue;
      }

      if (convertedIterator == null) {
        convertedIterator = IteratorUtils.toList(parent);
      }

      switch (getFieldType(field)) {
        case simple:
          RpcFlatField flatField = (RpcFlatField) field;
          element = findSOAPElement(convertedIterator, flatField.getOriginalName());
          logAndRemoveElementFromList(element, flatField.getOriginalName(), convertedIterator);

          if (element == null) {
            continue;
          }

          FieldUtil.readPrimitiveField(flatField, element);
          break;
        case structure:
          SimpleRpcStructureField structureField = (SimpleRpcStructureField) field;
          element = findSOAPElement(convertedIterator, structureField.getOriginalName());
          logAndRemoveElementFromList(element, structureField.getOriginalName(), convertedIterator);

          if (element == null) {
            continue;
          }

          if (structureField.getExpandedElements() != null) {
            for (String expanded : structureField.getExpandedElements()) {
              List<?> localConvertedIterator = IteratorUtils.toList(element.getChildElements());
              element = findSOAPElement(localConvertedIterator, expanded);
              logAndRemoveElementFromList(element, expanded, localConvertedIterator);

              if (element == null) {
                break;
              }
            }
          }

          if (element == null) {
            continue;
          }
          getFields(structureField.getChildrens(), element.getChildElements());
          break;
        case list:
          SimpleRpcStructureListField listField = (SimpleRpcStructureListField) field;
          if (listField.getOriginalName() != null) {
            if (!listField.getOriginalName().equals("")) {
              element = findSOAPElement(convertedIterator, listField.getOriginalNameForList());
              logAndRemoveElementFromList(
                  element, listField.getOriginalNameForList(), convertedIterator);
              if (element != null) {
                convertedIterator = IteratorUtils.toList(element.getChildElements());
              }
            }
          }

          List<RpcFields> childrens = listField.getChildrens();

          for (int i = 0; i < childrens.size(); i++) {
            element = findSOAPElement(convertedIterator, listField.getOriginalName());
            logAndRemoveElementFromList(element, listField.getOriginalName(), convertedIterator);
            if (element == null) {
              continue;
            }
            getFields(childrens.get(i).getFields(), element.getChildElements());
          }
          break;
      }
    }
  }
  private void setFields(List<RpcField> fields, SOAPElement actionElement) throws SOAPException {
    boolean elementFormDefault = actionData.getElementFormDefaultUse().equals("true");

    for (RpcField field : fields) {
      if (field.getDirection() == Direction.OUTPUT) {
        continue;
      }

      if (field.getName().equals(WsRpcActionUtil.FORCED_CHILD)) {
        continue;
      }

      SOAPElement element;
      switch (getFieldType(field)) {
        case simple:
          RpcFlatField flatField = (RpcFlatField) field;
          element =
              elementFormDefault
                  ? actionElement.addChildElement(flatField.getOriginalName(), ACTION_PREFIX)
                  : actionElement.addChildElement(flatField.getOriginalName());
          FieldUtil.writePrimitiveField((RpcFlatField) field, element);
          break;
        case structure:
          SimpleRpcStructureField structureField = (SimpleRpcStructureField) field;
          String soapElement = structureField.getOriginalName();

          element =
              (elementFormDefault || useFirstElementPrefix)
                  ? actionElement.addChildElement(soapElement, ACTION_PREFIX)
                  : actionElement.addChildElement(soapElement);
          useFirstElementPrefix = false;
          if (structureField.getExpandedElements() != null) {
            for (String expected : structureField.getExpandedElements()) {
              element =
                  elementFormDefault
                      ? element.addChildElement(expected, ACTION_PREFIX)
                      : element.addChildElement(expected);
            }
          }
          setFields(structureField.getChildrens(), element);
          break;
        case list:
          SimpleRpcStructureListField listField = (SimpleRpcStructureListField) field;
          if (listField.getOriginalName() != null) {
            if (!listField.getOriginalName().equals("")) {
              String listOriginalName = listField.getOriginalNameForList();
              actionElement =
                  (elementFormDefault || useFirstElementPrefix)
                      ? actionElement.addChildElement(listOriginalName, ACTION_PREFIX)
                      : actionElement.addChildElement(listOriginalName);
              useFirstElementPrefix = false;
            }
          }
          List<RpcFields> childrens = listField.getChildrens();
          for (int i = 0; i < childrens.size(); i++) {
            element =
                (elementFormDefault || useFirstElementPrefix)
                    ? actionElement.addChildElement(listField.getOriginalName(), ACTION_PREFIX)
                    : actionElement.addChildElement(listField.getOriginalName());
            useFirstElementPrefix = false;
            setFields(childrens.get(i).getFields(), element);
          }
          break;
      }
    }
  }