boolean (@NotNull Editor editor, @NotNull PsiFile file, @NotNull MoveInfo info, boolean down) { final Project project = file.getProject(); if (!HandlerUtils.canBeInvoked(editor, project) || !(file instanceof GroovyFileBase)) return false; LineRange range = getLineRangeFromSelection(editor); final Document document = editor.getDocument(); final int offset = document.getLineStartOffset(range.startLine); final GrLiteral literal = PsiTreeUtil.findElementOfClassAtOffset(file, offset, GrLiteral.class, false); if (literal != null && literal.textContains('\n')) return false; //multiline string final GroovyPsiElement pivot = getElementToMove((GroovyFileBase)file, offset); if (pivot == null) return false; final LineRange pivotRange = getLineRange(pivot); range = new LineRange(Math.min(range.startLine, pivotRange.startLine), Math.max(range.endLine, pivotRange.endLine)); final GroovyPsiElement scope = PsiTreeUtil.getParentOfType(pivot, GrMethod.class, GrTypeDefinitionBody.class, GroovyFileBase.class); final boolean stmtLevel = isStatement(pivot); boolean topLevel = pivot instanceof GrTypeDefinition && pivot.getParent() instanceof GroovyFileBase; final List<LineRange> allRanges = allRanges(scope, stmtLevel, topLevel); LineRange prev = null; LineRange next = null; for (LineRange each : allRanges) { if (each.endLine <= range.startLine) { prev = each; } if (each.containsLine(range.startLine)) { range = new LineRange(each.startLine, range.endLine); } if (each.startLine < range.endLine && each.endLine > range.endLine) { range = new LineRange(range.startLine, each.endLine); } if (each.startLine >= range.endLine && next == null) { next = each; } } info.toMove = range; info.toMove2 = down ? next : prev; return true; }