// Path: app/src/main/java/io/github/mthli/type/event/FormatEvent.java
// public class FormatEvent {
//     private boolean isBold;
//     private boolean isItalic;
//     private boolean isUnderline;
//     private boolean isStrikethrough;
//     private boolean isLink;
// 
//     public FormatEvent() {}
// 
//     public FormatEvent(boolean isBold, boolean isItalic, boolean isUnderline, boolean isStrikethrough, boolean isLink) {
//         this.isBold = isBold;
//         this.isItalic = isItalic;
//         this.isUnderline = isUnderline;
//         this.isStrikethrough = isStrikethrough;
//         this.isLink = isLink;
//     }
// 
//     public boolean isBold() {
//         return isBold;
//     }
// 
//     public void setBold(boolean isBold) {
//         this.isBold = isBold;
//     }
// 
//     public boolean isItalic() {
//         return isItalic;
//     }
// 
//     public void setItalic(boolean isItalic) {
//         this.isItalic = isItalic;
//     }
// 
//     public boolean isUnderline() {
//         return isUnderline;
//     }
// 
//     public void setUnderline(boolean isUnderline) {
//         this.isUnderline = isUnderline;
//     }
// 
//     public boolean isStrikethrough() {
//         return isStrikethrough;
//     }
// 
//     public void setStrikethrough(boolean isStrikethrough) {
//         this.isStrikethrough = isStrikethrough;
//     }
// 
//     public boolean isLink() {
//         return isLink;
//     }
// 
//     public void setLink(boolean isLink) {
//         this.isLink = isLink;
//     }
// }
// 
// Path: app/src/main/java/io/github/mthli/type/util/RxBus.java
// public class RxBus {
//     private static final RxBus sRxBus = new RxBus();
// 
//     public static RxBus getInstance() {
//         return sRxBus;
//     }
// 
//     private Subject<Object, Object> mSubject = new SerializedSubject<>(PublishSubject.create());
// 
//     private RxBus() {}
// 
//     public void post(Object object) {
//         mSubject.onNext(object);
//     }
// 
//     public <T> Observable<T> toObservable(Class<T> eventType) {
//         return mSubject.ofType(eventType);
//     }
// 
//     public boolean hasObservers() {
//         return mSubject.hasObservers();
//     }
// }


import io.github.mthli.type.util.RxBus;
import android.content.Context;
import android.graphics.Typeface;
import android.support.annotation.IntDef;
import android.support.v7.widget.AppCompatEditText;
import android.text.Spanned;
import android.text.style.StrikethroughSpan;
import android.text.style.StyleSpan;
import android.text.style.UnderlineSpan;
import android.util.AttributeSet;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
import io.github.mthli.type.event.FormatEvent;
            if (span.getStyle() == style) {
                list.add(new KnifePart(getEditableText().getSpanStart(span), getEditableText().getSpanEnd(span)));
                getEditableText().removeSpan(span);
            }
        }

        for (KnifePart part : list) {
            if (part.isValid()) {
                if (part.getStart() < start) {
                    styleValid(style, part.getStart(), start);
                }

                if (part.getEnd() > end) {
                    styleValid(style, end, part.getEnd());
                }
            }
        }
    }

    private boolean containStyle(int style, int start, int end) {
        switch (style) {
            case Typeface.NORMAL:
            case Typeface.BOLD:
            case Typeface.ITALIC:
            case Typeface.BOLD_ITALIC:
                break;
            default:
                return false;
        }

// Path: app/src/main/java/io/github/mthli/type/event/FormatEvent.java
// public class FormatEvent {
//     private boolean isBold;
//     private boolean isItalic;
//     private boolean isUnderline;
//     private boolean isStrikethrough;
//     private boolean isLink;
// 
//     public FormatEvent() {}
// 
//     public FormatEvent(boolean isBold, boolean isItalic, boolean isUnderline, boolean isStrikethrough, boolean isLink) {
//         this.isBold = isBold;
//         this.isItalic = isItalic;
//         this.isUnderline = isUnderline;
//         this.isStrikethrough = isStrikethrough;
//         this.isLink = isLink;
//     }
// 
//     public boolean isBold() {
//         return isBold;
//     }
// 
//     public void setBold(boolean isBold) {
//         this.isBold = isBold;
//     }
// 
//     public boolean isItalic() {
//         return isItalic;
//     }
// 
//     public void setItalic(boolean isItalic) {
//         this.isItalic = isItalic;
//     }
// 
//     public boolean isUnderline() {
//         return isUnderline;
//     }
// 
//     public void setUnderline(boolean isUnderline) {
//         this.isUnderline = isUnderline;
//     }
// 
//     public boolean isStrikethrough() {
//         return isStrikethrough;
//     }
// 
//     public void setStrikethrough(boolean isStrikethrough) {
//         this.isStrikethrough = isStrikethrough;
//     }
// 
//     public boolean isLink() {
//         return isLink;
//     }
// 
//     public void setLink(boolean isLink) {
//         this.isLink = isLink;
//     }
// }
// 
// Path: app/src/main/java/io/github/mthli/type/util/RxBus.java
// public class RxBus {
//     private static final RxBus sRxBus = new RxBus();
// 
//     public static RxBus getInstance() {
//         return sRxBus;
//     }
// 
//     private Subject<Object, Object> mSubject = new SerializedSubject<>(PublishSubject.create());
// 
//     private RxBus() {}
// 
//     public void post(Object object) {
//         mSubject.onNext(object);
//     }
// 
//     public <T> Observable<T> toObservable(Class<T> eventType) {
//         return mSubject.ofType(eventType);
//     }
// 
//     public boolean hasObservers() {
//         return mSubject.hasObservers();
//     }
// }


// Path: app/src/main/java/io/github/mthli/type/widget/text/KnifeText.java
import io.github.mthli.type.util.RxBus;
import android.content.Context;
import android.graphics.Typeface;
import android.support.annotation.IntDef;
import android.support.v7.widget.AppCompatEditText;
import android.text.Spanned;
import android.text.style.StrikethroughSpan;
import android.text.style.StyleSpan;
import android.text.style.UnderlineSpan;
import android.util.AttributeSet;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
import io.github.mthli.type.event.FormatEvent;

            if (span.getStyle() == style) {
                list.add(new KnifePart(getEditableText().getSpanStart(span), getEditableText().getSpanEnd(span)));
                getEditableText().removeSpan(span);
            }
        }

        for (KnifePart part : list) {
            if (part.isValid()) {
                if (part.getStart() < start) {
                    styleValid(style, part.getStart(), start);
                }

                if (part.getEnd() > end) {
                    styleValid(style, end, part.getEnd());
                }
            }
        }
    }

    private boolean containStyle(int style, int start, int end) {
        switch (style) {
            case Typeface.NORMAL:
            case Typeface.BOLD:
            case Typeface.ITALIC:
            case Typeface.BOLD_ITALIC:
                break;
            default:
                return false;
        }

        if (start > end) {