private Vector<XMLNoteReplacer> getReplacers() {
		Vector<XMLNoteReplacer> r=new Vector<XMLNoteReplacer>();
		r.add(new XMLNoteReplacer("[<]head[^>]*[>].*?[<][/]head[>]","",true));
		r.add(new XMLNoteReplacer("[<]p[>](.*?)[<][/]p[>]","::P:PAR:P::$1::P:EPAR:P::",true));
		r.add(new XMLNoteReplacer("[<]p\\s[^>]+[>](.*?)[<][/]p[>]","::P:PAR:P::$1::P:EPAR:P::",true));
		r.add(new XMLNoteReplacer("[<]br[^>]*[>]","::E:BR:E::",true));
		
		r.add(new XMLNoteReplacer("[<]li[>]::P:PAR:P::(.*?)::P:EPAR:P::","<li>$1</li>",true));   // Correct OpenOffice behaviour.

		{
			Vector<XMLNoteReplacer> ulr=new Vector<XMLNoteReplacer>();
			ulr.add(new XMLNoteReplacer("[<]ul(\\s[^>]+){0,1}[>]","[<][/][uo]l[>]","::P:UL:P::","::P:EUL:P::",true));
			ulr.add(new XMLNoteReplacer("[<]ol(\\s[^>]+){0,1}[>]","[<][/][uo]l[>]","::P:OL:P::","::P:EOL:P::",true));
			ulr.add(new XMLNoteReplacer("[<]li(\\s[^>]+){0,1}[>]","[<][/]li[>]","::P:LI:P::","::P:ELI:P::",true));
			r.add(new XMLNoteReplacer("[<](ul|ol|li)(\\s[^>]+){0,1}[>]","[<][/](ul|ol|li)[>]",
					"::P:(PAR|EPAR):P::","([<][/]?li(\\s[^>]+){0,1}[>])",ulr,true,true
					)
			); 
		}
		
		r.add(new XMLNoteReplacer("[&]nbsp[;]"," ",true));

		//r.add(new XMLNoteReplacer("[<]li[>](.*?)[<][/]li[>]","::P:LI:P::$1::P:ELI:P::",true));
		//r.add(new XMLNoteReplacer("[<]li\\s[^>]+[>](.*?)[<][/]li[>]","::P:LI:P::$1::P:ELI:P::",true));
		
		r.add(new XMLNoteReplacer("[<]b(\\sclass=[\"]h[0-9][\"])\\s*[>](.*?)[<][/]b[>]","::EL:B:$1:EL::$2::EL:EB:EL::",true));
		r.add(new XMLNoteReplacer("[<]b[>](.*?)[<][/]b[>]","::EL:B:EL::$1::EL:EB:EL::",true));
		r.add(new XMLNoteReplacer("[<]b\\s[^>]+[>](.*?)[<][/]b[>]","::EL:B:EL::$1::EL:EB:EL::",true));
		r.add(new XMLNoteReplacer("[<]i[>](.*?)[<][/]i[>]","::EL:I:EL::$1::EL:EI:EL::",true));
		r.add(new XMLNoteReplacer("[<]i\\s[^>]+[>](.*?)[<][/]i[>]","::EL:I:EL::$1::EL:EI:EL::",true));
		r.add(new XMLNoteReplacer("[<]u[>](.*?)[<][/]u[>]","::EL:U:EL::$1::EL:EU:EL::",true));
		r.add(new XMLNoteReplacer("[<]u\\s[^>]+[>](.*?)[<][/]u[>]","::EL:U:EL::$1::EL:EU:EL::",true));
		
		r.add(new XMLNoteReplacer("[<]h1[>](.*?)[<][/]h1[>]","::EL:H1:EL::$1::EL:EH1:EL::",true));
		r.add(new XMLNoteReplacer("[<]h1\\s[^>]+[>](.*?)[<][/]h1[>]","::EL:H1:EL::$1::EL:EH1:EL::",true));
		r.add(new XMLNoteReplacer("[<]h2[>](.*?)[<][/]h2[>]","::EL:H2:EL::$1::EL:EH2:EL::",true));
		r.add(new XMLNoteReplacer("[<]h2\\s[^>]+[>](.*?)[<][/]h2[>]","::EL:H2:EL::$1::EL:EH2:EL::",true));
		r.add(new XMLNoteReplacer("[<]h3[>](.*?)[<][/]h3[>]","::EL:H3:EL::$1::EL:EH3:EL::",true));
		r.add(new XMLNoteReplacer("[<]h3\\s[^>]+[>](.*?)[<][/]h3[>]","::EL:H3:EL::$1::EL:EH3:EL::",true));
		r.add(new XMLNoteReplacer("[<]h4[>](.*?)[<][/]h4[>]","::EL:H4:EL::$1::EL:EH4:EL::",true));
		r.add(new XMLNoteReplacer("[<]h4\\s[^>]+[>](.*?)[<][/]h4[>]","::EL:H4:EL::$1::EL:EH4:EL::",true));
		r.add(new XMLNoteReplacer("[<]h5[>](.*?)[<][/]h5[>]","::EL:B:EL::$1::EL:EB:EL::",true));
		r.add(new XMLNoteReplacer("[<]h5\\s[^>]+[>](.*?)[<][/]h5[>]","::EL:B:EL::$1::EL:EB:EL::",true));
		
		r.add(new XMLNoteReplacer("[<][^>]+[>]","",true,true)); // General tag cleaner.
		
		r.add(new XMLNoteReplacer("::E:BR:E::","<br>",true));
		r.add(new XMLNoteReplacer("::P:PAR:P::(.*?)::P:EPAR:P::","<p>$1</p>",true));
		// If we still have (we don't want that) nested paragraphs, we correct that
		r.add(new XMLNoteReplacer("::P:(EPAR|PAR):P::","",true));
		// For the nested stuff we already have made sure they match, no problem there.
		r.add(new XMLNoteReplacer("::P:UL:P::","<ul>",true));
		r.add(new XMLNoteReplacer("::P:EUL:P::","</ul>",true));
		r.add(new XMLNoteReplacer("::P:OL:P::","<ol>",true));
		r.add(new XMLNoteReplacer("::P:EOL:P::","</ol>",true));
		r.add(new XMLNoteReplacer("::P:LI:P::(.*?)::P:ELI:P::","<li>$1</li>",true));
		r.add(new XMLNoteReplacer("::P:LI:P::","<li>",true));
		r.add(new XMLNoteReplacer("::P:ELI:P::","</li>",true));
		
		// Correct <li>...<ul> to <li>...</li><ul>
		//r.add(new XMLNoteReplacer("[<]"))
		// Now correct nested <li>'s in the html, we can't have nested <li>'s. The outer nesting needs to go.
		r.add(new XMLNoteReplacer("[<]li[>]\\s*[<]([ou])l[>]","<$1l>",true));
		r.add(new XMLNoteReplacer("[<]li[>]([^<]+)[<]([ou])l[>]","<li>$1</li><$2l>",true));
		r.add(new XMLNoteReplacer("[<][/]([ou])l[>]\\s*[<][/]li[>]","</$1l>",true));
		
		
		r.add(new XMLNoteReplacer("[<][/](ul|ol)[>]([^<]+)[<][/]p[>]","</$1><p>$2</p>",true)); // No start paragraph tag for a given paragraph tag.
		 // (other tags have been cleaned with the general tag cleaner).
		 // ul and ol are the only ones left.

		
		r.add(new XMLNoteReplacer("::EL:B:([^:]+):EL::(.*?)::EL:EB:EL::","<b$1>$2</b>",true));
		r.add(new XMLNoteReplacer("::EL:B:EL::(.*?)::EL:EB:EL::","<b>$1</b>",true));
		r.add(new XMLNoteReplacer("::EL:I:EL::(.*?)::EL:EI:EL::","<i>$1</i>",true));
		r.add(new XMLNoteReplacer("::EL:U:EL::(.*?)::EL:EU:EL::","<u>$1</u>",true));
		r.add(new XMLNoteReplacer("::EL:H1:EL::(.*?)::EL:EH1:EL::","<p><b class=\"h1\">$1</b></p>",true));
		r.add(new XMLNoteReplacer("::EL:H2:EL::(.*?)::EL:EH2:EL::","<p><b class=\"h2\">$1</b></p>",true));
		r.add(new XMLNoteReplacer("::EL:H3:EL::(.*?)::EL:EH3:EL::","<p><b class=\"h3\">$1</b></p>",true));
		r.add(new XMLNoteReplacer("::EL:H4:EL::(.*?)::EL:EH4:EL::","<p><b class=\"h4\">$1</b></p>",true));

		
		// correction
		
		r.add(new XMLNoteReplacer("[>]\\s*[<]","><",true,true));  // cleanup empty space between tags, surrounding text
		//r.add(new XMLNoteReplacer("[>]\\s*",">",true));
		r.add(new XMLNoteReplacer("^\\s+","",true));
		r.add(new XMLNoteReplacer("\\s+$","",true));
		
		//r.add(new XMLNoteReplacer("[<]p[>]","<p>$1</p>",true));      // correct html that has no paragraphs at all.
		r.add(new XMLNoteReplacer(new XMLNoteReplacer.Repl() {
			public String process(String in) {
				if (in.substring(0,3).equals("<p>")) {
					return in;
				} else {
					int i1=in.indexOf("<p>");
					int i2=in.indexOf("</p>");
					if (i1<i2) {
						return "<p>"+in.substring(0,i1)+"</p>"+in.substring(i1);
					} else {
						return "<p>"+in;
					}
				}
			}
		})); // correct the html from the beginning to the first <p> tag
		r.add(new XMLNoteReplacer(new XMLNoteReplacer.Repl() {
			public String process(String in) {
				if (in.substring(in.length()-4).equals("</p>")) {
					return in;
				} else {
					int i;
					for(i=in.length()-4;i>=0 && !in.substring(i,i+4).equals("</p>");i--);
					if (i<0) {
						for(i=in.length()-3;i>=0 && !in.substring(i,i+3).equals("<p>");i--);
						if (i<0) {
							return in;
						} else {
							return in+"</p>";
						}
					} else {
						return in.substring(0,i+4)+"<p>"+in.substring(i+4)+"</p>";
					}
				}	
			}
		})); // correct html from end paragraph to end of html
		r.add(new XMLNoteReplacer("[<][/]p[>](.*?)[<]p[>]","</p><p>$1</p><p>",true)); // correct lines in between that have no paragraph boundaries
		r.add(new XMLNoteReplacer("[<]p[>][<][/]p[>]","",true)); // correct empty paragraphs.
		
		
		//This one doesn't work. with </ul></ul></p> 
		//r.add(new XMLNoteReplacer("[<][/](ul|ol)[>](.+?)[<][/]p[>]","</$1><p>$2</p>",true)); // No start paragraph tag for a given paragraph tag.
																							 // (other tags have been cleaned with the general tag cleaner).
																							 // ul and ol are the only ones left.
		// I've moved this cleaner up.

		r.add(new XMLNoteReplacer("(.*)","<p>$1</p>",true));  // enclose html in paragraph tags, in case there were no paragraph tags 
		r.add(new XMLNoteReplacer("[<]p[>][<]p[>]","<p>",true)); // remove double <p><p>
		r.add(new XMLNoteReplacer("[<][/]p[>][<][/]p[>]","</p>",true)); // remove double </p></p>	
		
		r.add(new XMLNoteReplacer("([<]p[>][<][/]p[>])+$","",true)); // remove ending (<p></p>)+
		
		
		r.add(new XMLNoteReplacer(new XMLNoteReplacer.Repl() {
			public String process(String in) {
				return correctNested(in,"[<]li[>]","[<][/]li[>]");
			}
		}));
		
		return r;
	}