/**
  * Looks for the given type in the list of outputs and recurring all the children as well. Will
  * stop at first found and return it.
  *
  * @param outputs list of outputs, can be null or empty.
  * @param type the type to look for
  * @return the first found type, or <tt>null</tt> if not found
  */
 public static <T> T findFirstTypeInOutputs(List<ProcessorDefinition> outputs, Class<T> type) {
   List<T> found = new ArrayList<T>();
   doFindType(outputs, type, found);
   if (found.isEmpty()) {
     return null;
   }
   return found.iterator().next();
 }
  @SuppressWarnings({"unchecked", "rawtypes"})
  private static <T> void doFindType(
      List<ProcessorDefinition<?>> outputs, Class<T> type, List<T> found) {
    if (outputs == null || outputs.isEmpty()) {
      return;
    }

    for (ProcessorDefinition out : outputs) {
      if (type.isInstance(out)) {
        found.add((T) out);
      }

      // send is much common
      if (out instanceof SendDefinition) {
        SendDefinition send = (SendDefinition) out;
        List<ProcessorDefinition<?>> children = send.getOutputs();
        doFindType(children, type, found);
      }

      // special for choice
      if (out instanceof ChoiceDefinition) {
        ChoiceDefinition choice = (ChoiceDefinition) out;
        for (WhenDefinition when : choice.getWhenClauses()) {
          List<ProcessorDefinition<?>> children = when.getOutputs();
          doFindType(children, type, found);
        }

        // otherwise is optional
        if (choice.getOtherwise() != null) {
          List<ProcessorDefinition<?>> children = choice.getOtherwise().getOutputs();
          doFindType(children, type, found);
        }
      }

      // special for try ... catch ... finally
      if (out instanceof TryDefinition) {
        TryDefinition doTry = (TryDefinition) out;
        List<ProcessorDefinition<?>> doTryOut = doTry.getOutputsWithoutCatches();
        doFindType(doTryOut, type, found);

        List<CatchDefinition> doTryCatch = doTry.getCatchClauses();
        for (CatchDefinition doCatch : doTryCatch) {
          doFindType(doCatch.getOutputs(), type, found);
        }

        if (doTry.getFinallyClause() != null) {
          doFindType(doTry.getFinallyClause().getOutputs(), type, found);
        }

        // do not check children as we already did that
        continue;
      }

      // try children as well
      List<ProcessorDefinition<?>> children = out.getOutputs();
      doFindType(children, type, found);
    }
  }
  @SuppressWarnings("unchecked")
  private static <T> void doFindType(
      List<ProcessorDefinition> outputs, Class<T> type, List<T> found) {
    if (outputs == null || outputs.isEmpty()) {
      return;
    }

    for (ProcessorDefinition out : outputs) {
      if (type.isInstance(out)) {
        found.add((T) out);
      }

      // send is much common
      if (out instanceof SendDefinition) {
        SendDefinition send = (SendDefinition) out;
        List<ProcessorDefinition> children = send.getOutputs();
        doFindType(children, type, found);
      }

      // special for choice
      if (out instanceof ChoiceDefinition) {
        ChoiceDefinition choice = (ChoiceDefinition) out;
        for (WhenDefinition when : choice.getWhenClauses()) {
          List<ProcessorDefinition> children = when.getOutputs();
          doFindType(children, type, found);
        }

        // otherwise is optional
        if (choice.getOtherwise() != null) {
          List<ProcessorDefinition> children = choice.getOtherwise().getOutputs();
          doFindType(children, type, found);
        }
      }

      // try children as well
      List<ProcessorDefinition> children = out.getOutputs();
      doFindType(children, type, found);
    }
  }
 /**
  * Looks for the given type in the list of outputs and recurring all the children as well.
  *
  * @param outputs list of outputs, can be null or empty.
  * @param type the type to look for
  * @return the found definitions, or <tt>null</tt> if not found
  */
 public static <T> Iterator<T> filterTypeInOutputs(
     List<ProcessorDefinition> outputs, Class<T> type) {
   List<T> found = new ArrayList<T>();
   doFindType(outputs, type, found);
   return found.iterator();
 }