// Path: src/main/java/tk/skuro/idea/orgmode/parser/OrgTokenTypes.java
// public interface OrgTokenTypes {
// 
//   IElementType BLOCK = new OrgTokenType("BLOCK");
//   IElementType DRAWER = new OrgTokenType("DRAWER");
//   IElementType OUTLINE_BLOCK = new OrgTokenType("OUTLINE_BLOCK");
//   IElementType TEXT_ELEMENT = new OrgTokenType("TEXT_ELEMENT");
// 
//   IElementType BLOCK_CONTENT = new OrgElementType("BLOCK_CONTENT");
//   IElementType BLOCK_END = new OrgElementType("BLOCK_END");
//   IElementType BLOCK_START = new OrgElementType("BLOCK_START");
//   IElementType BOLD = new OrgElementType("BOLD");
//   IElementType CODE = new OrgElementType("CODE");
//   IElementType COMMENT = new OrgElementType("COMMENT");
//   IElementType CRLF = new OrgElementType("CRLF");
//   IElementType DRAWER_CONTENT = new OrgElementType("DRAWER_CONTENT");
//   IElementType DRAWER_DELIMITER = new OrgElementType("DRAWER_DELIMITER");
//   IElementType KEYWORD = new OrgElementType("KEYWORD");
//   IElementType OUTLINE = new OrgElementType("OUTLINE");
//   IElementType PROPERTIES = new OrgElementType("PROPERTIES");
//   IElementType TEXT = new OrgElementType("TEXT");
//   IElementType UNDERLINE = new OrgElementType("UNDERLINE");
//   IElementType UNMATCHED_DELIMITER = new OrgElementType("UNMATCHED_DELIMITER");
//   IElementType WHITE_SPACE = new OrgElementType("WHITE_SPACE");
// 
//   class Factory {
//     public static PsiElement createElement(ASTNode node) {
//       IElementType type = node.getElementType();
//        if (type == BLOCK) {
//         return new OrgBlockImpl(node);
//       }
//       else if (type == DRAWER) {
//         return new OrgDrawerImpl(node);
//       }
//       else if (type == OUTLINE_BLOCK) {
//         return new OrgOutlineBlockImpl(node);
//       }
//       else if (type == TEXT_ELEMENT) {
//         return new OrgTextElementImpl(node);
//       }
//       throw new AssertionError("Unknown element type: " + type);
//     }
//   }
// }
// 
// Path: src/main/java/tk/skuro/idea/orgmode/psi/OrgPsiElementImpl.java
// public class OrgPsiElementImpl extends ASTWrapperPsiElement {
//     public OrgPsiElementImpl(@org.jetbrains.annotations.NotNull ASTNode astNode) {
//         super(astNode);
//     }
// }


import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.CaretModel;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import tk.skuro.idea.orgmode.parser.OrgTokenTypes;
import tk.skuro.idea.orgmode.psi.OrgPsiElementImpl;
        }

        return candidate;
    }

    private PsiElement findNextOutline(PsiElement element) {
        PsiElement candidate = findRootLevel(element);
        while(candidate != null && !isOutlineBlock(candidate)) {
            candidate = candidate.getNextSibling();
        }

        return candidate;
    }

    private int outlineDepth(final PsiElement element) {
        if(isOutlineBlock(element)) {
            return element.getText().split("\\s")[0].length();
        }

        final PsiElement previousOutline = findPreviousOutline(element);
        return previousOutline == null?  0 : outlineDepth(previousOutline);
    }

    private String createOutlineSameDepthAs(PsiElement currentOutline) {
        return currentOutline.getText().split("\\s")[0] + " ";
    }

    private PsiElement findPreviousOutline(PsiElement element) {
        PsiElement candidate = findRootLevel(element);
        while (candidate != null &&
// Path: src/main/java/tk/skuro/idea/orgmode/parser/OrgTokenTypes.java
// public interface OrgTokenTypes {
// 
//   IElementType BLOCK = new OrgTokenType("BLOCK");
//   IElementType DRAWER = new OrgTokenType("DRAWER");
//   IElementType OUTLINE_BLOCK = new OrgTokenType("OUTLINE_BLOCK");
//   IElementType TEXT_ELEMENT = new OrgTokenType("TEXT_ELEMENT");
// 
//   IElementType BLOCK_CONTENT = new OrgElementType("BLOCK_CONTENT");
//   IElementType BLOCK_END = new OrgElementType("BLOCK_END");
//   IElementType BLOCK_START = new OrgElementType("BLOCK_START");
//   IElementType BOLD = new OrgElementType("BOLD");
//   IElementType CODE = new OrgElementType("CODE");
//   IElementType COMMENT = new OrgElementType("COMMENT");
//   IElementType CRLF = new OrgElementType("CRLF");
//   IElementType DRAWER_CONTENT = new OrgElementType("DRAWER_CONTENT");
//   IElementType DRAWER_DELIMITER = new OrgElementType("DRAWER_DELIMITER");
//   IElementType KEYWORD = new OrgElementType("KEYWORD");
//   IElementType OUTLINE = new OrgElementType("OUTLINE");
//   IElementType PROPERTIES = new OrgElementType("PROPERTIES");
//   IElementType TEXT = new OrgElementType("TEXT");
//   IElementType UNDERLINE = new OrgElementType("UNDERLINE");
//   IElementType UNMATCHED_DELIMITER = new OrgElementType("UNMATCHED_DELIMITER");
//   IElementType WHITE_SPACE = new OrgElementType("WHITE_SPACE");
// 
//   class Factory {
//     public static PsiElement createElement(ASTNode node) {
//       IElementType type = node.getElementType();
//        if (type == BLOCK) {
//         return new OrgBlockImpl(node);
//       }
//       else if (type == DRAWER) {
//         return new OrgDrawerImpl(node);
//       }
//       else if (type == OUTLINE_BLOCK) {
//         return new OrgOutlineBlockImpl(node);
//       }
//       else if (type == TEXT_ELEMENT) {
//         return new OrgTextElementImpl(node);
//       }
//       throw new AssertionError("Unknown element type: " + type);
//     }
//   }
// }
// 
// Path: src/main/java/tk/skuro/idea/orgmode/psi/OrgPsiElementImpl.java
// public class OrgPsiElementImpl extends ASTWrapperPsiElement {
//     public OrgPsiElementImpl(@org.jetbrains.annotations.NotNull ASTNode astNode) {
//         super(astNode);
//     }
// }


// Path: src/main/java/tk/skuro/idea/orgmode/editor/actions/NewOutlineSameLevel.java
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.CaretModel;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import tk.skuro.idea.orgmode.parser.OrgTokenTypes;
import tk.skuro.idea.orgmode.psi.OrgPsiElementImpl;

        }

        return candidate;
    }

    private PsiElement findNextOutline(PsiElement element) {
        PsiElement candidate = findRootLevel(element);
        while(candidate != null && !isOutlineBlock(candidate)) {
            candidate = candidate.getNextSibling();
        }

        return candidate;
    }

    private int outlineDepth(final PsiElement element) {
        if(isOutlineBlock(element)) {
            return element.getText().split("\\s")[0].length();
        }

        final PsiElement previousOutline = findPreviousOutline(element);
        return previousOutline == null?  0 : outlineDepth(previousOutline);
    }

    private String createOutlineSameDepthAs(PsiElement currentOutline) {
        return currentOutline.getText().split("\\s")[0] + " ";
    }

    private PsiElement findPreviousOutline(PsiElement element) {
        PsiElement candidate = findRootLevel(element);
        while (candidate != null &&
                !candidate.getNode().getElementType().equals(OrgTokenTypes.OUTLINE_BLOCK)) {