// 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);
//     }
//   }
// }


import com.intellij.lang.ASTNode;
import com.intellij.lang.folding.FoldingBuilder;
import com.intellij.lang.folding.FoldingDescriptor;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import tk.skuro.idea.orgmode.parser.OrgTokenTypes;
import java.util.*;
package tk.skuro.idea.orgmode.editor.folding;



/**
 * Enables blocks folding in org files, e.g. for code blocks, drawers, etc.
 *
 * @author Carlo Sciolla
 * @since 0.3.0
 */
public class OrgFoldingBuilder implements FoldingBuilder {

    private final static Set<IElementType> BLOCK_ELEMENTS = new HashSet<IElementType>(Arrays.asList(
// 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/editor/folding/OrgFoldingBuilder.java
import com.intellij.lang.ASTNode;
import com.intellij.lang.folding.FoldingBuilder;
import com.intellij.lang.folding.FoldingDescriptor;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import tk.skuro.idea.orgmode.parser.OrgTokenTypes;
import java.util.*;

package tk.skuro.idea.orgmode.editor.folding;



/**
 * Enables blocks folding in org files, e.g. for code blocks, drawers, etc.
 *
 * @author Carlo Sciolla
 * @since 0.3.0
 */
public class OrgFoldingBuilder implements FoldingBuilder {

    private final static Set<IElementType> BLOCK_ELEMENTS = new HashSet<IElementType>(Arrays.asList(
            OrgTokenTypes.BLOCK,