public List<PsiVariable> getInputVariables(
     final PsiElement codeFragment, PsiElement[] elements, PsiVariable[] outputVariables) {
   final List<PsiVariable> inputVariables =
       ControlFlowUtil.getInputVariables(myControlFlow, myFlowStart, myFlowEnd);
   List<PsiVariable> myInputVariables;
   if (skipVariablesFromExitStatements(outputVariables)) {
     List<PsiVariable> inputVariableList = new ArrayList<>(inputVariables);
     removeParametersUsedInExitsOnly(codeFragment, inputVariableList);
     myInputVariables = inputVariableList;
   } else {
     List<PsiVariable> inputVariableList = new ArrayList<>(inputVariables);
     for (Iterator<PsiVariable> iterator = inputVariableList.iterator(); iterator.hasNext(); ) {
       PsiVariable variable = iterator.next();
       for (PsiElement element : elements) {
         if (PsiTreeUtil.isAncestor(element, variable, false)) {
           iterator.remove();
           break;
         }
       }
     }
     myInputVariables = inputVariableList;
   }
   // varargs variables go last, otherwise order is induced by original ordering
   Collections.sort(
       myInputVariables,
       (v1, v2) -> {
         if (v1.getType() instanceof PsiEllipsisType) {
           return 1;
         }
         if (v2.getType() instanceof PsiEllipsisType) {
           return -1;
         }
         return v1.getTextOffset() - v2.getTextOffset();
       });
   return myInputVariables;
 }