// Path: moshas/src/main/java/net/unit8/moshas/helper/Validate.java
// public class Validate {
//     
//     private Validate() {}
// 
//     /**
//      * Validates that the object is not null
//      * @param obj object to test
//      */
//     public static void notNull(Object obj) {
//         if (obj == null)
//             throw new IllegalArgumentException("Object must not be null");
//     }
// 
//     /**
//      * Validates that the object is not null
//      * @param obj object to test
//      * @param msg message to output if validation fails
//      */
//     public static void notNull(Object obj, String msg) {
//         if (obj == null)
//             throw new IllegalArgumentException(msg);
//     }
// 
//     /**
//      * Validates that the value is true
//      * @param val object to test
//      */
//     public static void isTrue(boolean val) {
//         if (!val)
//             throw new IllegalArgumentException("Must be true");
//     }
// 
//     /**
//      * Validates that the value is true
//      * @param val object to test
//      * @param msg message to output if validation fails
//      */
//     public static void isTrue(boolean val, String msg) {
//         if (!val)
//             throw new IllegalArgumentException(msg);
//     }
// 
//     /**
//      * Validates that the value is false
//      * @param val object to test
//      */
//     public static void isFalse(boolean val) {
//         if (val)
//             throw new IllegalArgumentException("Must be false");
//     }
// 
//     /**
//      * Validates that the value is false
//      * @param val object to test
//      * @param msg message to output if validation fails
//      */
//     public static void isFalse(boolean val, String msg) {
//         if (val)
//             throw new IllegalArgumentException(msg);
//     }
// 
//     /**
//      * Validates that the array contains no null elements
//      * @param objects the array to test
//      */
//     public static void noNullElements(Object[] objects) {
//         noNullElements(objects, "Array must not contain any null objects");
//     }
// 
//     /**
//      * Validates that the array contains no null elements
//      * @param objects the array to test
//      * @param msg message to output if validation fails
//      */
//     public static void noNullElements(Object[] objects, String msg) {
//         for (Object obj : objects)
//             if (obj == null)
//                 throw new IllegalArgumentException(msg);
//     }
// 
//     /**
//      * Validates that the string is not empty
//      * @param string the string to test
//      */
//     public static void notEmpty(String string) {
//         if (string == null || string.length() == 0)
//             throw new IllegalArgumentException("String must not be empty");
//     }
// 
//     /**
//      * Validates that the string is not empty
//      * @param string the string to test
//      * @param msg message to output if validation fails
//      */
//     public static void notEmpty(String string, String msg) {
//         if (string == null || string.length() == 0)
//             throw new IllegalArgumentException(msg);
//     }
// 
//     /**
//      Cause a failure.
//      @param msg message to output.
//      */
//     public static void fail(String msg) {
//         throw new IllegalArgumentException(msg);
//     }    
// }


import net.unit8.moshas.helper.Validate;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
package net.unit8.moshas.parser;



/**
 *
 * @author kawasima
 */
public class Tag implements Serializable {
    private static final Map<String, Tag> tags = new HashMap<>(); // map of known tags

    private String tagName;
    private boolean isBlock = true; // block or inline
    private boolean formatAsBlock = true; // should be formatted as a block
    private boolean canContainBlock = true; // Can this tag hold block level tags?
    private boolean canContainInline = true; // only pcdata if not
    private boolean empty = false; // can hold nothing; e.g. img
    private boolean selfClosing = false; // can self close (<foo />). used for unknown tags that self close, without forcing them as empty.
    private boolean preserveWhitespace = false; // for pre, textarea, script etc
    private boolean formList = false; // a control that appears in forms: input, textarea, output etc
    private boolean formSubmit = false; // a control that can be submitted in a form: input etc

    private Tag(String tagName) {
        this.tagName = tagName.toLowerCase();
    }

    /**
     * Get this tag's name.
     *
     * @return the tag's name
     */
    public String getName() {
        return tagName;
    }

    /**
     * Get a Tag by name. If not previously defined (unknown), returns a new generic tag, that can do anything.
     * <p>
     * Pre-defined tags (P, DIV etc) will be ==, but unknown tags are not registered and will only .equals().
     * </p>
     *
     * @param tagName Name of tag, e.g. "p". Case insensitive.
     * @return The tag, either defined or new generic.
     */
    public static Tag valueOf(String tagName) {
        Validate.notNull(tagName);
        Tag tag = tags.get(tagName);

        if (tag == null) {
            tagName = tagName.trim().toLowerCase();
// Path: moshas/src/main/java/net/unit8/moshas/helper/Validate.java
// public class Validate {
//     
//     private Validate() {}
// 
//     /**
//      * Validates that the object is not null
//      * @param obj object to test
//      */
//     public static void notNull(Object obj) {
//         if (obj == null)
//             throw new IllegalArgumentException("Object must not be null");
//     }
// 
//     /**
//      * Validates that the object is not null
//      * @param obj object to test
//      * @param msg message to output if validation fails
//      */
//     public static void notNull(Object obj, String msg) {
//         if (obj == null)
//             throw new IllegalArgumentException(msg);
//     }
// 
//     /**
//      * Validates that the value is true
//      * @param val object to test
//      */
//     public static void isTrue(boolean val) {
//         if (!val)
//             throw new IllegalArgumentException("Must be true");
//     }
// 
//     /**
//      * Validates that the value is true
//      * @param val object to test
//      * @param msg message to output if validation fails
//      */
//     public static void isTrue(boolean val, String msg) {
//         if (!val)
//             throw new IllegalArgumentException(msg);
//     }
// 
//     /**
//      * Validates that the value is false
//      * @param val object to test
//      */
//     public static void isFalse(boolean val) {
//         if (val)
//             throw new IllegalArgumentException("Must be false");
//     }
// 
//     /**
//      * Validates that the value is false
//      * @param val object to test
//      * @param msg message to output if validation fails
//      */
//     public static void isFalse(boolean val, String msg) {
//         if (val)
//             throw new IllegalArgumentException(msg);
//     }
// 
//     /**
//      * Validates that the array contains no null elements
//      * @param objects the array to test
//      */
//     public static void noNullElements(Object[] objects) {
//         noNullElements(objects, "Array must not contain any null objects");
//     }
// 
//     /**
//      * Validates that the array contains no null elements
//      * @param objects the array to test
//      * @param msg message to output if validation fails
//      */
//     public static void noNullElements(Object[] objects, String msg) {
//         for (Object obj : objects)
//             if (obj == null)
//                 throw new IllegalArgumentException(msg);
//     }
// 
//     /**
//      * Validates that the string is not empty
//      * @param string the string to test
//      */
//     public static void notEmpty(String string) {
//         if (string == null || string.length() == 0)
//             throw new IllegalArgumentException("String must not be empty");
//     }
// 
//     /**
//      * Validates that the string is not empty
//      * @param string the string to test
//      * @param msg message to output if validation fails
//      */
//     public static void notEmpty(String string, String msg) {
//         if (string == null || string.length() == 0)
//             throw new IllegalArgumentException(msg);
//     }
// 
//     /**
//      Cause a failure.
//      @param msg message to output.
//      */
//     public static void fail(String msg) {
//         throw new IllegalArgumentException(msg);
//     }    
// }


// Path: moshas/src/main/java/net/unit8/moshas/parser/Tag.java
import net.unit8.moshas.helper.Validate;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

package net.unit8.moshas.parser;



/**
 *
 * @author kawasima
 */
public class Tag implements Serializable {
    private static final Map<String, Tag> tags = new HashMap<>(); // map of known tags

    private String tagName;
    private boolean isBlock = true; // block or inline
    private boolean formatAsBlock = true; // should be formatted as a block
    private boolean canContainBlock = true; // Can this tag hold block level tags?
    private boolean canContainInline = true; // only pcdata if not
    private boolean empty = false; // can hold nothing; e.g. img
    private boolean selfClosing = false; // can self close (<foo />). used for unknown tags that self close, without forcing them as empty.
    private boolean preserveWhitespace = false; // for pre, textarea, script etc
    private boolean formList = false; // a control that appears in forms: input, textarea, output etc
    private boolean formSubmit = false; // a control that can be submitted in a form: input etc

    private Tag(String tagName) {
        this.tagName = tagName.toLowerCase();
    }

    /**
     * Get this tag's name.
     *
     * @return the tag's name
     */
    public String getName() {
        return tagName;
    }

    /**
     * Get a Tag by name. If not previously defined (unknown), returns a new generic tag, that can do anything.
     * <p>
     * Pre-defined tags (P, DIV etc) will be ==, but unknown tags are not registered and will only .equals().
     * </p>
     *
     * @param tagName Name of tag, e.g. "p". Case insensitive.
     * @return The tag, either defined or new generic.
     */
    public static Tag valueOf(String tagName) {
        Validate.notNull(tagName);
        Tag tag = tags.get(tagName);

        if (tag == null) {
            tagName = tagName.trim().toLowerCase();
            Validate.notEmpty(tagName);