/**
   * Calculates indent, based on code style, between parent block and child node
   *
   * @param parent parent block
   * @param child child node
   * @return indent
   */
  @NotNull
  public static Indent getChildIndent(
      @NotNull final GroovyBlock parent, @NotNull final ASTNode child) {
    ASTNode astNode = parent.getNode();
    final PsiElement psiParent = astNode.getPsi();

    // For Groovy file
    if (psiParent instanceof GroovyFileBase) {
      return Indent.getNoneIndent();
    }

    if (psiParent instanceof GrMethod && child.getPsi() instanceof GrParameterList) {
      return Indent.getContinuationIndent();
    }

    if (GSTRING_TOKENS_INNER.contains(child.getElementType())
        && mGSTRING_BEGIN != child.getElementType()) {
      return Indent.getAbsoluteNoneIndent();
    }

    if (psiParent instanceof GrListOrMap) {
      if (mLBRACK.equals(child.getElementType()) || mRBRACK.equals(child.getElementType())) {
        return Indent.getNoneIndent();
      } else {
        return Indent.getContinuationWithoutFirstIndent();
      }
    }

    // For common code block
    if (BLOCK_SET.contains(astNode.getElementType())
        && !BLOCK_STATEMENT.equals(astNode.getElementType())) {
      return indentForBlock(psiParent, child);
    }

    if (CASE_SECTION.equals(astNode.getElementType())) {
      return indentForCaseSection(child);
    }

    if (SWITCH_STATEMENT.equals(astNode.getElementType())) {
      return indentForSwitchStatement(psiParent, child);
    }

    if (psiParent instanceof GrLabeledStatement) {
      if (child.getPsi() instanceof GrLabel) {
        CommonCodeStyleSettings.IndentOptions indentOptions =
            parent.getSettings().getIndentOptions();
        if (indentOptions.LABEL_INDENT_ABSOLUTE) {
          return Indent.getAbsoluteLabelIndent();
        }
        return Indent.getLabelIndent();
      }
    }

    // for control structures
    if (psiParent instanceof GrControlStatement) {
      return getControlIndent(psiParent, child);
    }

    if (psiParent instanceof GrExpression) {
      return getExpressionIndent(psiParent, child);
    }
    if (psiParent instanceof GrVariable
        && child.getPsi() == ((GrVariable) psiParent).getInitializerGroovy()) {
      return Indent.getNormalIndent();
    }

    // For parameter lists
    if (psiParent instanceof GrParameterList
        || psiParent instanceof GrExtendsClause
        || psiParent instanceof GrThrowsClause) {
      if (parent.getIndent() != null) {
        return Indent.getContinuationWithoutFirstIndent();
      }
      return Indent.getNoneIndent();
    }

    // For arguments
    if (psiParent instanceof GrArgumentList) {
      if (child.getElementType() != mLPAREN
          && child.getElementType() != mRPAREN /*&& child.getElementType() != mCOMMA*/) {
        return Indent.getContinuationWithoutFirstIndent();
      }
    }

    if ((psiParent instanceof GrDocComment && child.getElementType() != mGDOC_COMMENT_START)
        || psiParent instanceof GrDocTag && child.getElementType() != mGDOC_TAG_NAME) {
      return Indent.getSpaceIndent(GDOC_COMMENT_INDENT);
    }

    if (psiParent instanceof GrNamedArgument
        && child.getPsi() == ((GrNamedArgument) psiParent).getExpression()) {
      return Indent.getContinuationIndent();
    }

    if (child.getPsi() instanceof GrVariable && psiParent instanceof GrVariableDeclaration) {
      return Indent.getContinuationWithoutFirstIndent();
    }

    return Indent.getNoneIndent();
  }
 private static Indent indentForSwitchStatement(PsiElement psiParent, ASTNode child) {
   if (CASE_SECTION.equals(child.getElementType())) {
     return getSwitchCaseIndent(psiParent);
   }
   return Indent.getNoneIndent();
 }