/**
   * This method returns the input values for given foreach node
   *
   * @param forEachNode
   * @param listOfValues
   * @param invokerMap
   * @return
   * @throws WorkflowException
   */
  public static Object getInputsForForEachNode(
      final ForEachNode forEachNode,
      final LinkedList<String> listOfValues,
      Map<Node, Invoker> invokerMap)
      throws WorkflowException {
    List<DataPort> inputPorts = forEachNode.getInputPorts();

    Object returnValForProvenance = null;
    for (DataPort inputPort : inputPorts) {

      Node inputNode = inputPort.getFromNode();
      // if input node for for-each is WSNode
      if (inputNode instanceof InputNode) {
        //                for (DataPort dataPort : forEachNode.getInputPorts()) {
        returnValForProvenance = InterpreterUtil.findInputFromPort(inputPort, invokerMap);
        if (null == returnValForProvenance) {
          throw new WorkFlowInterpreterException(
              "Unable to find input for the node:" + forEachNode.getID());
        }
        String[] vals = StringUtil.getElementsFromString(returnValForProvenance.toString());
        listOfValues.addAll(Arrays.asList(vals));
        //                }
      } else {
        Invoker workflowInvoker = invokerMap.get(inputNode);
        if (workflowInvoker != null) {
          if (workflowInvoker instanceof GenericInvoker) {

            String outputName = inputNode.getOutputPort(0).getName();
            returnValForProvenance = workflowInvoker.getOutput(outputName);
            Iterator children = null;
            if (returnValForProvenance instanceof org.xmlpull.v1.builder.XmlElement) {
              org.xmlpull.v1.builder.XmlElement msgElmt =
                  (org.xmlpull.v1.builder.XmlElement) returnValForProvenance;
              children = msgElmt.children();
            } else {
              XmlElement msgElmt =
                  XmlConstants.BUILDER.parseFragmentFromString(
                      "<temp>" + returnValForProvenance + "</temp>");
              children = msgElmt.children().iterator();
            }
            while (children.hasNext()) {
              Object object = children.next();
              if (object instanceof org.xmlpull.v1.builder.XmlElement) {
                org.xmlpull.v1.builder.XmlElement child =
                    (org.xmlpull.v1.builder.XmlElement) object;
                Iterator valItr = child.children();
                if (valItr.hasNext()) {
                  Object object2 = valItr.next();
                  if (object2 instanceof String) {
                    listOfValues.add(object2.toString());
                  }
                }
              }
              if (object instanceof XmlElement) {
                listOfValues.add(((XmlElement) object).children().iterator().next().toString());
              }
              if (object instanceof String) {
                listOfValues.add(object.toString());
              }
            }
          } else if (workflowInvoker instanceof SystemComponentInvoker) {
            int index = inputNode.getOutputPorts().indexOf(inputPort.getEdge(0).getFromPort());
            String outputName = "";
            if (inputNode.getInputPort(index) instanceof SystemDataPort) {
              outputName =
                  ((SystemDataPort) inputNode.getInputPort(index)).getWSComponentPort().getName();
            } else if (inputNode.getInputPort(index) instanceof WSPort) {
              outputName =
                  ((SystemDataPort)
                          inputNode.getInputPort(
                              inputNode
                                  .getOutputPorts()
                                  .indexOf(inputPort.getEdge(0).getFromPort())))
                      .getWSComponentPort()
                      .getName();
            }
            returnValForProvenance = workflowInvoker.getOutput(outputName);
            XmlElement msgElmt =
                XmlConstants.BUILDER.parseFragmentFromString(
                    "<temp>" + returnValForProvenance + "</temp>");
            Iterator valItr = msgElmt.children().iterator();
            while (valItr.hasNext()) {
              Object object2 = valItr.next();
              if (object2 instanceof XmlElement) {
                listOfValues.add(((XmlElement) object2).children().iterator().next().toString());
              }
            }
          }
        } else {
          throw new WorkFlowInterpreterException("Did not find inputs from WS to foreach");
        }
      }
    }
    return returnValForProvenance;
  }
  /**
   * @param inputPort
   * @param invokerMap
   * @return
   * @throws WorkflowException
   */
  public static Object findInputFromPort(DataPort inputPort, Map<Node, Invoker> invokerMap)
      throws WorkflowException {
    Object outputVal = null;
    Node fromNode = inputPort.getFromNode();
    if (fromNode instanceof InputNode) {
      outputVal = ((InputNode) fromNode).getDefaultValue();
    } else if (fromNode instanceof ConstantNode) {
      outputVal = ((ConstantNode) fromNode).getValue();
    } else if (fromNode instanceof DifferedInputNode
        && ((DifferedInputNode) fromNode).isConfigured()) {
      outputVal = ((DifferedInputNode) fromNode).getDefaultValue();
    } else if (fromNode instanceof EndifNode
        || fromNode instanceof DoWhileNode
        || fromNode instanceof EndDoWhileNode) {
      Invoker fromInvoker = invokerMap.get(fromNode);
      outputVal = fromInvoker.getOutput(inputPort.getFromPort().getID());
    } else if (fromNode instanceof InstanceNode) {
      return ((InstanceNode) fromNode).getOutputInstanceId();
    } else if (fromNode instanceof EndForEachNode) {
      outputVal = "";
      Invoker workflowInvoker = invokerMap.get(fromNode);
      String outputName = "";
      if (inputPort instanceof SystemDataPort) {
        outputName = ((SystemDataPort) inputPort).getWSComponentPort().getName();

      } else if (inputPort instanceof WSPort) {
        outputName =
            ((SystemDataPort)
                    fromNode.getInputPort(
                        fromNode.getOutputPorts().indexOf(inputPort.getEdge(0).getFromPort())))
                .getWSComponentPort()
                .getName();
      }
      XmlElement msgElmt =
          XmlConstants.BUILDER.parseFragmentFromString(
              "<temp>" + workflowInvoker.getOutput(outputName) + "</temp>");
      Iterator valItr = msgElmt.children().iterator();
      while (valItr.hasNext()) {
        Object object2 = valItr.next();
        if (object2 instanceof XmlElement) {

          if (((XmlElement) object2).children().iterator().hasNext()) {
            outputVal =
                outputVal
                    + StringUtil.DELIMETER
                    + StringUtil.quoteString(
                        ((XmlElement) object2).children().iterator().next().toString());
          }
        }
      }

      if (((String) outputVal).length() == 0) {
        throw new WorkflowException("Empty Output Generated");
      }
      outputVal = ((String) outputVal).substring(1, ((String) outputVal).length());
    } else {
      Invoker fromInvoker = invokerMap.get(fromNode);
      try {
        if (fromInvoker != null)
          outputVal = fromInvoker.getOutput(inputPort.getFromPort().getName());

      } catch (Exception e) {
        // if the value is still null look it up from the inputport name
        // because the value is set to the input port name at some point
        // there is no harm in doing this
        if (null == outputVal) {
          outputVal = fromInvoker.getOutput(inputPort.getName());
        }
      }
    }
    return outputVal;
  }
  public static Integer[] getNumberOfInputsForForEachNode(
      final ForEachNode forEachNode, Map<Node, Invoker> invokerMap) throws WorkflowException {
    List<DataPort> inputPorts = forEachNode.getInputPorts();
    Integer[] inputNumbers = new Integer[inputPorts.size()];
    for (DataPort forEachInputPort : inputPorts) {
      // if input node for for-each is WSNode
      Node forEachInputNode = forEachInputPort.getFromNode();
      int index = 0;
      Object returnValForProvenance = null;
      if (forEachInputNode instanceof InputNode) {
        returnValForProvenance = InterpreterUtil.findInputFromPort(forEachInputPort, invokerMap);
        if (null == returnValForProvenance) {
          throw new WorkFlowInterpreterException(
              "Unable to find input for the node:" + forEachNode.getID());
        }
        String[] vals = StringUtil.getElementsFromString(returnValForProvenance.toString());
        inputNumbers[inputPorts.indexOf(forEachInputPort)] = vals.length;
      } else {
        Invoker workflowInvoker = invokerMap.get(forEachInputNode);
        if (workflowInvoker != null) {
          if (workflowInvoker instanceof GenericInvoker) {

            returnValForProvenance = ((GenericInvoker) workflowInvoker).getOutputs();
            String message = returnValForProvenance.toString();

            XmlElement msgElmt = XmlConstants.BUILDER.parseFragmentFromString(message);
            Iterator children = msgElmt.children().iterator();
            while (children.hasNext()) {
              Object object = children.next();
              // foreachWSNode.getInputPort(0).getType()
              if (object instanceof XmlElement) {
                index++;
              }
            }
          } else if (workflowInvoker instanceof WorkflowInvokerWrapperForGFacInvoker) {
            String outputName = forEachInputNode.getOutputPort(0).getName();
            returnValForProvenance = workflowInvoker.getOutput(outputName);
            org.xmlpull.v1.builder.XmlElement msgElmt =
                (org.xmlpull.v1.builder.XmlElement) returnValForProvenance;
            Iterator children = msgElmt.children();
            while (children.hasNext()) {
              Object object = children.next();
              if (object instanceof org.xmlpull.v1.builder.XmlElement) {
                org.xmlpull.v1.builder.XmlElement child =
                    (org.xmlpull.v1.builder.XmlElement) object;
                Iterator valItr = child.children();
                if (valItr.hasNext()) {
                  Object object2 = valItr.next();
                  if (object2 instanceof String) {
                    index++;
                  }
                }
              }
            }
            inputNumbers[inputPorts.indexOf(forEachInputPort)] = index;
          } else if (workflowInvoker instanceof SystemComponentInvoker) {
            int portIndex =
                forEachInputNode
                    .getOutputPorts()
                    .indexOf(forEachInputPort.getEdge(0).getFromPort());
            String outputName = "";
            if (forEachInputNode.getInputPort(portIndex) instanceof SystemDataPort) {
              outputName =
                  ((SystemDataPort) forEachInputNode.getInputPort(portIndex))
                      .getWSComponentPort()
                      .getName();
            } else if (forEachInputNode.getInputPort(portIndex) instanceof WSPort) {
              outputName =
                  ((WSPort) forEachInputNode.getInputPort(portIndex)).getComponentPort().getName();
            }
            returnValForProvenance = workflowInvoker.getOutput(outputName);
            XmlElement msgElmt =
                XmlConstants.BUILDER.parseFragmentFromString(
                    "<temp>" + returnValForProvenance + "</temp>");
            Iterator valItr = msgElmt.children().iterator();
            while (valItr.hasNext()) {
              Object object2 = valItr.next();
              if (object2 instanceof XmlElement) {
                index++;
              }
            }
            inputNumbers[inputPorts.indexOf(forEachInputPort)] = index;
          }

        } else {
          throw new WorkFlowInterpreterException("Did not find inputs from WS to foreach");
        }
      }
    }
    return inputNumbers;
  }
  private void initSchema(File rootDir, File srcDir, File classesDir) {

    List<DataPort> inputPorts = node.getInputPorts();
    for (DataPort inPort : inputPorts) {
      Port fromPort = inPort.getFromPort();
      Node fromNode = inPort.getFromNode();
      if (fromNode instanceof WSNode) {
        WSNode fromWsNode = (WSNode) fromNode;
        if (null != fromPort && fromPort instanceof DataPort) {
          DataPort fromDataPort = (DataPort) fromPort;
          WsdlDefinitions wsdl =
              engine.getGUI().getWorkflow().getWSDLs().get(fromWsNode.getWSDLID());
          Iterator<XmlNamespace> itr = wsdl.xml().namespaces().iterator();
          try {
            XmlElement schema = wsdl.getTypes().element("schema").clone();
            // do not change the following ordering of setting
            // namespaces.
            schema.setNamespace(
                xsul5.XmlConstants.BUILDER.newNamespace("http://www.w3.org/2001/XMLSchema"));
            while (itr.hasNext()) {
              XmlNamespace next = itr.next();
              if (!"".equals(next.getPrefix()) && null != next.getPrefix()) {
                schema.setAttributeValue("xmlns:" + next.getPrefix(), next.getName());
              }
            }

            try {
              xsul5.XmlConstants.BUILDER.serializeToOutputStream(
                  schema,
                  new FileOutputStream(
                      rootDir.getCanonicalPath() + File.separatorChar + "types.xsd"));
            } catch (Exception e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
            }

            typesPath = rootDir.getCanonicalPath() + File.separatorChar + "mytype.jar";
            String[] args =
                new String[] {
                  "-d",
                  classesDir.getCanonicalPath(),
                  "-src",
                  srcDir.getCanonicalPath(),
                  "-out",
                  typesPath,
                  rootDir.getCanonicalPath() + File.separatorChar + "types.xsd"
                };
            SchemaCompilerUtil.compile(args);

          } catch (XmlBuilderException e) {
            this.engine.getGUI().getErrorWindow().error(e);
          } catch (CloneNotSupportedException e) {
            this.engine.getGUI().getErrorWindow().error(e);
          } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }

        } else {
          throw new WorkflowRuntimeException("Unknown port for code generation" + fromPort);
        }
      } else {
        throw new WorkflowRuntimeException("Unknown from node for code generation" + fromNode);
      }
    }
  }