Index: org/htmlcleaner/MathMLTagProvider.java
===================================================================
--- org/htmlcleaner/MathMLTagProvider.java	(revision 0)
+++ org/htmlcleaner/MathMLTagProvider.java	(revision 0)
@@ -0,0 +1,186 @@
+package org.htmlcleaner;
+
+import java.util.concurrent.ConcurrentMap;
+
+/**It contains the MathML tags to use with Html5 tags
+ * 
+ * @author User
+ *
+ */
+public class MathMLTagProvider {
+    
+    private static final String CLOSE_BEFORE_TAGS = "menclose,mpadded,mphantom,mfenced,mstyle,merror,msqrt,mroot,mtd,mtr,maligngroup,malignmark,mlabeledtr,ms,mi,mo,mn,mfrac,mrow,mtext,mspace,mglyph,p,details,summary,menuitem,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml";
+    
+    public MathMLTagProvider(TagInfo tagInfo,ConcurrentMap<String, TagInfo> tagInfoMap) {
+    	presentationMarkup(tagInfo,tagInfoMap);
+    }
+    
+   public void presentationMarkup(TagInfo tagInfo,ConcurrentMap<String, TagInfo> tagInfoMap){
+	   tokenElements(tagInfo,tagInfoMap);
+	   layoutElements(tagInfo,tagInfoMap);
+	   scriptElements(tagInfo,tagInfoMap);
+	   tableElements(tagInfo,tagInfoMap);
+	   
+	   tagInfo = new TagInfo("maction", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("maction", tagInfo,tagInfoMap);
+       
+   }
+   
+   
+   public void tokenElements(TagInfo tagInfo,ConcurrentMap<String, TagInfo> tagInfoMap){
+	   tagInfo = new TagInfo("mi", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("mi", tagInfo,tagInfoMap);
+	
+	   tagInfo = new TagInfo("mn", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("mn", tagInfo,tagInfoMap);
+	   
+	   tagInfo = new TagInfo("mo", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("mo", tagInfo,tagInfoMap);
+	   
+	   tagInfo = new TagInfo("mtext", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("mtext", tagInfo,tagInfoMap);
+	   
+	   tagInfo = new TagInfo("mspace", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.optional, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("mspace", tagInfo,tagInfoMap);
+	   
+	   tagInfo = new TagInfo("ms", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("ms", tagInfo,tagInfoMap);
+	   
+	   tagInfo = new TagInfo("mglyph", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.optional, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("mglyph", tagInfo,tagInfoMap);
+   }
+   
+   
+   public void layoutElements(TagInfo tagInfo,ConcurrentMap<String, TagInfo> tagInfoMap){
+	   
+	   tagInfo = new TagInfo("mrow", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("mrow", tagInfo,tagInfoMap);
+	   
+	   tagInfo = new TagInfo("mfrac", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("mfrac", tagInfo,tagInfoMap);
+	   
+	   tagInfo = new TagInfo("msqrt", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("msqrt", tagInfo,tagInfoMap);
+	   
+	   tagInfo = new TagInfo("mroot", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("mroot", tagInfo,tagInfoMap);
+	   
+	   tagInfo = new TagInfo("mstyle", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("mstyle", tagInfo,tagInfoMap);
+	   
+	   tagInfo = new TagInfo("merror", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("merror", tagInfo,tagInfoMap);
+	   
+	   tagInfo = new TagInfo("mpadded", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("mpadded", tagInfo,tagInfoMap);
+	   
+	   tagInfo = new TagInfo("mphantom", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("mphantom", tagInfo,tagInfoMap);
+	   
+	   tagInfo = new TagInfo("mfenced", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("mfenced", tagInfo,tagInfoMap);
+	   
+	   tagInfo = new TagInfo("menclose", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("menclose", tagInfo,tagInfoMap);
+	   
+   }
+    
+    
+   public void scriptElements(TagInfo tagInfo,ConcurrentMap<String, TagInfo> tagInfoMap){
+	   tagInfo = new TagInfo("msub", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("msub", tagInfo,tagInfoMap); 
+	   
+	   tagInfo = new TagInfo("msup", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("msup", tagInfo,tagInfoMap); 
+	   
+	   tagInfo = new TagInfo("msubsup", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("msubsup", tagInfo,tagInfoMap);
+	   
+	   tagInfo = new TagInfo("munder", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("munder", tagInfo,tagInfoMap);
+	   
+	   tagInfo = new TagInfo("mover", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("mover", tagInfo,tagInfoMap); 
+	   
+	   tagInfo = new TagInfo("munderover", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("munderover", tagInfo,tagInfoMap); 
+	   
+	   tagInfo = new TagInfo("mmultiscripts", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("mmultiscripts", tagInfo,tagInfoMap); 
+	   
+   }
+   
+   public void tableElements(TagInfo tagInfo,ConcurrentMap<String, TagInfo> tagInfoMap){
+	   tagInfo = new TagInfo("mtable", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   tagInfo.defineAllowedChildrenTags("mtr,mtd,mo,mn,mlabeledtr");
+	   this.put("mtable", tagInfo,tagInfoMap); 
+	   
+	   tagInfo = new TagInfo("mlabeledtr", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   tagInfo.defineRequiredEnclosingTags("mtable");
+	   tagInfo.defineFatalTags("mtable");
+	   this.put("mlabeledtr", tagInfo,tagInfoMap);
+	   
+	   tagInfo = new TagInfo("mtr", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   tagInfo.defineAllowedChildrenTags("mtd,mlabeledtr");
+	   tagInfo.defineRequiredEnclosingTags("body");
+	   tagInfo.defineFatalTags("mtable");
+	   this.put("mtr", tagInfo,tagInfoMap);
+	   
+	   tagInfo = new TagInfo("mtd", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   tagInfo.defineRequiredEnclosingTags("mtr");
+	   tagInfo.defineFatalTags("mtable");
+	   this.put("mtd", tagInfo,tagInfoMap);
+	   
+	   tagInfo = new TagInfo("maligngroup", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("maligngroup", tagInfo,tagInfoMap);
+	   
+	   tagInfo = new TagInfo("malignmark", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+	   tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+	   this.put("malignmark", tagInfo,tagInfoMap);
+	   
+   }
+   
+   
+    protected void put(String tagName, TagInfo tagInfo,ConcurrentMap<String, TagInfo> tagInfoMap) {
+        tagInfoMap.put(tagName, tagInfo);
+    }
+
+    public TagInfo getTagInfo(String tagName,ConcurrentMap<String, TagInfo> tagInfoMap) {
+        if ( tagName == null) {
+            return null;
+        } else {
+            return tagInfoMap.get(tagName);
+        }
+    }
+    
+}
Index: org/htmlcleaner/HtmlCleaner.java
===================================================================
--- org/htmlcleaner/HtmlCleaner.java	(revision 389)
+++ org/htmlcleaner/HtmlCleaner.java	(working copy)
@@ -100,12 +100,24 @@
  */
 public class HtmlCleaner {
 
+	
     /**
      * Marker attribute added to aid with part of the cleaning process.
      * TODO: a non-intrusive way of doing this that does not involve modifying the source html
      */
     private static final String MARKER_ATTRIBUTE = "htmlcleaner_marker";
     
+    public static int HTML_4=4;
+    public static int HTML_5=5;
+    
+    
+    /**
+     * Default html version is HTML5. If user wants html 4 it must be specified in terminal
+     * with argument htmlver=4.
+     */
+    public static int defaulthtml=HTML_5;
+ 
+    
     /**
      * Contains information about single open tag
      */
@@ -295,9 +307,14 @@
     private CleanerProperties properties;
 
     private CleanerTransformations transformations;
-
+    
+    /**
+     * Constructor - creates cleaner instance with default tag info provider,default html version 5
+     *  and default properties.
+     */
+   
     /**
-     * Constructor - creates cleaner instance with default tag info provider and default properties.
+     * Constructor - creates cleaner instance with default tag info provider,default version and default properties.
      */
     public HtmlCleaner() {
         this(null, null);
@@ -310,6 +327,8 @@
     public HtmlCleaner(ITagInfoProvider tagInfoProvider) {
         this(tagInfoProvider, null);
     }
+    
+    
 
     /**
      * Constructor - creates the instance with default tag info provider and specified properties
@@ -318,6 +337,8 @@
     public HtmlCleaner(CleanerProperties properties) {
         this(null, properties);
     }
+    
+   
 
     /**
 	 * Constructor - creates the instance with specified tag info provider and specified properties
@@ -325,19 +346,22 @@
 	 * @param properties Properties used during parsing and serializing
 	 */
 	public HtmlCleaner(ITagInfoProvider tagInfoProvider, CleanerProperties properties) {
-        this.properties = properties == null ? new CleanerProperties() : properties;
-        //
-        // If the given tagInfoProvider is null, then we set it to the default
-        // UNLESS the TagInfoProvider has already been set in cleanerProperties.
-        // in which case we leave properties as they are.
-        //
-        if (tagInfoProvider == null && this.properties.getTagInfoProvider() == null){
-        	 this.properties.setTagInfoProvider(DefaultTagProvider.INSTANCE);
-        } else {
-        	if (tagInfoProvider != null){
-        	   this.properties.setTagInfoProvider(tagInfoProvider == null ? DefaultTagProvider.INSTANCE : tagInfoProvider);
-        	}
-        }
+		 this.properties = properties == null ? new CleanerProperties() : properties;
+	        //
+	        // If the given tagInfoProvider is null, then we set it to the default
+	        // UNLESS the TagInfoProvider has already been set in cleanerProperties.
+	        // in which case we leave properties as they are.
+	        //
+	        if (tagInfoProvider == null && this.properties.getTagInfoProvider() == null){
+	        	if (defaulthtml==HTML_4)
+	        		this.properties.setTagInfoProvider(Html4TagProvider.INSTANCE);
+	        	else
+	        		this.properties.setTagInfoProvider(Html5TagProvider.INSTANCE);
+	        } else {
+	        	if (tagInfoProvider != null){
+	        	   this.properties.setTagInfoProvider(tagInfoProvider == null ? Html4TagProvider.INSTANCE : tagInfoProvider);
+	        	}
+	        }
 	}
 
     public TagNode clean(String htmlContent) {
@@ -636,7 +660,7 @@
         TagPos rubbishPos = getOpenTags(cleanTimeValues).findTagToPlaceRubbish();
         if (rubbishPos != null) {
     		TagNode startTagToken = (TagNode) nodeList.get(rubbishPos.position);
-			startTagToken.addItemForMoving(tokenToAdd);
+            startTagToken.addItemForMoving(tokenToAdd);
         }
     }
 
@@ -699,10 +723,10 @@
                     	// Get the open start tag. If it contained an xmlns, then we remove it from the current namespace stack
                     	//
                         if (closed.size()>0){
-                    	  TagNode startingTag = (TagNode) closed.get(0);
-                    	  if (startingTag.hasAttribute("xmlns")){
-                    		  cleanTimeValues.namespace.pop();
-                    	  }
+                      	  TagNode startingTag = (TagNode) closed.get(0);
+                      	  if (startingTag.hasAttribute("xmlns")){
+                      		  cleanTimeValues.namespace.pop();
+                      	  }
                         }
                     	
                         nodeIterator.set(null);
@@ -844,7 +868,7 @@
 					nodeIterator.set(null);
                 // unknown HTML tag and unknown tags are not allowed
 				// unless we have set the namespace-aware option, and the current NS is valid
-                } else if ( tag == null && properties.isOmitUnknownTags() && !isAllowedAsForeignMarkup(tagName, cleanTimeValues)) {
+                }else if ( tag == null && properties.isOmitUnknownTags() && !isAllowedAsForeignMarkup(tagName, cleanTimeValues)) {
                     nodeIterator.set(null);
                     properties.fireUglyHtml(true, startTagToken, ErrorType.Unknown);
                 } else if ( tag != null && tag.isDeprecated() && properties.isOmitDeprecatedTags()) {
@@ -1062,7 +1086,7 @@
 	private List<TagNode> closeSnippet(List nodeList, TagPos tagPos, Object toNode, CleanTimeValues cleanTimeValues) {
 		List<TagNode> closed = new ArrayList<TagNode>();
 		ListIterator it = nodeList.listIterator(tagPos.position);
-
+		
 		TagNode tagNode = null;
 		Object item = it.next();
 		boolean isListEnd = false;
Index: org/htmlcleaner/CommandLine.java
===================================================================
--- org/htmlcleaner/CommandLine.java	(revision 389)
+++ org/htmlcleaner/CommandLine.java	(working copy)
@@ -43,6 +43,7 @@
 import java.io.FileOutputStream;
 import java.net.URL;
 import java.util.Map;
+import java.util.Scanner;
 import java.util.TreeMap;
 import java.util.logging.Logger;
 
@@ -104,9 +105,19 @@
 
     public static void main(String[] args) throws IOException, XPatherException {
         String source = getArgValue(args, "src", "");
+        Scanner scan = new Scanner(System.in);
+        String s = "";
+        
         if ( "".equals(source) ) {
-            System.err.println("Usage: java -jar htmlcleanerXX.jar src=<url | file> [incharset=<charset>] " +
+        	 while (scan.hasNext()) {
+                 s += scan.nextLine();
+             }
+             if (s.compareTo("") != 0) {
+                 System.err.println("Output:");
+             } else {
+            System.err.println("Usage: java -jar htmlcleanerXX.jar src=<url | file> [htmlver=4] [incharset=<charset>] " +
                                "[dest=<file>] [outcharset=<charset>] [taginfofile=<file>] [options...]");
+            System.err.println("Alternative: java -jar htmlcleanerXX.jar (reads the input from console)");
             System.err.println("");
             System.err.println("where options include:");
             System.err.println("    outputtype=simple* | compact | browser-compact | pretty");
@@ -134,6 +145,7 @@
             System.err.println("    t:<sourcetagX>[=<desttag>[,<preserveatts>]]");
             System.err.println("    t:<sourcetagX>.<destattrY>[=<template>]");
             System.exit(1);
+             }
         }
 
         String inCharset = getArgValue(args, "incharset", "");
@@ -146,6 +158,7 @@
             outCharset = CleanerProperties.DEFAULT_CHARSET;
         }
 
+        String htmlversion = getArgValue(args, "htmlver", "");
         String destination = getArgValue(args, "dest", "");
         String outputType = getArgValue(args, "outputtype", "");
         String advancedXmlEscape = getArgValue(args, "advancedxmlescape", "");
@@ -172,6 +185,12 @@
 
         HtmlCleaner cleaner;
 
+        int defhtmlver=HtmlCleaner.HTML_5; //Default html version is 5
+      //If the user specifies HTML version 4 for parsing
+        if (htmlversion.compareTo("4")==0){
+        	defhtmlver=HtmlCleaner.HTML_4;
+        }
+        	
         String tagInfoFile = getArgValue(args, "taginfofile", "");
         if ( !"".equals(tagInfoFile) ) {
             cleaner = new HtmlCleaner(new ConfigFileTagProvider(new File(tagInfoFile)));
@@ -268,6 +287,8 @@
             props.setBooleanAttributeValues(booleanAtts);
         }
 
+        
+        	
         // collect transformation info
         Map transInfos = new TreeMap();
         for (String arg2 : args) {
@@ -287,10 +308,13 @@
         TagNode node;
 
         String src = source.toLowerCase();
-        if ( src.startsWith("http://") || src.startsWith("https://") ) {
+        
+        if (src.startsWith("http://") || src.startsWith("https://")) {
             node = cleaner.clean(new URL(src), inCharset);
-        } else {
+        } else if (!src.isEmpty()) {
             node = cleaner.clean(new File(src), inCharset);
+        } else {
+            node = cleaner.clean(s);
         }
 
         // if user specifies XPath expresssion to choose node for serialization, then
@@ -316,6 +340,8 @@
         } else {
             out = new FileOutputStream(destination);
         }
+        
+        	
 
         if ( "compact".equals(outputType) ) {
             new CompactXmlSerializer(props).writeToStream(node, out, outCharset);
Index: org/htmlcleaner/Html5TagProvider.java
===================================================================
--- org/htmlcleaner/Html5TagProvider.java	(revision 389)
+++ org/htmlcleaner/Html5TagProvider.java	(working copy)
@@ -1,35 +1,40 @@
-/*  Copyright (c) 2006-2015, The HtmlCleaner Project
-    All rights reserved.
+/*  Copyright (c) 2006-2015, Philokypros Ioulianou
+	All rights reserved.
+
+	Redistribution and use of this software in source and binary forms,
+	with or without modification, are permitted provided that the following
+	conditions are met:
 
-    Redistribution and use of this software in source and binary forms,
-    with or without modification, are permitted provided that the following
-    conditions are met:
+	* Redistributions of source code must retain the above
+	  copyright notice, this list of conditions and the
+	  following disclaimer.
 
-    * Redistributions of source code must retain the above
-      copyright notice, this list of conditions and the
-      following disclaimer.
+	* Redistributions in binary form must reproduce the above
+	  copyright notice, this list of conditions and the
+	  following disclaimer in the documentation and/or other
+	  materials provided with the distribution.
 
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the
-      following disclaimer in the documentation and/or other
-      materials provided with the distribution.
+	* The name of HtmlCleaner may not be used to endorse or promote
+	  products derived from this software without specific prior
+	  written permission.
 
-    * The name of HtmlCleaner may not be used to endorse or promote
-      products derived from this software without specific prior
-      written permission.
+	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+	AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+	ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+	LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+	CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+	POSSIBILITY OF SUCH DAMAGE.
 
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-    POSSIBILITY OF SUCH DAMAGE.
+	You can contact Philokypros Ioulianou by sending e-mail to
+	philokypro_s@hotmail.com. Please include the word "HtmlCleaner" in the
+	subject line.
 */
+
 package org.htmlcleaner;
 
 import java.util.concurrent.ConcurrentHashMap;
@@ -107,6 +112,7 @@
         tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
         tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
         tagInfo.defineForbiddenTags("menu");
+        tagInfo.defineForbiddenTags("address");
         this.put("aside", tagInfo);
    
         tagInfo = new TagInfo("h1", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
@@ -142,19 +148,20 @@
         tagInfo = new TagInfo("hgroup", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
         tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
         tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+        tagInfo.defineAllowedChildrenTags("h1,h2,h3,h4,h5,h6");
         this.put("hgroup", tagInfo);
    
         // header and footer
         tagInfo = new TagInfo("header", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
         tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
         tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
-        tagInfo.defineForbiddenTags("menu");
+        tagInfo.defineForbiddenTags("menu,header,footer");
         this.put("header", tagInfo);
         
         tagInfo = new TagInfo("footer", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
         tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
         tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
-        tagInfo.defineForbiddenTags("menu");
+        tagInfo.defineForbiddenTags("menu,header,footer");
         this.put("footer", tagInfo);
         
         tagInfo = new TagInfo("main", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
@@ -165,6 +172,7 @@
         tagInfo = new TagInfo("address", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
         tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
         tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+        tagInfo.defineForbiddenTags("address");
         this.put("address", tagInfo);
     }
         
@@ -183,6 +191,7 @@
         tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
         tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
         tagInfo.defineRequiredEnclosingTags("details");
+        tagInfo.defineForbiddenTags("summary");
         this.put("summary", tagInfo);
         
         tagInfo = new TagInfo("command", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
@@ -200,7 +209,7 @@
         tagInfo = new TagInfo("menuitem", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
         tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
         tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
-        tagInfo.defineFatalTags("menu");
+        tagInfo.defineRequiredEnclosingTags("menu");
         this.put("menuitem", tagInfo);
         
         tagInfo = new TagInfo("dialog", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.any);
@@ -267,10 +276,12 @@
 
         tagInfo = new TagInfo("dt", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.optional, Display.block);
         tagInfo.defineCloseBeforeTags("dt,dd");
+        tagInfo.defineRequiredEnclosingTags("dl");
         this.put("dt", tagInfo);
 
         tagInfo = new TagInfo("dd", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.optional, Display.block);
         tagInfo.defineCloseBeforeTags("dt,dd");
+        tagInfo.defineRequiredEnclosingTags("dl");
         this.put("dd", tagInfo);
         
         tagInfo = new TagInfo("hr", ContentType.none, BelongsTo.BODY, false, false, false, CloseTag.forbidden, Display.block);
@@ -407,7 +418,7 @@
         //
         // If we include this rule, we get an out-of-memory error. See issue 126.
         //
-        tagInfo.defineRequiredEnclosingTags("ruby");
+        //tagInfo.defineRequiredEnclosingTags("ruby");
         tagInfo.defineAllowedChildrenTags(PHRASING_TAGS);
         this.put("rp", tagInfo);
         }
@@ -490,7 +501,7 @@
         public void tableTags(TagInfo tagInfo){
         
         tagInfo = new TagInfo("table", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
-        tagInfo.defineAllowedChildrenTags("tr,tbody,thead,tfoot,colgroup,caption");
+        tagInfo.defineAllowedChildrenTags("tr,tbody,thead,tfoot,col,colgroup,caption");
         tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
         tagInfo.defineCloseBeforeTags("tr,thead,tbody,tfoot,caption,colgroup,table,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
         this.put("table", tagInfo);
@@ -583,7 +594,7 @@
 
         tagInfo = new TagInfo("option",  ContentType.text, BelongsTo.BODY, false, false, true, CloseTag.optional, Display.inline);
         tagInfo.defineFatalTags("select,datalist");
-        tagInfo.defineCloseBeforeTags("option");
+        tagInfo.defineCloseBeforeTags("option,optgroup");
         this.put("option", tagInfo);
 
         tagInfo = new TagInfo("optgroup", ContentType.all, BelongsTo.BODY, false, false, true, CloseTag.required, Display.inline);
@@ -597,10 +608,11 @@
         this.put("button", tagInfo);
 
         tagInfo = new TagInfo("label", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        tagInfo.defineFatalTags("label");
         this.put("label", tagInfo);
         
-        //Works now
         tagInfo = new TagInfo("legend", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+        //Bug with fieldset
         //tagInfo.defineRequiredEnclosingTags("fieldset");
         tagInfo.defineAllowedChildrenTags(PHRASING_TAGS);
         this.put("legend", tagInfo);
@@ -662,134 +674,6 @@
         this.put("noscript", tagInfo);
         }    
         
-        /**
-         * HTML 4 and earlier tags
-         */
-
-   
-
-
-//        tagInfo = new TagInfo("h1", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
-//        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
-//        tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
-//        this.put("h1", tagInfo);
-//
-//        tagInfo = new TagInfo("h2", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
-//        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
-//        tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
-//        this.put("h2", tagInfo);
-//
-//        tagInfo = new TagInfo("h3", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
-//        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
-//        tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
-//        this.put("h3", tagInfo);
-//
-//        tagInfo = new TagInfo("h4", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
-//        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
-//        tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
-//        this.put("h4", tagInfo);
-//
-//        tagInfo = new TagInfo("h5", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
-//        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
-//        tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
-//        this.put("h5", tagInfo);
-//
-//        tagInfo = new TagInfo("h6", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
-//        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
-//        tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
-//        this.put("h6", tagInfo);
-
-        // jericho parser requires <p></p>
-//        tagInfo = new TagInfo("p", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
-//        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
-//        tagInfo.defineCloseBeforeTags("p,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
-//        this.put("p", tagInfo);
-  
-        //only html4
-        //tagInfo = new TagInfo("acronym", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
-        //this.put("acronym", tagInfo);
-
-        //before html4
-        //tagInfo = new TagInfo("xmp",  ContentType.text, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
-        //this.put("xmp", tagInfo);
-
-
-//        
-//
-//       
-//      //only html4
-//        tagInfo = new TagInfo("applet", ContentType.all, BelongsTo.BODY, true, false, false, CloseTag.required, Display.any);
-//        this.put("applet", tagInfo);
-//
-//        tagInfo = new TagInfo("xml", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.none);
-//        this.put("xml", tagInfo);
-//
-//       
-//      //old html
-//        tagInfo = new TagInfo("menu", ContentType.all, BelongsTo.BODY, true, false, false, CloseTag.required, Display.block);
-//        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
-//        tagInfo.defineCloseBeforeTags("p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
-//        this.put("menu", tagInfo);
-//
-//        tagInfo = new TagInfo("dir", ContentType.all, BelongsTo.BODY, true, false, false, CloseTag.required, Display.block);
-//        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
-//        tagInfo.defineCloseBeforeTags("p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
-//        this.put("dir", tagInfo);
-//
-//
-//        tagInfo = new TagInfo("isindex", ContentType.none, BelongsTo.BODY, true, false, false, CloseTag.forbidden, Display.block);
-//        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
-//        tagInfo.defineCloseBeforeTags("p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
-//        this.put("isindex", tagInfo);
-//
-//       
-//
-//       
-//
-//        tagInfo = new TagInfo("tt", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
-//        tagInfo.defineCloseInsideCopyAfterTags("b,u,i,sub,sup,big,small,strike,blink,s");
-//        this.put("tt", tagInfo);
-//
-//       
-//        //html4
-//        tagInfo = new TagInfo("big", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
-//        tagInfo.defineCloseInsideCopyAfterTags("b,u,i,tt,sub,sup,small,strike,blink,s");
-//        this.put("big", tagInfo);
-//
-//       
-//
-//        tagInfo = new TagInfo("strike", ContentType.all, BelongsTo.BODY, true, false, false, CloseTag.required, Display.inline);
-//        tagInfo.defineCloseInsideCopyAfterTags("b,u,i,tt,sub,sup,big,small,blink,s");
-//        this.put("strike", tagInfo);
-//
-//        tagInfo = new TagInfo("blink", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
-//        tagInfo.defineCloseInsideCopyAfterTags("b,u,i,tt,sub,sup,big,small,strike,s");
-//        this.put("blink", tagInfo);
-//
-//        tagInfo = new TagInfo("marquee", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
-//        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
-//        tagInfo.defineCloseBeforeTags("p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
-//        this.put("marquee", tagInfo);
-//
-//        tagInfo = new TagInfo("font", ContentType.all, BelongsTo.BODY, true, false, false, CloseTag.required, Display.inline);
-//        this.put("font", tagInfo);
-//
-//        tagInfo = new TagInfo("basefont", ContentType.none, BelongsTo.BODY, true, false, false, CloseTag.forbidden, Display.none);
-//        this.put("basefont", tagInfo);
-//
-//        tagInfo = new TagInfo("center", ContentType.all, BelongsTo.BODY, true, false, false, CloseTag.required, Display.block);
-//        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
-//        tagInfo.defineCloseBeforeTags("p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
-//        this.put("center", tagInfo);
-//
-//        tagInfo = new TagInfo("comment", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.none);
-//        this.put("comment", tagInfo);
-//
-//        tagInfo = new TagInfo("server", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.none);
-//        this.put("server", tagInfo);
-
-        
-    
 
     /**
      * @param key
Index: org/htmlcleaner/Html4TagProvider.java
===================================================================
--- org/htmlcleaner/Html4TagProvider.java	(revision 0)
+++ org/htmlcleaner/Html4TagProvider.java	(revision 0)
@@ -0,0 +1,535 @@
+/*  Copyright (c) 2006-2015, Philokypros Ioulianou
+	All rights reserved.
+
+	Redistribution and use of this software in source and binary forms,
+	with or without modification, are permitted provided that the following
+	conditions are met:
+
+	* Redistributions of source code must retain the above
+	  copyright notice, this list of conditions and the
+	  following disclaimer.
+
+	* Redistributions in binary form must reproduce the above
+	  copyright notice, this list of conditions and the
+	  following disclaimer in the documentation and/or other
+	  materials provided with the distribution.
+
+	* The name of HtmlCleaner may not be used to endorse or promote
+	  products derived from this software without specific prior
+	  written permission.
+
+	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+	AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+	ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+	LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+	CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+	POSSIBILITY OF SUCH DAMAGE.
+
+	You can contact Philokypros Ioulianou by sending e-mail to
+	philokypro_s@hotmail.com. Please include the word "HtmlCleaner" in the
+	subject line.
+*/
+
+package org.htmlcleaner;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+public class Html4TagProvider implements ITagInfoProvider {
+
+	private static final String STRONG = "strong";
+    private ConcurrentMap<String, TagInfo> tagInfoMap = new ConcurrentHashMap<String, TagInfo>();
+    // singleton instance, used if no other TagInfoProvider is specified
+    public final static Html4TagProvider INSTANCE= new Html4TagProvider();
+    
+    private static final String CLOSE_BEFORE_COPY_INSIDE_TAGS = "bdo,"+STRONG+",em,q,b,i,u,tt,sub,sup,big,small,strike,s,font";
+    private static final String CLOSE_BEFORE_TAGS = "p,details,summary,menuitem,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml";
+  
+    /**
+     * Phrasing tags are those that can make up paragraphs along with text to make Phrasing Content
+     */
+    private static final String PHRASING_TAGS = "a,abbr,area,b,bdi,bdo,br,button,canvas,cite,code,command,data,datalist,del,dfn,em,embed,i,iframe,img,input,ins,kbd,keygen,label,link,map,mark,math,meta,meter,noscript,object,output,progress,q,s,samp,script,select,small,span,strong,sub,sup,svg,template,text,textarea,time,u,var,wbr";
+    
+    public Html4TagProvider() {
+
+    	TagInfo tagInfo=null;
+    	basicElements(tagInfo);
+    	formattingElements(tagInfo);
+    	formElements(tagInfo);
+    	imgElements(tagInfo);
+    	listElements(tagInfo);
+    	linkElements(tagInfo);
+    	tableElements(tagInfo);
+    	styleElements(tagInfo);
+    	olderElements(tagInfo);
+    	scriptElements(tagInfo);
+    }
+    
+    public void basicElements(TagInfo tagInfo){
+    
+    	  tagInfo = new TagInfo("title",  ContentType.text, BelongsTo.HEAD, false, true, false, CloseTag.required, Display.none);
+          this.put("title", tagInfo);
+
+          tagInfo = new TagInfo("h1", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+          tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+          tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+          this.put("h1", tagInfo);
+
+          tagInfo = new TagInfo("h2", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+          tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+          tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+          this.put("h2", tagInfo);
+
+          tagInfo = new TagInfo("h3", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+          tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+          tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+          this.put("h3", tagInfo);
+
+          tagInfo = new TagInfo("h4", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+          tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+          tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+          this.put("h4", tagInfo);
+
+          tagInfo = new TagInfo("h5", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+          tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+          tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+          this.put("h5", tagInfo);
+
+          tagInfo = new TagInfo("h6", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+          tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+          tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+          this.put("h6", tagInfo);
+          
+          // jericho parser requires <p></p>
+          tagInfo = new TagInfo("p", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+          tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+          tagInfo.defineCloseBeforeTags("p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
+          this.put("p", tagInfo);
+          
+          tagInfo = new TagInfo("br", ContentType.none, BelongsTo.BODY, false, false, false, CloseTag.forbidden, Display.none);
+          this.put("br", tagInfo);
+
+          tagInfo = new TagInfo("hr", ContentType.none, BelongsTo.BODY, false, false, false, CloseTag.forbidden, Display.block);
+          tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+          tagInfo.defineCloseBeforeTags("p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
+          this.put("hr", tagInfo);
+          
+          tagInfo = new TagInfo("div", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+          tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+          tagInfo.defineCloseBeforeTags(CLOSE_BEFORE_TAGS);
+          this.put("div", tagInfo);
+    }
+    
+    
+    public void formattingElements(TagInfo tagInfo){
+    
+    	tagInfo = new TagInfo("abbr", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        this.put("abbr", tagInfo);
+
+        tagInfo = new TagInfo("acronym", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        this.put("acronym", tagInfo);
+
+        tagInfo = new TagInfo("address", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+        tagInfo.defineCloseBeforeTags("p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
+        this.put("address", tagInfo);
+
+        tagInfo = new TagInfo("b", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        tagInfo.defineCloseInsideCopyAfterTags("u,i,tt,sub,sup,big,small,strike,blink,s");
+        this.put("b", tagInfo);
+        
+        tagInfo = new TagInfo("bdo", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        this.put("bdo", tagInfo);
+
+        
+        tagInfo = new TagInfo("blockquote", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+        tagInfo.defineCloseBeforeTags("p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
+        this.put("blockquote", tagInfo);
+
+        tagInfo = new TagInfo("cite", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        this.put("cite", tagInfo);
+
+        tagInfo = new TagInfo("q", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        this.put("q", tagInfo);
+
+        tagInfo = new TagInfo("code", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        this.put("code", tagInfo);
+
+        tagInfo = new TagInfo("ins", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.any);
+        this.put("ins", tagInfo);
+
+
+        tagInfo = new TagInfo("i", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        tagInfo.defineCloseInsideCopyAfterTags("b,u,tt,sub,sup,big,small,strike,blink,s");
+        this.put("i", tagInfo);
+
+        tagInfo = new TagInfo("u", ContentType.all, BelongsTo.BODY, true, false, false, CloseTag.required, Display.inline);
+        tagInfo.defineCloseInsideCopyAfterTags("b,i,tt,sub,sup,big,small,strike,blink,s");
+        this.put("u", tagInfo);
+
+        tagInfo = new TagInfo("tt", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        tagInfo.defineCloseInsideCopyAfterTags("b,u,i,sub,sup,big,small,strike,blink,s");
+        this.put("tt", tagInfo);
+
+        tagInfo = new TagInfo("sub", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        tagInfo.defineCloseInsideCopyAfterTags("b,u,i,tt,sup,big,small,strike,blink,s");
+        this.put("sub", tagInfo);
+
+        tagInfo = new TagInfo("sup", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        tagInfo.defineCloseInsideCopyAfterTags("b,u,i,tt,sub,big,small,strike,blink,s");
+        this.put("sup", tagInfo);
+
+        tagInfo = new TagInfo("big", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        tagInfo.defineCloseInsideCopyAfterTags("b,u,i,tt,sub,sup,small,strike,blink,s");
+        this.put("big", tagInfo);
+
+        tagInfo = new TagInfo("small", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        tagInfo.defineCloseInsideCopyAfterTags("b,u,i,tt,sub,sup,big,strike,blink,s");
+        this.put("small", tagInfo);
+
+        tagInfo = new TagInfo("strike", ContentType.all, BelongsTo.BODY, true, false, false, CloseTag.required, Display.inline);
+        tagInfo.defineCloseInsideCopyAfterTags("b,u,i,tt,sub,sup,big,small,blink,s");
+        this.put("strike", tagInfo);
+
+        tagInfo = new TagInfo("blink", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        tagInfo.defineCloseInsideCopyAfterTags("b,u,i,tt,sub,sup,big,small,strike,s");
+        this.put("blink", tagInfo);
+
+        tagInfo = new TagInfo("marquee", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+        tagInfo.defineCloseBeforeTags("p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
+        this.put("marquee", tagInfo);
+
+        tagInfo = new TagInfo("s", ContentType.all, BelongsTo.BODY, true, false, false, CloseTag.required, Display.inline);
+        tagInfo.defineCloseInsideCopyAfterTags("b,u,i,tt,sub,sup,big,small,strike,blink");
+        this.put("s", tagInfo);
+
+
+        tagInfo = new TagInfo("font", ContentType.all, BelongsTo.BODY, true, false, false, CloseTag.required, Display.inline);
+        this.put("font", tagInfo);
+
+        tagInfo = new TagInfo("basefont", ContentType.none, BelongsTo.BODY, true, false, false, CloseTag.forbidden, Display.none);
+        this.put("basefont", tagInfo);
+
+        tagInfo = new TagInfo("center", ContentType.all, BelongsTo.BODY, true, false, false, CloseTag.required, Display.block);
+        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+        tagInfo.defineCloseBeforeTags("p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
+        this.put("center", tagInfo);
+
+        
+        tagInfo = new TagInfo("del", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.any);
+        this.put("del", tagInfo);
+
+        tagInfo = new TagInfo("dfn", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        this.put("dfn", tagInfo);
+
+        tagInfo = new TagInfo("kbd", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        this.put("kbd", tagInfo);
+
+        tagInfo = new TagInfo("pre", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+        tagInfo.defineCloseBeforeTags("p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
+        this.put("pre", tagInfo);
+
+        tagInfo = new TagInfo("samp", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        this.put("samp", tagInfo);
+        
+        tagInfo = new TagInfo(STRONG, ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        this.put(STRONG, tagInfo);
+
+        tagInfo = new TagInfo("em", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        this.put("em", tagInfo);
+
+        tagInfo = new TagInfo("var", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        this.put("var", tagInfo);
+
+        
+        tagInfo = new TagInfo("wbr", ContentType.none, BelongsTo.BODY, false, false, false, CloseTag.forbidden, Display.none);
+        this.put("wbr", tagInfo);
+        
+        
+    }
+    
+    
+    public void formElements(TagInfo tagInfo){
+    	tagInfo = new TagInfo("form", ContentType.all, BelongsTo.BODY, false, false, true, CloseTag.required, Display.block);
+        tagInfo.defineForbiddenTags("form");
+        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+        tagInfo.defineCloseBeforeTags("option,optgroup,textarea,select,fieldset,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
+        this.put("form", tagInfo);
+
+        tagInfo = new TagInfo("input", ContentType.none, BelongsTo.BODY, false, false, false, CloseTag.forbidden, Display.inline);
+        tagInfo.defineCloseBeforeTags("select,optgroup,option");
+        this.put("input", tagInfo);
+
+        tagInfo = new TagInfo("textarea", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        tagInfo.defineCloseBeforeTags("select,optgroup,option");
+        this.put("textarea", tagInfo);
+
+        tagInfo = new TagInfo("select", ContentType.all, BelongsTo.BODY, false, false, true, CloseTag.required, Display.inline);
+        tagInfo.defineAllowedChildrenTags("option,optgroup");
+        tagInfo.defineCloseBeforeTags("option,optgroup,select");
+        this.put("select", tagInfo);
+
+        tagInfo = new TagInfo("option",  ContentType.text, BelongsTo.BODY, false, false, true, CloseTag.optional, Display.inline);
+        tagInfo.defineFatalTags("select");
+        tagInfo.defineCloseBeforeTags("option");
+        this.put("option", tagInfo);
+
+        tagInfo = new TagInfo("optgroup", ContentType.all, BelongsTo.BODY, false, false, true, CloseTag.required, Display.inline);
+        tagInfo.defineFatalTags("select");
+        tagInfo.defineAllowedChildrenTags("option");
+        tagInfo.defineCloseBeforeTags("optgroup");
+        this.put("optgroup", tagInfo);
+
+        tagInfo = new TagInfo("button", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.any);
+        tagInfo.defineCloseBeforeTags("select,optgroup,option");
+        this.put("button", tagInfo);
+
+        tagInfo = new TagInfo("label", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        this.put("label", tagInfo);
+        
+        tagInfo = new TagInfo("legend", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+        //
+        // If we include this rule, we get an out-of-memory error. See issue 129.
+        //
+        //tagInfo.defineRequiredEnclosingTags("fieldset");
+        tagInfo.defineAllowedChildrenTags(PHRASING_TAGS);
+        this.put("legend", tagInfo);
+
+        tagInfo = new TagInfo("fieldset", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+        tagInfo.defineCloseBeforeTags("p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
+        this.put("fieldset", tagInfo);
+    
+    }
+    
+    
+    public void listElements(TagInfo tagInfo){
+    	
+    	tagInfo = new TagInfo("ul", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+        tagInfo.defineCloseBeforeTags("p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
+        this.put("ul", tagInfo);
+
+        tagInfo = new TagInfo("ol", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+        tagInfo.defineCloseBeforeTags("p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
+        this.put("ol", tagInfo);
+
+        tagInfo = new TagInfo("li", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.optional, Display.block);
+        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+        tagInfo.defineCloseBeforeTags("li,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
+        this.put("li", tagInfo);
+
+        tagInfo = new TagInfo("dl", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+        tagInfo.defineCloseBeforeTags("p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
+        this.put("dl", tagInfo);
+
+        tagInfo = new TagInfo("dt", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.optional, Display.block);
+        tagInfo.defineCloseBeforeTags("dt,dd");
+        this.put("dt", tagInfo);
+
+        tagInfo = new TagInfo("dd", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.optional, Display.block);
+        tagInfo.defineCloseBeforeTags("dt,dd");
+        this.put("dd", tagInfo);
+
+        tagInfo = new TagInfo("menu", ContentType.all, BelongsTo.BODY, true, false, false, CloseTag.required, Display.block);
+        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+        tagInfo.defineCloseBeforeTags("p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
+        this.put("menu", tagInfo);
+        
+        tagInfo = new TagInfo("dir", ContentType.all, BelongsTo.BODY, true, false, false, CloseTag.required, Display.block);
+        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+        tagInfo.defineCloseBeforeTags("p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
+        this.put("dir", tagInfo);
+    	
+    }
+    
+    
+    public void linkElements(TagInfo tagInfo){
+    	
+    	 tagInfo = new TagInfo("link", ContentType.none, BelongsTo.HEAD, false, false, false, CloseTag.forbidden, Display.none);
+         this.put("link", tagInfo);
+         
+         tagInfo = new TagInfo("a", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+         tagInfo.defineCloseBeforeTags("a");
+         this.put("a", tagInfo);
+    }
+    	
+    
+    public void tableElements(TagInfo tagInfo){
+    	
+    	tagInfo = new TagInfo("table", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+        tagInfo.defineAllowedChildrenTags("tr,tbody,thead,tfoot,colgroup,caption");
+        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+        tagInfo.defineCloseBeforeTags("tr,thead,tbody,tfoot,caption,colgroup,table,p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
+        this.put("table", tagInfo);
+
+        tagInfo = new TagInfo("tr", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.optional, Display.block);
+        tagInfo.defineFatalTags("table");
+        tagInfo.defineRequiredEnclosingTags("tbody");
+        tagInfo.defineAllowedChildrenTags("td,th");
+        tagInfo.defineHigherLevelTags("thead,tfoot");
+        tagInfo.defineCloseBeforeTags("tr,td,th,caption,colgroup");
+        this.put("tr", tagInfo);
+
+        // jericho parser requires <td></td>
+        tagInfo = new TagInfo("td", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+        tagInfo.defineFatalTags("table");
+        tagInfo.defineRequiredEnclosingTags("tr");
+        tagInfo.defineCloseBeforeTags("td,th,caption,colgroup");
+        this.put("td", tagInfo);
+
+        tagInfo = new TagInfo("th", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.optional, Display.block);
+        tagInfo.defineFatalTags("table");
+        tagInfo.defineRequiredEnclosingTags("tr");
+        tagInfo.defineCloseBeforeTags("td,th,caption,colgroup");
+        this.put("th", tagInfo);
+
+        tagInfo = new TagInfo("tbody", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.optional, Display.block);
+        tagInfo.defineFatalTags("table");
+        tagInfo.defineAllowedChildrenTags("tr,form");
+        tagInfo.defineCloseBeforeTags("td,th,tr,tbody,thead,tfoot,caption,colgroup");
+        this.put("tbody", tagInfo);
+
+        tagInfo = new TagInfo("thead", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.optional, Display.block);
+        tagInfo.defineFatalTags("table");
+        tagInfo.defineAllowedChildrenTags("tr,form");
+        tagInfo.defineCloseBeforeTags("td,th,tr,tbody,thead,tfoot,caption,colgroup");
+        this.put("thead", tagInfo);
+
+        tagInfo = new TagInfo("tfoot", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.optional, Display.block);
+        tagInfo.defineFatalTags("table");
+        tagInfo.defineAllowedChildrenTags("tr,form");
+        tagInfo.defineCloseBeforeTags("td,th,tr,tbody,thead,tfoot,caption,colgroup");
+        this.put("tfoot", tagInfo);
+
+        tagInfo = new TagInfo("col", ContentType.none, BelongsTo.BODY, false, false, false, CloseTag.forbidden, Display.block);
+        tagInfo.defineFatalTags("colgroup");
+        this.put("col", tagInfo);
+
+        tagInfo = new TagInfo("colgroup", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.optional, Display.block);
+        tagInfo.defineFatalTags("table");
+        tagInfo.defineAllowedChildrenTags("col");
+        tagInfo.defineCloseBeforeTags("td,th,tr,tbody,thead,tfoot,caption,colgroup");
+        this.put("colgroup", tagInfo);
+        
+        tagInfo = new TagInfo("caption", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        tagInfo.defineFatalTags("table");
+        tagInfo.defineCloseBeforeTags("td,th,tr,tbody,thead,tfoot,caption,colgroup");
+        this.put("caption", tagInfo);
+        
+    }
+    
+    
+    public void styleElements(TagInfo tagInfo){
+    	
+    	tagInfo = new TagInfo("span", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+        this.put("span", tagInfo);
+
+        tagInfo = new TagInfo("style",  ContentType.text, BelongsTo.HEAD, false, false, false, CloseTag.required, Display.none);
+        this.put("style", tagInfo);
+
+        tagInfo = new TagInfo("bgsound", ContentType.none, BelongsTo.HEAD, false, false, false, CloseTag.forbidden, Display.none);
+        this.put("bgsound", tagInfo);
+
+        tagInfo = new TagInfo("meta", ContentType.none, BelongsTo.HEAD, false, false, false, CloseTag.forbidden, Display.none);
+        this.put("meta", tagInfo);
+
+        tagInfo = new TagInfo("base", ContentType.none, BelongsTo.HEAD, false, false, false, CloseTag.forbidden, Display.none);
+        this.put("base", tagInfo);
+    }
+    	
+    
+    public void scriptElements(TagInfo tagInfo){
+    	
+    	tagInfo = new TagInfo("script", ContentType.all, BelongsTo.HEAD_AND_BODY, false, false, false, CloseTag.required, Display.none);
+        this.put("script", tagInfo);
+
+        tagInfo = new TagInfo("noscript", ContentType.all, BelongsTo.HEAD_AND_BODY, false, false, false, CloseTag.required, Display.block);
+        this.put("noscript", tagInfo);
+        
+        tagInfo = new TagInfo("applet", ContentType.all, BelongsTo.BODY, true, false, false, CloseTag.required, Display.any);
+        this.put("applet", tagInfo);
+        
+        tagInfo = new TagInfo("object", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.any);
+        this.put("object", tagInfo);
+
+        tagInfo = new TagInfo("param", ContentType.none, BelongsTo.BODY, false, false, false, CloseTag.forbidden, Display.none);
+        tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+        tagInfo.defineCloseBeforeTags("p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
+        this.put("param", tagInfo);
+    }
+        
+       
+    public void imgElements(TagInfo tagInfo){
+    	  tagInfo = new TagInfo("img", ContentType.none, BelongsTo.BODY, false, false, false, CloseTag.forbidden, Display.inline);
+          this.put("img", tagInfo);
+
+          tagInfo = new TagInfo("area", ContentType.none, BelongsTo.BODY, false, false, false, CloseTag.forbidden, Display.none);
+          tagInfo.defineFatalTags("map");
+          tagInfo.defineCloseBeforeTags("area");
+          this.put("area", tagInfo);
+
+          tagInfo = new TagInfo("map", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.any);
+          tagInfo.defineCloseBeforeTags("map");
+          this.put("map", tagInfo);
+
+    }
+
+      
+    	public void olderElements(TagInfo tagInfo){
+    		tagInfo = new TagInfo("listing", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.block);
+            tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+            tagInfo.defineCloseBeforeTags("p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
+            this.put("listing", tagInfo);
+
+            tagInfo = new TagInfo("nobr", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+            tagInfo.defineCloseBeforeTags("nobr");
+            this.put("nobr", tagInfo);
+
+            tagInfo = new TagInfo("xmp",  ContentType.text, BelongsTo.BODY, false, false, false, CloseTag.required, Display.inline);
+            this.put("xmp", tagInfo);
+
+            tagInfo = new TagInfo("xml", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.none);
+            this.put("xml", tagInfo);
+
+            tagInfo = new TagInfo("isindex", ContentType.none, BelongsTo.BODY, true, false, false, CloseTag.forbidden, Display.block);
+            tagInfo.defineCloseBeforeCopyInsideTags(CLOSE_BEFORE_COPY_INSIDE_TAGS);
+            tagInfo.defineCloseBeforeTags("p,address,label,abbr,acronym,dfn,kbd,samp,var,cite,code,param,xml");
+            this.put("isindex", tagInfo);
+
+            tagInfo = new TagInfo("comment", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.none);
+            this.put("comment", tagInfo);
+
+            tagInfo = new TagInfo("server", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.none);
+            this.put("server", tagInfo);
+
+            tagInfo = new TagInfo("iframe", ContentType.all, BelongsTo.BODY, false, false, false, CloseTag.required, Display.any);
+            this.put("iframe", tagInfo);
+    		
+    	}
+      
+    
+    protected void put(String tagName, TagInfo tagInfo) {
+        this.tagInfoMap.put(tagName, tagInfo);
+    }
+
+    public TagInfo getTagInfo(String tagName) {
+        if ( tagName == null) {
+            // null named tagNode happens when a html fragment is being dealt with
+            return null;
+        } else {
+            return this.tagInfoMap.get(tagName);
+        }
+    }
+
+}
Index: org/htmlcleaner/CleanerProperties.java
===================================================================
--- org/htmlcleaner/CleanerProperties.java	(revision 389)
+++ org/htmlcleaner/CleanerProperties.java	(working copy)
@@ -84,6 +84,7 @@
     private boolean transSpecialEntitiesToNCR;
     private boolean omitCdataOutsideScriptAndStyle;
     private boolean deserializeEntities;
+    private int htmlversion=HtmlCleaner.defaulthtml;
     private boolean trimAttributeValues;
 
     /**
@@ -336,6 +337,26 @@
     public void setDeserializeEntities(boolean deserializeEntities) {
         this.deserializeEntities = deserializeEntities;
     }
+    
+    public CleanerProperties setHtmlVersion(boolean htmlver) {
+    	CleanerProperties c=new CleanerProperties();
+    	if(htmlver){
+    	   c.setTagInfoProvider(Html4TagProvider.INSTANCE);
+    	   HtmlCleaner.defaulthtml=HtmlCleaner.HTML_4;
+    	   return c;
+       }
+       else{
+    	   c.setTagInfoProvider(Html5TagProvider.INSTANCE);
+    	   HtmlCleaner.defaulthtml=HtmlCleaner.HTML_5;
+    	   return c;
+       }
+    }
+
+    public boolean isHtmlVersion4() {
+    	 if(HtmlCleaner.defaulthtml==HtmlCleaner.HTML_4)
+       	   return true;
+       return false;
+     }
 
     public boolean isTrimAttributeValues() {
         return trimAttributeValues;
@@ -344,7 +365,7 @@
     public void setTrimAttributeValues(boolean trimAttributeValues) {
         this.trimAttributeValues = trimAttributeValues;
     }
-
+    
     /**
      * Resets prune tags set and adds tag name conditions to it.
      * All the tags listed by pruneTags param are added.
@@ -465,6 +486,7 @@
      * collapseNullHtml = CollapseHtml.none
      * charset = "UTF-8";
      * trimAttributeValues = true;
+     * tagInfoProvider = HTML5TagProvider.INSTANCE
      */
     public void reset() {
         advancedXmlEscape = true;
@@ -493,7 +515,12 @@
         charset = "UTF-8";
         cleanerTransformations.clear();
         resetPruneTagSet();
-        tagInfoProvider = DefaultTagProvider.INSTANCE;
+        if (HtmlCleaner.defaulthtml==HtmlCleaner.HTML_4){
+        	tagInfoProvider = Html4TagProvider.INSTANCE;
+        }
+        else{
+        	tagInfoProvider = Html5TagProvider.INSTANCE;
+        }
         htmlModificationListeners = new ArrayList < HtmlModificationListener >();
         omitCdataOutsideScriptAndStyle = false;
         trimAttributeValues = true;
