private ITypeBinding[] computeTypeVariables(ITypeBinding[] bindings) {
   Selection selection = getSelection();
   Set<ITypeBinding> result = new HashSet<>();
   // first remove all type variables that come from outside of the method
   // or are covered by the selection
   CompilationUnit compilationUnit = (CompilationUnit) fEnclosingBodyDeclaration.getRoot();
   for (int i = 0; i < bindings.length; i++) {
     ASTNode decl = compilationUnit.findDeclaringNode(bindings[i]);
     if (decl == null
         || (!selection.covers(decl) && decl.getParent() instanceof MethodDeclaration))
       result.add(bindings[i]);
   }
   // all all type variables which are needed since a local variable uses it
   for (int i = 0; i < fArguments.length; i++) {
     IVariableBinding arg = fArguments[i];
     ITypeBinding type = arg.getType();
     if (type != null && type.isTypeVariable()) {
       ASTNode decl = compilationUnit.findDeclaringNode(type);
       if (decl == null
           || (!selection.covers(decl) && decl.getParent() instanceof MethodDeclaration))
         result.add(type);
     }
   }
   return result.toArray(new ITypeBinding[result.size()]);
 }
 private IVariableBinding[] removeSelectedDeclarations(IVariableBinding[] bindings) {
   List<IVariableBinding> result = new ArrayList<>(bindings.length);
   Selection selection = getSelection();
   for (int i = 0; i < bindings.length; i++) {
     ASTNode decl =
         ((CompilationUnit) fEnclosingBodyDeclaration.getRoot()).findDeclaringNode(bindings[i]);
     if (!selection.covers(decl)) result.add(bindings[i]);
   }
   return result.toArray(new IVariableBinding[result.size()]);
 }