Re: r6168 - in branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml: . internal

From: Mike Schrag (mschra..obox.com)
Date: Sun Oct 03 2010 - 21:17:25 UTC

  • Next message: Mike Schrag: "any showstoppers?"

    blerg ... i obviously accidentally hit cmd-shift-f on FuzzyXMLParser. oh well.

    On Oct 3, 2010, at 5:16 PM, mschra..bjectstyle.org wrote:

    > Author: mschrag
    > Date: 2010-10-03 21:16:16 +0000 (Sun, 03 Oct 2010)
    > New Revision: 6168
    >
    > Modified:
    > branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/FuzzyXMLAttribute.java
    > branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/FuzzyXMLElement.java
    > branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/FuzzyXMLNode.java
    > branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/FuzzyXMLParser.java
    > branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/internal/AbstractFuzzyXMLNode.java
    > branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/internal/FuzzyXMLAttributeImpl.java
    > branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/internal/FuzzyXMLElementImpl.java
    > branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/internal/FuzzyXMLFormatComposite.java
    > Log:
    > better support <div id="<webobject name="NestedTag"/>"> in both parsing and formatting ... add the concept of "synthetic tags" that don't structurally render
    >
    > Modified: branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/FuzzyXMLAttribute.java
    > ===================================================================
    > --- branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/FuzzyXMLAttribute.java 2010-10-03 21:15:19 UTC (rev 6167)
    > +++ branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/FuzzyXMLAttribute.java 2010-10-03 21:16:16 UTC (rev 6168)
    >.. -38,4 +38,8 @@
    > public void setEscape(boolean escape);
    >
    > public boolean isEscape();
    > +
    > + public void setHasNestedTag(boolean hasNestedTag);
    > +
    > + public boolean hasNestedTag();
    > }
    >
    > Modified: branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/FuzzyXMLElement.java
    > ===================================================================
    > --- branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/FuzzyXMLElement.java 2010-10-03 21:15:19 UTC (rev 6167)
    > +++ branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/FuzzyXMLElement.java 2010-10-03 21:16:16 UTC (rev 6168)
    >.. -71,4 +71,6 @@
    > public boolean isSelfClosing();
    >
    > public boolean isForbiddenFromHavingChildren();
    > +
    > + public void setSynthetic(boolean synthetic);
    > }
    >
    > Modified: branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/FuzzyXMLNode.java
    > ===================================================================
    > --- branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/FuzzyXMLNode.java 2010-10-03 21:15:19 UTC (rev 6167)
    > +++ branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/FuzzyXMLNode.java 2010-10-03 21:16:16 UTC (rev 6168)
    >.. -21,5 +21,6 @@
    > public String toXMLString(RenderContext renderContext);
    >
    > public void toXMLString(RenderContext renderContext, StringBuffer xmlBuffer);
    > -
    > +
    > + public boolean isSynthetic();
    > }
    >
    > Modified: branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/FuzzyXMLParser.java
    > ===================================================================
    > --- branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/FuzzyXMLParser.java 2010-10-03 21:15:19 UTC (rev 6167)
    > +++ branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/FuzzyXMLParser.java 2010-10-03 21:16:16 UTC (rev 6168)
    >.. -32,945 +32,964 @@
    >
    > public class FuzzyXMLParser {
    >
    > - private Stack<FuzzyXMLNode> _stack = new Stack<FuzzyXMLNode>();
    > - private String _originalSource;
    > - private List<FuzzyXMLNode> _roots;
    > - private FuzzyXMLDocType _docType;
    > + private Stack<FuzzyXMLNode> _stack = new Stack<FuzzyXMLNode>();
    > + private String _originalSource;
    > + private List<FuzzyXMLNode> _roots;
    > + private FuzzyXMLDocType _docType;
    >
    > - private List<FuzzyXMLErrorListener> _listeners = new ArrayList<FuzzyXMLErrorListener>();
    > - private List<FuzzyXMLElement> _nonCloseElements = new ArrayList<FuzzyXMLElement>();
    > - private List<String> _looseNamespaces = new ArrayList<String>();
    > - private List<String> _autocloseTags = new ArrayList<String>();
    > - private List<String> _looseTags = new ArrayList<String>();
    > + private List<FuzzyXMLErrorListener> _listeners = new ArrayList<FuzzyXMLErrorListener>();
    > + private List<FuzzyXMLElement> _nonCloseElements = new ArrayList<FuzzyXMLElement>();
    > + private List<String> _looseNamespaces = new ArrayList<String>();
    > + private List<String> _autocloseTags = new ArrayList<String>();
    > + private List<String> _looseTags = new ArrayList<String>();
    >
    > - private boolean _wellFormedRequired = false;
    > - private boolean _isHTML = false;
    > + private boolean _wellFormedRequired = false;
    > + private boolean _isHTML = false;
    >
    > - // ∞p™[∞X≠É⁄g˜p≠·≠é∆“—K\‘»
    > - private Pattern _tag = Pattern.compile("<((|/)([^<>]*))([^<]?|>)");
    > - // private Pattern attr = Pattern.compile("([\\w:]+?)\\s*=(\"|')([^\"]*?)\\2");
    > - private Pattern _docTypeName = Pattern.compile("^<!DOCTYPE[ \r\n\t]+([\\w\\-_]*)");
    > - private Pattern _docTypePublic = Pattern.compile("PUBLIC[ \r\n\t]+\"([^\"]*)\"[ \r\n\t]*\"*([^\">]*)\"*");
    > - private Pattern _docTypeSystem = Pattern.compile("SYSTEM[ \r\n\t]+\"([^\"]*)\"");
    > - private Pattern _docTypeSubset = Pattern.compile("\\[([^\\]]*)\\]>");
    > - private Pattern _invalidStringPattern = Pattern.compile("([<>&])");
    > - private Pattern _preCloseTagPattern = Pattern.compile("<\\s*/\\s*PRE\\s*>", Pattern.CASE_INSENSITIVE);
    > + // ï¿∏pï¿∏[ï¿∏Xï¿∏É⁄gï¿∏pï¿∏ï¿∏ï¿∏é∆“ï¿∏Kï¿∏\ï¿∏ï¿∏
    > + private Pattern _tag = Pattern.compile("<((|/)([^<>]*))([^<]?|>)");
    > + // private Pattern attr =
    > + // Pattern.compile("([\\w:]+?)\\s*=(\"|')([^\"]*?)\\2");
    > + private Pattern _docTypeName = Pattern.compile("^<!DOCTYPE[ \r\n\t]+([\\w\\-_]*)");
    > + private Pattern _docTypePublic = Pattern.compile("PUBLIC[ \r\n\t]+\"([^\"]*)\"[ \r\n\t]*\"*([^\">]*)\"*");
    > + private Pattern _docTypeSystem = Pattern.compile("SYSTEM[ \r\n\t]+\"([^\"]*)\"");
    > + private Pattern _docTypeSubset = Pattern.compile("\\[([^\\]]*)\\]>");
    > + private Pattern _invalidStringPattern = Pattern.compile("([<>&])");
    > + private Pattern _preCloseTagPattern = Pattern.compile("<\\s*/\\s*PRE\\s*>", Pattern.CASE_INSENSITIVE);
    >
    > - public FuzzyXMLParser(boolean wellFormedRequired) {
    > - this(wellFormedRequired, false);
    > - }
    > + public FuzzyXMLParser(boolean wellFormedRequired) {
    > + this(wellFormedRequired, false);
    > + }
    >
    > - public FuzzyXMLParser(boolean wellFormedRequired, boolean isHTML) {
    > - super();
    > - _wellFormedRequired = wellFormedRequired;
    > - _roots = new LinkedList<FuzzyXMLNode>();
    > - _isHTML = isHTML;
    > - // MS: Hardcoded that "wo" is a loose namespace
    > - addLooseNamespace("wo");
    > - addLooseNamespace("webobject");
    > - addLooseNamespace("webobjects");
    > - if (!_wellFormedRequired) {
    > - addAutocloseTag("img");
    > - addAutocloseTag("br");
    > - addAutocloseTag("hr");
    > - addAutocloseTag("meta");
    > - addAutocloseTag("link");
    > - addAutocloseTag("input");
    > - addAutocloseTag("spacer");
    > - addAutocloseTag("frame");
    > - addAutocloseTag("basefont");
    > - addAutocloseTag("base");
    > - addAutocloseTag("area");
    > - addAutocloseTag("col");
    > - addAutocloseTag("isindex");
    > - addAutocloseTag("param");
    > - addLooseTag("p");
    > - addLooseTag("li");
    > - }
    > - }
    > -
    > - /**
    > - * An autoclose tag is like br or link where it commonly does not have a closing tag
    > - * but it also never has contents.
    > - *
    > - *..aram autocloseTag the name of the tag to make loose
    > - */
    > - public void addAutocloseTag(String autocloseTag) {
    > - _autocloseTags.add(autocloseTag);
    > - addLooseTag(autocloseTag);
    > - }
    > -
    > - /**
    > - * A "loose" tag is like li or p where people lazily often do not close them properly,
    > - * but they may have content.
    > - *
    > - *..aram looseTag the name of the tag to make loose
    > - */
    > - public void addLooseTag(String looseTag) {
    > - _looseTags.add(looseTag);
    > - }
    > + public FuzzyXMLParser(boolean wellFormedRequired, boolean isHTML) {
    > + super();
    > + _wellFormedRequired = wellFormedRequired;
    > + _roots = new LinkedList<FuzzyXMLNode>();
    > + _isHTML = isHTML;
    > + // MS: Hardcoded that "wo" is a loose namespace
    > + addLooseNamespace("wo");
    > + addLooseNamespace("webobject");
    > + addLooseNamespace("webobjects");
    > + if (!_wellFormedRequired) {
    > + addAutocloseTag("img");
    > + addAutocloseTag("br");
    > + addAutocloseTag("hr");
    > + addAutocloseTag("meta");
    > + addAutocloseTag("link");
    > + addAutocloseTag("input");
    > + addAutocloseTag("spacer");
    > + addAutocloseTag("frame");
    > + addAutocloseTag("basefont");
    > + addAutocloseTag("base");
    > + addAutocloseTag("area");
    > + addAutocloseTag("col");
    > + addAutocloseTag("isindex");
    > + addAutocloseTag("param");
    > + addLooseTag("p");
    > + addLooseTag("li");
    > + }
    > + }
    >
    > - /**
    > - * A "loose" namespace is like the wo: namespace. We don't actually require that
    > - * wo:if have a corresponding wo:if close tag -- it actually just needs a
    > - * wo close tag.
    > - *
    > - *..aram namespace the name of the namespace to make loose
    > - */
    > - public void addLooseNamespace(String namespace) {
    > - _looseNamespaces.add(namespace);
    > - }
    > + /**
    > + * An autoclose tag is like br or link where it commonly does not have a
    > + * closing tag
    > + * but it also never has contents.
    > + *
    > + *..aram autocloseTag
    > + * the name of the tag to make loose
    > + */
    > + public void addAutocloseTag(String autocloseTag) {
    > + _autocloseTags.add(autocloseTag);
    > + addLooseTag(autocloseTag);
    > + }
    >
    > - /**
    > - * ∞G∞≈™[∞n∞„∞h∞…∞„∞O˜p≠Ì∞…∞X∞i≠›‚Ç≈Á≠µ≠Ü≠·™B
    > - *
    > - *..aram listener ∞…∞X∞i
    > - */
    > - public void addErrorListener(FuzzyXMLErrorListener listener) {
    > - _listeners.add(listener);
    > - }
    > + /**
    > + * A "loose" tag is like li or p where people lazily often do not close them
    > + * properly,
    > + * but they may have content.
    > + *
    > + *..aram looseTag
    > + * the name of the tag to make loose
    > + */
    > + public void addLooseTag(String looseTag) {
    > + _looseTags.add(looseTag);
    > + }
    >
    > - private void fireErrorEvent(int offset, int length, String message, FuzzyXMLNode node) {
    > - FuzzyXMLErrorEvent evt = new FuzzyXMLErrorEvent(offset, length, message, node);
    > - for (FuzzyXMLErrorListener listener : _listeners) {
    > - listener.error(evt);
    > - }
    > - }
    > + /**
    > + * A "loose" namespace is like the wo: namespace. We don't actually require
    > + * that
    > + * wo:if have a corresponding wo:if close tag -- it actually just needs a
    > + * wo close tag.
    > + *
    > + *..aram namespace
    > + * the name of the namespace to make loose
    > + */
    > + public void addLooseNamespace(String namespace) {
    > + _looseNamespaces.add(namespace);
    > + }
    >
    > - /**
    > - * „ü˜Í∞X∞g∞…™[∞•≠©≠çXML∞h∞L∞∑∞™∞„∞g≠›∞p™[∞X≠µ≠Ü≠·™B
    > - * ¶⁄˚∞R™[∞h≠ÍXML∆é‘≤≠É≠µ≠∏≠ª≠Á≠ĉ»Ê≠“≠ê≠Ü≠·™B
    > - *
    > - *..aram in „ü˜Í∞X∞g∞…™[∞•
    > - *..eturn ∞p™[∞X‘—≈Ê
    > - *..hrows IOException
    > - */
    > - public FuzzyXMLDocument parse(InputStream in) throws IOException {
    > - byte[] bytes = FuzzyXMLUtil.readStream(in);
    > - String encode = FuzzyXMLUtil.getEncoding(bytes);
    > - if (encode == null) {
    > - return parse(new String(bytes));
    > - }
    > - return parse(new String(bytes, encode));
    > - }
    > + /**
    > + * ï¿∏Gï¿∏ï¿∏ï¿∏[ï¿∏nï¿∏ï¿∏ï¿∏hï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Oï¿∏pï¿∏Ì∞ï¿∏ï¿∏Xï¿∏iï¿∏ï¿∏Ç≈ï¿∏ï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B
    > + *
    > + *..aram listener
    > + * ï¿∏ï¿∏ï¿∏Xï¿∏i
    > + */
    > + public void addErrorListener(FuzzyXMLErrorListener listener) {
    > + _listeners.add(listener);
    > + }
    >
    > - /**
    > - * ∞t .E2C∞—≠©≠çXML∞h∞L∞∑∞™∞„∞g≠›∞p™[∞X≠µ≠Ü≠·™B
    > - * ¶⁄˚∞R™[∞h≠ÍXML∆é‘≤≠É≠µ≠∏≠ª≠Á≠ĉ»Ê≠“≠ê≠Ü≠·™B
    > - *
    > - *..aram file ∞t∞@∞C∞—
    > - *..eturn ∞p™[∞X‘—≈Ê
    > - *..hrows IOException
    > - */
    > - public FuzzyXMLDocument parse(File file) throws IOException {
    > - byte[] bytes = FuzzyXMLUtil.readStream(new FileInputStream(file));
    > - String encode = FuzzyXMLUtil.getEncoding(bytes);
    > - if (encode == null) {
    > - return parse(new String(bytes));
    > - }
    > - return parse(new String(bytes, encode));
    > - }
    > + private void fireErrorEvent(int offset, int length, String message, FuzzyXMLNode node) {
    > + FuzzyXMLErrorEvent evt = new FuzzyXMLErrorEvent(offset, length, message, node);
    > + for (FuzzyXMLErrorListener listener : _listeners) {
    > + listener.error(evt);
    > + }
    > + }
    >
    > - protected int _parse(String source, int initialOffset, boolean woOnly) {
    > - // ∞p™[∞X≠›…J⁄n
    > - Matcher matcher = _tag.matcher(source);
    > - int lastIndex = initialOffset - 1;
    > - while (matcher.find()) {
    > - int start = matcher.start() + initialOffset;
    > - int end = matcher.end() + initialOffset;
    > - if (lastIndex == -1 && start > 0) {
    > - handleText(0, start, true);
    > - }
    > - else if (lastIndex != (initialOffset - 1) && lastIndex < start) {
    > - handleText(lastIndex, start, true);
    > - }
    > - String originalText = matcher.group(1);
    > - String text = originalText.trim();
    > - // Â≠¶∞^∞O
    > - if (!woOnly && text.startsWith("%")) {
    > - // ignore
    > - handleText(start, end, false);
    > - }
    > - else if (!woOnly && text.startsWith("?")) {
    > - handleDeclaration(start, end);
    > - }
    > - else if (!woOnly && (text.startsWith("!DOCTYPE") || text.startsWith("!doctype"))) {
    > - handleDoctype(start, end, text);
    > - }
    > - else if (!woOnly && text.startsWith("![CDATA[")) {
    > - handleCDATA(start, end, _originalSource.substring(start, end));
    > - }
    > - else if (!woOnly && (text.equalsIgnoreCase("pre") || text.toLowerCase().startsWith("pre "))) {
    > - end = handlePreTag(start, end);
    > - matcher.region(end, source.length());
    > - }
    > - else if (text.startsWith("/") && (!woOnly || WodHtmlUtils.isWOTag(text.substring(1)))) {
    > - handleCloseTag(start, end, text);
    > - }
    > - else if (text.endsWith("/") && (!woOnly || WodHtmlUtils.isWOTag(text))) {
    > - if (originalText.endsWith(" ")) {
    > - fireErrorEvent(start, end - start, "You can not have a space between the / and the > in your webobject tags.", null);
    > - }
    > - handleEmptyTag(start, end);
    > - }
    > - else if (!woOnly && text.startsWith("!--")) {
    > - end = _originalSource.indexOf("-->", start);
    > - if (end > 0) {
    > - end += 3;
    > - }
    > - handleComment(start, end, _originalSource.substring(start, end));
    > - matcher.region(end, source.length());
    > - }
    > - else if (!woOnly || WodHtmlUtils.isWOTag(text)) {
    > - handleStartTag(start, end);
    > - }
    > - lastIndex = end;
    > - }
    > - return lastIndex;
    > - }
    > + /**
    > + * ï¿∏ï¿∏Í∞Xï¿∏gï¿∏ï¿∏ï¿∏[ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏XMLï¿∏hï¿∏Lï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏gï¿∏ï¿∏ï¿∏pï¿∏[ï¿∏Xï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B
    > + * ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Rï¿∏[ï¿∏hï¿∏ï¿∏XMLï¿∏é‘≤ï¿∏É≠ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ĉï¿∏ï¿∏Ê≠ï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B
    > + *
    > + *..aram in
    > + * ï¿∏ï¿∏Í∞Xï¿∏gï¿∏ï¿∏ï¿∏[ï¿∏ï¿∏
    > + *..eturn ï¿∏pï¿∏[ï¿∏Xï¿∏ï¿∏ï¿∏ï¿∏
    > + *..hrows IOException
    > + */
    > + public FuzzyXMLDocument parse(InputStream in) throws IOException {
    > + byte[] bytes = FuzzyXMLUtil.readStream(in);
    > + String encode = FuzzyXMLUtil.getEncoding(bytes);
    > + if (encode == null) {
    > + return parse(new String(bytes));
    > + }
    > + return parse(new String(bytes, encode));
    > + }
    >
    > - /**
    > - * √ø∆‰≠Æ≠µ≠Ä„n≠“≠ê≠∏XML∞\™[∞X≠›∞p™[∞X≠µ≠ÄFuzzyXMLDocument∞I∞u∞W∞F∞N∞g≠›Ô—p≠µ≠Ü≠·™B
    > - *
    > - *..aram source XML∞\™[∞X
    > - *..eturn ∞p™[∞X‘—≈Ê≠ÌFuzzyXMLDocument∞I∞u∞W∞F∞N∞g
    > - */
    > - public FuzzyXMLDocument parse(String source) {
    > - // ∞I∞…∞W∞i∞—≠Ì∞\™[∞X≠›€Œ¶≠µ≠Ä≠¨≠–
    > - _originalSource = source;
    > - // ∞R∞™∞„∞g™ACDATA™ADOCTYPE‰ª≠›∂˛—⁄
    > - source = FuzzyXMLUtil.comment2space(source, true);
    > - source = FuzzyXMLUtil.escapeScript(source);
    > - source = FuzzyXMLUtil.scriptlet2space(source, true);
    > - source = FuzzyXMLUtil.cdata2space(source, true);
    > - source = FuzzyXMLUtil.doctype2space(source, true);
    > - source = FuzzyXMLUtil.processing2space(source, true);
    > - source = FuzzyXMLUtil.escapeString(source);
    > + /**
    > + * ï¿∏tï¿.C3¿∏Cï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏XMLï¿∏hï¿∏Lï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏gï¿∏ï¿∏ï¿∏pï¿∏[ï¿∏Xï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B
    > + * ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Rï¿∏[ï¿∏hï¿∏ï¿∏XMLï¿∏é‘≤ï¿∏É≠ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ĉï¿∏ï¿∏Ê≠ï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B
    > + *
    > + *..aram file
    > + * ï¿∏tï¿.C3¿∏Cï¿∏ï¿∏
    > + *..eturn ï¿∏pï¿∏[ï¿∏Xï¿∏ï¿∏ï¿∏ï¿∏
    > + *..hrows IOException
    > + */
    > + public FuzzyXMLDocument parse(File file) throws IOException {
    > + byte[] bytes = FuzzyXMLUtil.readStream(new FileInputStream(file));
    > + String encode = FuzzyXMLUtil.getEncoding(bytes);
    > + if (encode == null) {
    > + return parse(new String(bytes));
    > + }
    > + return parse(new String(bytes, encode));
    > + }
    >
    > - int lastIndex = _parse(source, 0, false);
    > + protected int _parse(String source, int initialOffset, boolean woOnly, boolean parseAsSynthetic) {
    > + // ï¿∏pï¿∏[ï¿∏Xï¿∏ï¿∏ï¿∏Jï¿∏n
    > + Matcher matcher = _tag.matcher(source);
    > + int lastIndex = initialOffset - 1;
    > + while (matcher.find()) {
    > + int start = matcher.start() + initialOffset;
    > + int end = matcher.end() + initialOffset;
    > + if (lastIndex == -1 && start > 0) {
    > + handleText(0, start, true);
    > + }
    > + else if (lastIndex != (initialOffset - 1) && lastIndex < start) {
    > + handleText(lastIndex, start, true);
    > + }
    > + String originalText = matcher.group(1);
    > + String text = originalText.trim();
    > + // ï¿∏Â≠ï¿∏ï¿∏^ï¿∏O
    > + if (!woOnly && text.startsWith("%")) {
    > + // ignore
    > + handleText(start, end, false);
    > + }
    > + else if (!woOnly && text.startsWith("?")) {
    > + handleDeclaration(start, end);
    > + }
    > + else if (!woOnly && (text.startsWith("!DOCTYPE") || text.startsWith("!doctype"))) {
    > + handleDoctype(start, end, text);
    > + }
    > + else if (!woOnly && text.startsWith("![CDATA[")) {
    > + handleCDATA(start, end, _originalSource.substring(start, end));
    > + }
    > + else if (!woOnly && (text.equalsIgnoreCase("pre") || text.toLowerCase().startsWith("pre "))) {
    > + end = handlePreTag(start, end);
    > + matcher.region(end, source.length());
    > + }
    > + else if (text.startsWith("/") && (!woOnly || WodHtmlUtils.isWOTag(text.substring(1)))) {
    > + handleCloseTag(start, end, text);
    > + }
    > + else if (text.endsWith("/") && (!woOnly || WodHtmlUtils.isWOTag(text))) {
    > + if (originalText.endsWith(" ")) {
    > + fireErrorEvent(start, end - start, "You can not have a space between the / and the > in your webobject tags.", null);
    > + }
    > + handleEmptyTag(start, end, parseAsSynthetic);
    > + }
    > + else if (!woOnly && text.startsWith("!--")) {
    > + end = _originalSource.indexOf("-->", start);
    > + if (end > 0) {
    > + end += 3;
    > + }
    > + handleComment(start, end, _originalSource.substring(start, end));
    > + matcher.region(end, source.length());
    > + }
    > + else if (!woOnly || WodHtmlUtils.isWOTag(text)) {
    > + handleStartTag(start, end, parseAsSynthetic);
    > + }
    > + lastIndex = end;
    > + }
    > + return lastIndex;
    > + }
    >
    > - if (_stack.size() > 0 && _nonCloseElements.size() > 0) {
    > - FuzzyXMLElementImpl lastElement = (FuzzyXMLElementImpl) _nonCloseElements.get(_nonCloseElements.size() - 1);
    > - String lowercaseLastElementName = lastElement.getName().toLowerCase();
    > - if (!_looseTags.contains(lowercaseLastElementName)) {
    > - fireErrorEvent(lastElement.getOffset(), lastElement.getLength(), Messages.getMessage("error.noCloseTag", lastElement.getName()), null);
    > - }
    > + /**
    > + * ï¿∏ï¿∏Æ≠ï¿∏ï¿∏Ä„nï¿∏ï¿∏ï¿∏ê≠∏XMLï¿∏\ï¿∏[ï¿∏Xï¿∏ï¿∏ï¿∏pï¿∏[ï¿∏Xï¿∏ï¿∏ï¿∏ï¿∏FuzzyXMLDocumentï¿∏Iï¿∏uï¿∏Wï¿∏Fï¿∏Nï¿∏gï¿∏ï¿∏Ô—pï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B
    > + *
    > + *..aram source
    > + * XMLï¿∏\ï¿∏[ï¿∏X
    > + *..eturn ï¿∏pï¿∏[ï¿∏Xï¿∏ï¿∏ï¿∏Ê≠ï¿∏FuzzyXMLDocumentï¿∏Iï¿∏uï¿∏Wï¿∏Fï¿∏Nï¿∏g
    > + */
    > + public FuzzyXMLDocument parse(String source) {
    > + // ï¿∏Iï¿∏ï¿∏ï¿∏Wï¿∏iï¿∏ï¿∏ï¿∏Ì∞\ï¿∏[ï¿∏Xï¿∏ï¿∏€Œï¿∏ï¿∏ï¿∏ï¿∏Ä≠ï¿∏ï¿∏ï¿∏
    > + _originalSource = source;
    > + // ï¿∏Rï¿∏ï¿∏ï¿∏ï¿∏ï¿∏gï¿∏ACDATAï¿∏ADOCTYPEï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏
    > + source = FuzzyXMLUtil.comment2space(source, true);
    > + source = FuzzyXMLUtil.escapeScript(source);
    > + source = FuzzyXMLUtil.scriptlet2space(source, true);
    > + source = FuzzyXMLUtil.cdata2space(source, true);
    > + source = FuzzyXMLUtil.doctype2space(source, true);
    > + source = FuzzyXMLUtil.processing2space(source, true);
    > + source = FuzzyXMLUtil.escapeString(source);
    >
    > - for (FuzzyXMLNode openNode : _stack) {
    > - if (openNode instanceof FuzzyXMLElementImpl) {
    > - FuzzyXMLElementImpl openElement = (FuzzyXMLElementImpl) openNode;
    > - openElement.setLength(lastIndex - openElement.getOffset());
    > - if (openElement.getParentNode() == null) {
    > - _roots.add(openElement);
    > - }
    > - else {
    > - ((FuzzyXMLElementImpl) openElement.getParentNode()).appendChildWithNoCheck(openElement);
    > - }
    > - }
    > - }
    > - }
    > + int lastIndex = _parse(source, 0, false, false);
    >
    > - // MS: Capture trailing text that isn't inside of a tag at all
    > - if (lastIndex != source.length()) {
    > - handleText(Math.max(0, lastIndex), source.length(), true);
    > - }
    > + if (_stack.size() > 0 && _nonCloseElements.size() > 0) {
    > + FuzzyXMLElementImpl lastElement = (FuzzyXMLElementImpl) _nonCloseElements.get(_nonCloseElements.size() - 1);
    > + String lowercaseLastElementName = lastElement.getName().toLowerCase();
    > + if (!_looseTags.contains(lowercaseLastElementName)) {
    > + fireErrorEvent(lastElement.getOffset(), lastElement.getLength(), Messages.getMessage("error.noCloseTag", lastElement.getName()), null);
    > + }
    >
    > - FuzzyXMLElement docElement = null;
    > - if (_roots.size() == 0) {
    > - docElement = new FuzzyXMLElementImpl(null, "document", 0, _originalSource.length(), 0);
    > - //docElement.appendChild(root);
    > - }
    > - else {
    > - FuzzyXMLNode firstRoot = _roots.get(0);
    > - FuzzyXMLNode lastRoot = _roots.get(_roots.size() - 1);
    > - docElement = new FuzzyXMLElementImpl(null, "document", firstRoot.getOffset(), lastRoot.getOffset() + lastRoot.getLength() - firstRoot.getOffset(), 0);
    > - for (FuzzyXMLNode root : _roots) {
    > - ((FuzzyXMLElementImpl) docElement).appendChildWithNoCheck(root);
    > - }
    > - }
    > - FuzzyXMLDocumentImpl doc = new FuzzyXMLDocumentImpl(docElement, _docType);
    > - doc.setHTML(_isHTML);
    > - return doc;
    > - }
    > + for (FuzzyXMLNode openNode : _stack) {
    > + if (openNode instanceof FuzzyXMLElementImpl) {
    > + FuzzyXMLElementImpl openElement = (FuzzyXMLElementImpl) openNode;
    > + openElement.setLength(lastIndex - openElement.getOffset());
    > + if (openElement.getParentNode() == null) {
    > + _roots.add(openElement);
    > + }
    > + else {
    > + ((FuzzyXMLElementImpl) openElement.getParentNode()).appendChildWithNoCheck(openElement);
    > + }
    > + }
    > + }
    > + }
    >
    > - /** CDATA∞m™[∞h≠›∂√˜ˇ≠µ≠Ü≠·™B */
    > - private void handleCDATA(int offset, int end, String text) {
    > - closeAutocloseTags();
    > - text = text.replaceFirst("<!\\[CDATA\\[", "");
    > - text = text.replaceFirst("\\]\\]>", "");
    > - FuzzyXMLCDATAImpl cdata = new FuzzyXMLCDATAImpl(getParent(), text, offset, end - offset);
    > - if (getParent() != null) {
    > - ((FuzzyXMLElement) getParent()).appendChild(cdata);
    > - }
    > - else {
    > - _roots.add(cdata);
    > - }
    > + // MS: Capture trailing text that isn't inside of a tag at all
    > + if (lastIndex != source.length()) {
    > + handleText(Math.max(0, lastIndex), source.length(), true);
    > + }
    >
    > - _stack.push(cdata);
    > - _parse(text, offset + "<![CDATA[".length(), true);
    > - FuzzyXMLNode poppedNode = _stack.pop();
    > - if (poppedNode != cdata) {
    > - _stack.push(poppedNode);
    > - }
    > - }
    > -
    > - private int handlePreTag(int offset, int end) {
    > - closeAutocloseTags();
    > - String[] content = _preCloseTagPattern.split(_originalSource.substring(end, _originalSource.length()), 2);
    > - String text = content[0];
    > - TagInfo info = parseTagContents(_originalSource.substring(offset + 1, end - 1));
    > - FuzzyXMLPreImpl preNode = new FuzzyXMLPreImpl(getParent(), text, offset, text.length());
    > - handleStartTag(preNode, info, offset, end);
    > - String preBlock = _originalSource.substring(offset, end + text.length() + 1);
    > - return _parse(preBlock, offset, true) - 1;
    > - }
    > + FuzzyXMLElement docElement = null;
    > + if (_roots.size() == 0) {
    > + docElement = new FuzzyXMLElementImpl(null, "document", 0, _originalSource.length(), 0);
    > + // docElement.appendChild(root);
    > + }
    > + else {
    > + FuzzyXMLNode firstRoot = _roots.get(0);
    > + FuzzyXMLNode lastRoot = _roots.get(_roots.size() - 1);
    > + docElement = new FuzzyXMLElementImpl(null, "document", firstRoot.getOffset(), lastRoot.getOffset() + lastRoot.getLength() - firstRoot.getOffset(), 0);
    > + for (FuzzyXMLNode root : _roots) {
    > + ((FuzzyXMLElementImpl) docElement).appendChildWithNoCheck(root);
    > + }
    > + }
    > + FuzzyXMLDocumentImpl doc = new FuzzyXMLDocumentImpl(docElement, _docType);
    > + doc.setHTML(_isHTML);
    > + return doc;
    > + }
    >
    > - /** ∞e∞L∞X∞g∞m™[∞h≠›∂√˜ˇ≠µ≠Ü≠·™B */
    > - private void handleText(int offset, int end, boolean escape) {
    > - String text = _originalSource.substring(offset, end);
    > - //System.out.println("FuzzyXMLParser.handleText: '" + text + "'");
    > - closeAutocloseTags();
    > - FuzzyXMLTextImpl textNode = new FuzzyXMLTextImpl(getParent(), FuzzyXMLUtil.decode(text, _isHTML), offset, end - offset);
    > - textNode.setEscape(escape);
    > - if (getParent() != null) {
    > - ((FuzzyXMLElement) getParent()).appendChild(textNode);
    > - }
    > - else {
    > - _roots.add(textNode);
    > - }
    > - }
    > + /** CDATAï¿∏mï¿∏[ï¿∏hï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B */
    > + private void handleCDATA(int offset, int end, String text) {
    > + closeAutocloseTags();
    > + text = text.replaceFirst("<!\\[CDATA\\[", "");
    > + text = text.replaceFirst("\\]\\]>", "");
    > + FuzzyXMLCDATAImpl cdata = new FuzzyXMLCDATAImpl(getParent(), text, offset, end - offset);
    > + if (getParent() != null) {
    > + ((FuzzyXMLElement) getParent()).appendChild(cdata);
    > + }
    > + else {
    > + _roots.add(cdata);
    > + }
    >
    > - /** XML∆é‘≤™i∂√˜ˇˆ∏˜ß™j≠›∂√˜ˇ≠µ≠Ü≠·™B */
    > - private void handleDeclaration(int offset, int end) {
    > - closeAutocloseTags();
    > - String text = _originalSource.substring(offset, end);
    > - text = text.replaceFirst("^<\\?", "");
    > - text = text.replaceFirst("\\?>$", "");
    > - text = text.trim();
    > + _stack.push(cdata);
    > + _parse(text, offset + "<![CDATA[".length(), true, true);
    > + FuzzyXMLNode poppedNode = _stack.pop();
    > + if (poppedNode != cdata) {
    > + _stack.push(poppedNode);
    > + }
    > + }
    >
    > - String[] dim = text.split("[ \r\n\t]+");
    > - String name = dim[0];
    > - String data = text.substring(name.length()).trim();
    > + private int handlePreTag(int offset, int end) {
    > + closeAutocloseTags();
    > + String[] content = _preCloseTagPattern.split(_originalSource.substring(end, _originalSource.length()), 2);
    > + String text = content[0];
    > + TagInfo info = parseTagContents(_originalSource.substring(offset + 1, end - 1));
    > + FuzzyXMLPreImpl preNode = new FuzzyXMLPreImpl(getParent(), text, offset, text.length());
    > + handleStartTag(preNode, info, offset, end);
    > + String preBlock = _originalSource.substring(offset, end + text.length() + 1);
    > + return _parse(preBlock, offset, true, false) - 1;
    > + }
    >
    > - FuzzyXMLProcessingInstructionImpl pi = new FuzzyXMLProcessingInstructionImpl(null, name, data, offset, end - offset);
    > - if (getParent() != null) {
    > - // ˜]‘v≠È‰ª≠›Ÿí≠é
    > - ((FuzzyXMLElement) getParent()).appendChild(pi);
    > - }
    > - else {
    > - _roots.add(pi);
    > - }
    > + /** ï¿∏eï¿∏Lï¿∏Xï¿∏gï¿∏mï¿∏[ï¿∏hï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B */
    > + private void handleText(int offset, int end, boolean escape) {
    > + String text = _originalSource.substring(offset, end);
    > + // System.out.println("FuzzyXMLParser.handleText: '" + text + "'");
    > + closeAutocloseTags();
    > + FuzzyXMLTextImpl textNode = new FuzzyXMLTextImpl(getParent(), FuzzyXMLUtil.decode(text, _isHTML), offset, end - offset);
    > + textNode.setEscape(escape);
    > + if (getParent() != null) {
    > + ((FuzzyXMLElement) getParent()).appendChild(textNode);
    > + }
    > + else {
    > + _roots.add(textNode);
    > + }
    > + }
    >
    > - // XML should not have autoclosing tags
    > - if (name.startsWith("xml")) {
    > - _autocloseTags.clear();
    > - }
    > - }
    > + /** XMLï¿∏é‘≤ï¿∏iï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ß™jï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B */
    > + private void handleDeclaration(int offset, int end) {
    > + closeAutocloseTags();
    > + String text = _originalSource.substring(offset, end);
    > + text = text.replaceFirst("^<\\?", "");
    > + text = text.replaceFirst("\\?>$", "");
    > + text = text.trim();
    >
    > - /** DOCTYPE∆é‘≤≠›∂√˜ˇ≠µ≠Ü≠·™B */
    > - private void handleDoctype(int offset, int end, String text) {
    > - closeAutocloseTags();
    > - if (_docType == null) {
    > - String name = "";
    > - String publicId = "";
    > - String systemId = "";
    > - String internalSubset = "";
    > -
    > - text = _originalSource.substring(offset, end);
    > - Matcher matcher = _docTypeName.matcher(text);
    > - if (matcher.find()) {
    > - name = matcher.group(1);
    > - }
    > - matcher = _docTypePublic.matcher(text);
    > - if (matcher.find()) {
    > - publicId = matcher.group(1);
    > - systemId = matcher.group(2);
    > - }
    > - else {
    > - matcher = _docTypeSystem.matcher(text);
    > - if (matcher.find()) {
    > - systemId = matcher.group(1);
    > - }
    > - }
    > - matcher = _docTypeSubset.matcher(text);
    > - if (matcher.find()) {
    > - internalSubset = matcher.group(1);
    > - }
    > - _docType = new FuzzyXMLDocTypeImpl(null, name, publicId, systemId, internalSubset, offset, end - offset);
    > - }
    > - }
    > + String[] dim = text.split("[ \r\n\t]+");
    > + String name = dim[0];
    > + String data = text.substring(name.length()).trim();
    >
    > - private void closeAutocloseTags() {
    > - if (_stack.size() > 0) {
    > - FuzzyXMLElementImpl lastOpenElement = (FuzzyXMLElementImpl)_stack.peek();
    > - String name = lastOpenElement.getName().toLowerCase();
    > - if (_autocloseTags.contains(name) || lastOpenElement.isForbiddenFromHavingChildren()) {
    > - int openTagEndOffset = lastOpenElement.getOffset() + lastOpenElement.getOpenTagLength();
    > - handleCloseTag(openTagEndOffset, openTagEndOffset, "/" + name, false);
    > - }
    > - }
    > - }
    > -
    > - /** Â≠¶∞^∞O≠›∂√˜ˇ≠µ≠Ü≠·™B */
    > - private void handleCloseTag(int offset, int end, String text) {
    > - handleCloseTag(offset, end, text, true);
    > - }
    > + FuzzyXMLProcessingInstructionImpl pi = new FuzzyXMLProcessingInstructionImpl(null, name, data, offset, end - offset);
    > + if (getParent() != null) {
    > + // ï¿∏]ï¿∏vï¿∏Èï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏
    > + ((FuzzyXMLElement) getParent()).appendChild(pi);
    > + }
    > + else {
    > + _roots.add(pi);
    > + }
    >
    > - private void handleCloseTag(int offset, int end, String text, boolean showMismatchError) {
    > - if (_stack.size() == 0) {
    > - return;
    > - }
    > - String tagName = text.substring(1).trim();
    > + // XML should not have autoclosing tags
    > + if (name.startsWith("xml")) {
    > + _autocloseTags.clear();
    > + }
    > + }
    >
    > - // MS: Chuck does close tags like </webobject closing something else>
    > - int chuckIndex = tagName.indexOf(' ');
    > - if (chuckIndex != -1) {
    > - String chuckWord = tagName.substring(0, chuckIndex);
    > - if (WodHtmlUtils.isWOTag(chuckWord)) {
    > - tagName = chuckWord;
    > - }
    > - }
    > + /** DOCTYPEï¿∏é‘≤ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B */
    > + private void handleDoctype(int offset, int end, String text) {
    > + closeAutocloseTags();
    > + if (_docType == null) {
    > + String name = "";
    > + String publicId = "";
    > + String systemId = "";
    > + String internalSubset = "";
    >
    > - FuzzyXMLElementImpl lastOpenElement = (FuzzyXMLElementImpl) _stack.pop();
    > - String lowercaseLastOpenElementName = lastOpenElement.getName().toLowerCase();
    > - String lowercaseCloseTagName = tagName.toLowerCase();
    > + text = _originalSource.substring(offset, end);
    > + Matcher matcher = _docTypeName.matcher(text);
    > + if (matcher.find()) {
    > + name = matcher.group(1);
    > + }
    > + matcher = _docTypePublic.matcher(text);
    > + if (matcher.find()) {
    > + publicId = matcher.group(1);
    > + systemId = matcher.group(2);
    > + }
    > + else {
    > + matcher = _docTypeSystem.matcher(text);
    > + if (matcher.find()) {
    > + systemId = matcher.group(1);
    > + }
    > + }
    > + matcher = _docTypeSubset.matcher(text);
    > + if (matcher.find()) {
    > + internalSubset = matcher.group(1);
    > + }
    > + _docType = new FuzzyXMLDocTypeImpl(null, name, publicId, systemId, internalSubset, offset, end - offset);
    > + }
    > + }
    >
    > - boolean closeTagMatches = lowercaseLastOpenElementName.equals(lowercaseCloseTagName);
    > - // System.out.println("FuzzyXMLParser.handleCloseTag: lastOpen = " +
    > - // lowercaseLastOpenElementName + ", close = " + lowercaseCloseTagName);
    > - if (!closeTagMatches) {
    > - closeAutocloseTags();
    > + private void closeAutocloseTags() {
    > + if (_stack.size() > 0) {
    > + FuzzyXMLElementImpl lastOpenElement = (FuzzyXMLElementImpl) _stack.peek();
    > + String name = lastOpenElement.getName().toLowerCase();
    > + if (_autocloseTags.contains(name) || lastOpenElement.isForbiddenFromHavingChildren()) {
    > + int openTagEndOffset = lastOpenElement.getOffset() + lastOpenElement.getOpenTagLength();
    > + handleCloseTag(openTagEndOffset, openTagEndOffset, "/" + name, false);
    > + }
    > + }
    > + }
    >
    > - // Allow </wo> to close </wo:if>
    > - boolean looseNamespace = false;
    > - int colonIndex = lowercaseLastOpenElementName.indexOf(':');
    > - if (colonIndex != -1) {
    > - String elementNamespace = lowercaseLastOpenElementName.substring(0, colonIndex);
    > - if (lowercaseCloseTagName.equals(elementNamespace) && _looseNamespaces.contains(elementNamespace)) {
    > - tagName = lastOpenElement.getName();
    > - lowercaseCloseTagName = lowercaseLastOpenElementName;
    > - looseNamespace = true;
    > - }
    > - }
    > + /** ï¿∏Â≠ï¿∏ï¿∏^ï¿∏Oï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B */
    > + private void handleCloseTag(int offset, int end, String text) {
    > + handleCloseTag(offset, end, text, true);
    > + }
    >
    > - if (!looseNamespace) {
    > - boolean looseTag = false;
    > - if (_looseTags.contains(lowercaseLastOpenElementName)) {
    > - looseTag = true;
    > - }
    > + private void handleCloseTag(int offset, int end, String text, boolean showMismatchError) {
    > + if (_stack.size() == 0) {
    > + return;
    > + }
    > + String tagName = text.substring(1).trim();
    >
    > - if (looseTag) {
    > - while (lowercaseLastOpenElementName != null && !lowercaseLastOpenElementName.equals(lowercaseCloseTagName)
    > - && _looseTags.contains(lowercaseLastOpenElementName)) {
    > - int lastOpenElementEndOffset = end;
    > - // int lastOpenElementEndOffset = lastOpenElement.getOffset() +
    > - // lastOpenElement.getLength();
    > - _stack.push(lastOpenElement);
    > - handleCloseTag(lastOpenElementEndOffset, lastOpenElementEndOffset, "/" + lastOpenElement.getName(), false);
    > + // MS: Chuck does close tags like </webobject closing something else>
    > + int chuckIndex = tagName.indexOf(' ');
    > + if (chuckIndex != -1) {
    > + String chuckWord = tagName.substring(0, chuckIndex);
    > + if (WodHtmlUtils.isWOTag(chuckWord)) {
    > + tagName = chuckWord;
    > + }
    > + }
    >
    > - /*
    > - FuzzyXMLElement looseElement = lastOpenElement;
    > - FuzzyXMLNode[] looseElementChildren = lastOpenElement.getChildren();
    > - FuzzyXMLElement looseElementParent = (FuzzyXMLElement) lastOpenElement.getParentNode();
    > - for (FuzzyXMLNode looseElementChild : looseElementChildren) {
    > - looseElement.removeChild(looseElementChild);
    > - looseElementParent.insertAfter(looseElementChild, looseElement);
    > - //((AbstractFuzzyXMLNode) looseElementChild).setOffset(looseElementChild.getOffset() + 1);
    > - }
    > - */
    > + FuzzyXMLElementImpl lastOpenElement = (FuzzyXMLElementImpl) _stack.pop();
    > + String lowercaseLastOpenElementName = lastOpenElement.getName().toLowerCase();
    > + String lowercaseCloseTagName = tagName.toLowerCase();
    >
    > - if (_stack.size() == 0) {
    > - lastOpenElement = null;
    > - lowercaseLastOpenElementName = null;
    > - }
    > - else {
    > - lastOpenElement = (FuzzyXMLElementImpl) _stack.pop();
    > - lowercaseLastOpenElementName = lastOpenElement.getName().toLowerCase();
    > - }
    > - }
    > - }
    > - else {
    > - FuzzyXMLElement matchingOpenElement = null;
    > - for (FuzzyXMLElement nonCloseElement : _nonCloseElements) {
    > - if (nonCloseElement.getName().equalsIgnoreCase(lowercaseCloseTagName)) {
    > - matchingOpenElement = nonCloseElement;
    > - }
    > - }
    > - if (matchingOpenElement == null) {
    > - if (showMismatchError) {
    > - fireErrorEvent(offset, end - offset, Messages.getMessage("error.noStartTag", tagName), null);
    > - }
    > - _stack.push(lastOpenElement);
    > - return;
    > - }
    > + boolean closeTagMatches = lowercaseLastOpenElementName.equals(lowercaseCloseTagName);
    > + // System.out.println("FuzzyXMLParser.handleCloseTag: lastOpen = " +
    > + // lowercaseLastOpenElementName + ", close = " + lowercaseCloseTagName);
    > + if (!closeTagMatches) {
    > + closeAutocloseTags();
    >
    > - //System.out.println("FuzzyXMLParser.handleCloseTag: mismatched close " + lastOpenElement.getName());
    > - if (showMismatchError) {
    > - //fireErrorEvent(offset, end - offset, "Found </" + tagName + "> before </" + lastOpenElement.getName() + ">", null);
    > - fireErrorEvent(lastOpenElement.getOffset(), lastOpenElement.getLength(), "Missing </" + lastOpenElement.getName() + "> tag", null);
    > - }
    > - _stack.push(lastOpenElement);
    > - handleCloseTag(offset, offset, "/" + lastOpenElement.getName(), false);
    > - lastOpenElement = (FuzzyXMLElementImpl) _stack.pop();
    > - lowercaseLastOpenElementName = lastOpenElement.getName().toLowerCase();
    > - }
    > - /*
    > - boolean matchesOpenElement = false;
    > - if (looseTag) {
    > - for (FuzzyXMLElement nonCloseElement : nonCloseElements) {
    > - if (nonCloseElement.getName().equalsIgnoreCase(lowercaseCloseTagName)) {
    > - matchesOpenElement = true;
    > - }
    > - }
    > - if (matchesOpenElement) {
    > - nonCloseElements.remove(lastOpenElement);
    > - }
    > - }
    > + // Allow </wo> to close </wo:if>
    > + boolean looseNamespace = false;
    > + int colonIndex = lowercaseLastOpenElementName.indexOf(':');
    > + if (colonIndex != -1) {
    > + String elementNamespace = lowercaseLastOpenElementName.substring(0, colonIndex);
    > + if (lowercaseCloseTagName.equals(elementNamespace) && _looseNamespaces.contains(elementNamespace)) {
    > + tagName = lastOpenElement.getName();
    > + lowercaseCloseTagName = lowercaseLastOpenElementName;
    > + looseNamespace = true;
    > + }
    > + }
    >
    > - if (lastOpenElement.getParentNode() != null) {
    > - ((FuzzyXMLElementImpl) lastOpenElement.getParentNode()).appendChildWithNoCheck(lastOpenElement);
    > - FuzzyXMLNode[] nodes = lastOpenElement.getChildren();
    > - for (int i = 0; i < nodes.length; i++) {
    > - ((AbstractFuzzyXMLNode) nodes[i]).setParentNode(lastOpenElement.getParentNode());
    > - lastOpenElement.removeChild(nodes[i]);
    > - ((FuzzyXMLElementImpl) lastOpenElement.getParentNode()).appendChildWithNoCheck(nodes[i]);
    > - }
    > - }
    > - else {
    > - //System.out.println(tagName + "≠Ì…J⁄n∞^∞O≠ª‘©≠Â≠©≠è≠Ü≠’≠ñ™B");
    > - fireErrorEvent(offset, end - offset, Messages.getMessage("error.noStartTag", tagName), null);
    > - }
    > - if (matchesOpenElement) {
    > - handleCloseTag(offset, end, text);
    > - }
    > - // stack.push(element);
    > - return;
    > - */
    > - }
    > - }
    > + if (!looseNamespace) {
    > + boolean looseTag = false;
    > + if (_looseTags.contains(lowercaseLastOpenElementName)) {
    > + looseTag = true;
    > + }
    >
    > - if (lastOpenElement != null) {
    > - // —ó∞^∞O≠Ì∂êŸΩ≠Í—ó≠Ì∞e∞L∞X∞g∞m™[∞h≠›‚Ç≈Á≠µ≠Ä≠¨≠–
    > - if (lastOpenElement.getChildren().length == 0) {
    > - // MS: Hopefully this doesn't break things ... Sure wish I could read
    > - // Japanese to know what the original author said about this :)
    > - //lastOpenElement.appendChild(new FuzzyXMLTextImpl(getParent(), "", offset, 0));
    > - }
    > - lastOpenElement.setLength(end - lastOpenElement.getOffset());
    > - if (closeTagMatches) {
    > - lastOpenElement.setCloseTagOffset(offset);
    > - lastOpenElement.setCloseTagLength(end - offset - 2);
    > - lastOpenElement.setCloseNameOffset(text.indexOf(tagName));
    > - }
    > - _nonCloseElements.remove(lastOpenElement);
    > - if (lastOpenElement.getParentNode() == null) {
    > - _roots.add(lastOpenElement);
    > - for (FuzzyXMLElement error : _nonCloseElements) {
    > - //System.out.println(error.getName() + "≠ÍÂ≠¶≠Ä≠¢≠Ü≠’≠ñ™B");
    > - if (showMismatchError) {
    > - fireErrorEvent(error.getOffset(), error.getLength(), Messages.getMessage("error.noCloseTag", error.getName()), error);
    > - }
    > - }
    > - }
    > - else {
    > - ((FuzzyXMLElementImpl) lastOpenElement.getParentNode()).appendChildWithNoCheck(lastOpenElement);
    > - }
    > - }
    > - }
    > + if (looseTag) {
    > + while (lowercaseLastOpenElementName != null && !lowercaseLastOpenElementName.equals(lowercaseCloseTagName) && _looseTags.contains(lowercaseLastOpenElementName)) {
    > + int lastOpenElementEndOffset = end;
    > + // int lastOpenElementEndOffset = lastOpenElement.getOffset() +
    > + // lastOpenElement.getLength();
    > + _stack.push(lastOpenElement);
    > + handleCloseTag(lastOpenElementEndOffset, lastOpenElementEndOffset, "/" + lastOpenElement.getName(), false);
    >
    > - private void checkAttributeValue(FuzzyXMLAttribute attr) {
    > - String str = attr.getRawValue();
    > - if (str != null) {
    > - str = str.replaceAll("&[^&; \"]+;", " ");
    > - Matcher invalidStringMatcher = _invalidStringPattern.matcher(str);
    > - while (invalidStringMatcher.find()) {
    > - String invalidPart = invalidStringMatcher.group();
    > - fireErrorEvent(attr.getParentNode().getOffset() + attr.getValueDataOffset() + 1, attr.getValueDataLength(), "The character '" + invalidPart + "' must be escaped.", attr);
    > - }
    > - }
    > - }
    > + /*
    > + * FuzzyXMLElement looseElement = lastOpenElement;
    > + * FuzzyXMLNode[] looseElementChildren =
    > + * lastOpenElement.getChildren();
    > + * FuzzyXMLElement looseElementParent = (FuzzyXMLElement)
    > + * lastOpenElement.getParentNode();
    > + * for (FuzzyXMLNode looseElementChild : looseElementChildren) {
    > + * looseElement.removeChild(looseElementChild);
    > + * looseElementParent.insertAfter(looseElementChild, looseElement);
    > + * //((AbstractFuzzyXMLNode)
    > + * looseElementChild).setOffset(looseElementChild.getOffset() + 1);
    > + * }
    > + */
    >
    > - /** —ó∞^∞O≠›∂√˜ˇ≠µ≠Ü≠·™B */
    > - private void handleEmptyTag(int offset, int end) {
    > - closeAutocloseTags();
    > - TagInfo info = parseTagContents(_originalSource.substring(offset + 1, end - 1));
    > - FuzzyXMLNode parent = getParent();
    > - FuzzyXMLElementImpl element = new FuzzyXMLElementImpl(parent, info.name, offset, end - offset, info.nameOffset);
    > - if (parent == null) {
    > - _roots.add(element);
    > - }
    > - else {
    > - ((FuzzyXMLElement) parent).appendChild(element);
    > - }
    > - // Œ®∆«≠›‚Ç≈Á
    > - AttrInfo[] attrs = info.getAttrs();
    > - for (int i = 0; i < attrs.length; i++) {
    > - FuzzyXMLAttributeImpl attr = createFuzzyXMLAttribute(element, offset, attrs[i]);
    > - element.appendChild(attr);
    > - }
    > + if (_stack.size() == 0) {
    > + lastOpenElement = null;
    > + lowercaseLastOpenElementName = null;
    > + }
    > + else {
    > + lastOpenElement = (FuzzyXMLElementImpl) _stack.pop();
    > + lowercaseLastOpenElementName = lastOpenElement.getName().toLowerCase();
    > + }
    > + }
    > + }
    > + else {
    > + FuzzyXMLElement matchingOpenElement = null;
    > + for (FuzzyXMLElement nonCloseElement : _nonCloseElements) {
    > + if (nonCloseElement.getName().equalsIgnoreCase(lowercaseCloseTagName)) {
    > + matchingOpenElement = nonCloseElement;
    > + }
    > + }
    > + if (matchingOpenElement == null) {
    > + if (showMismatchError) {
    > + fireErrorEvent(offset, end - offset, Messages.getMessage("error.noStartTag", tagName), null);
    > + }
    > + _stack.push(lastOpenElement);
    > + return;
    > + }
    >
    > - FuzzyXMLElement branchNode = new FuzzyXMLElementImpl(element, "", 0, 0, 0) {
    > - ..verride
    > - public void toXMLString(RenderContext renderContext, StringBuffer xmlBuffer) {
    > - }
    > - };
    > + // System.out.println("FuzzyXMLParser.handleCloseTag: mismatched close "
    > + // + lastOpenElement.getName());
    > + if (showMismatchError) {
    > + // fireErrorEvent(offset, end - offset, "Found </" + tagName +
    > + // "> before </" + lastOpenElement.getName() + ">", null);
    > + fireErrorEvent(lastOpenElement.getOffset(), lastOpenElement.getLength(), "Missing </" + lastOpenElement.getName() + "> tag", null);
    > + }
    > + _stack.push(lastOpenElement);
    > + handleCloseTag(offset, offset, "/" + lastOpenElement.getName(), false);
    > + lastOpenElement = (FuzzyXMLElementImpl) _stack.pop();
    > + lowercaseLastOpenElementName = lastOpenElement.getName().toLowerCase();
    > + }
    > + /*
    > + * boolean matchesOpenElement = false;
    > + * if (looseTag) {
    > + * for (FuzzyXMLElement nonCloseElement : nonCloseElements) {
    > + * if
    > + * (nonCloseElement.getName().equalsIgnoreCase(lowercaseCloseTagName)) {
    > + * matchesOpenElement = true;
    > + * }
    > + * }
    > + * if (matchesOpenElement) {
    > + * nonCloseElements.remove(lastOpenElement);
    > + * }
    > + * }
    > + *
    > + * if (lastOpenElement.getParentNode() != null) {
    > + * ((FuzzyXMLElementImpl)
    > + * lastOpenElement.getParentNode()).appendChildWithNoCheck
    > + * (lastOpenElement);
    > + * FuzzyXMLNode[] nodes = lastOpenElement.getChildren();
    > + * for (int i = 0; i < nodes.length; i++) {
    > + * ((AbstractFuzzyXMLNode)
    > + * nodes[i]).setParentNode(lastOpenElement.getParentNode());
    > + * lastOpenElement.removeChild(nodes[i]);
    > + * ((FuzzyXMLElementImpl)
    > + * lastOpenElement.getParentNode()).appendChildWithNoCheck(nodes[i]);
    > + * }
    > + * }
    > + * else {
    > + * //System.out.println(tagName + "ï¿∏Ì…Jï¿∏nï¿∏^ï¿∏Oï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Â≠ï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏ï¿∏B");
    > + * fireErrorEvent(offset, end - offset,
    > + * Messages.getMessage("error.noStartTag", tagName), null);
    > + * }
    > + * if (matchesOpenElement) {
    > + * handleCloseTag(offset, end, text);
    > + * }
    > + * // stack.push(element);
    > + * return;
    > + */
    > + }
    > + }
    >
    > - if (!_wellFormedRequired) {
    > - element.appendChild(branchNode);
    > - }
    > + if (lastOpenElement != null) {
    > + // ï¿∏ï¿∏^ï¿∏Oï¿∏Ì∂êŸΩï¿∏Í—ï¿∏Ì∞eï¿∏Lï¿∏Xï¿∏gï¿∏mï¿∏[ï¿∏hï¿∏ï¿∏Ç≈ï¿∏ï¿∏ï¿∏ï¿∏Ä≠ï¿∏ï¿∏ï¿∏
    > + if (lastOpenElement.getChildren().length == 0) {
    > + // MS: Hopefully this doesn't break things ... Sure wish I could read
    > + // Japanese to know what the original author said about this :)
    > + // lastOpenElement.appendChild(new FuzzyXMLTextImpl(getParent(), "",
    > + // offset, 0));
    > + }
    > + lastOpenElement.setLength(end - lastOpenElement.getOffset());
    > + if (closeTagMatches) {
    > + lastOpenElement.setCloseTagOffset(offset);
    > + lastOpenElement.setCloseTagLength(end - offset - 2);
    > + lastOpenElement.setCloseNameOffset(text.indexOf(tagName));
    > + }
    > + _nonCloseElements.remove(lastOpenElement);
    > + if (lastOpenElement.getParentNode() == null) {
    > + _roots.add(lastOpenElement);
    > + for (FuzzyXMLElement error : _nonCloseElements) {
    > + // System.out.println(error.getName() + "ï¿∏ÍÂ≠ï¿∏ï¿∏Ä≠ï¿∏ï¿∏Ü≠ï¿∏ï¿∏ï¿∏B");
    > + if (showMismatchError) {
    > + fireErrorEvent(error.getOffset(), error.getLength(), Messages.getMessage("error.noCloseTag", error.getName()), error);
    > + }
    > + }
    > + }
    > + else {
    > + ((FuzzyXMLElementImpl) lastOpenElement.getParentNode()).appendChildWithNoCheck(lastOpenElement);
    > + }
    > + }
    > + }
    >
    > - for (FuzzyXMLAttribute attr : element.getAttributes()) {
    > - if (!_wellFormedRequired) {
    > - _stack.push(branchNode);
    > - _parse(attr.getValue(), element.getOffset() + attr.getValueDataOffset() + 1, true);
    > - FuzzyXMLNode poppedNode = _stack.pop();
    > - if (poppedNode != branchNode) {
    > - _stack.push(poppedNode);
    > - }
    > - }
    > - else {
    > - checkAttributeValue(attr);
    > - }
    > - }
    > + private void checkAttributeValue(FuzzyXMLAttribute attr) {
    > + String str = attr.getRawValue();
    > + if (str != null) {
    > + // MS: Don't consider nested tags for escaping ...
    > + if (attr.hasNestedTag()) {
    > + str = str.replaceAll("<[^>]*>", "");
    > + }
    >
    > - if (!_wellFormedRequired && !branchNode.hasChildren()) {
    > - element.removeChild(branchNode);
    > - }
    > + str = str.replaceAll("&[^&; \"]+;", " ");
    > + Matcher invalidStringMatcher = _invalidStringPattern.matcher(str);
    > + while (invalidStringMatcher.find()) {
    > + String invalidPart = invalidStringMatcher.group();
    > + fireErrorEvent(attr.getParentNode().getOffset() + attr.getValueDataOffset() + 1, attr.getValueDataLength(), "The character '" + invalidPart + "' must be escaped.", attr);
    > + }
    >
    > - }
    > + }
    > + }
    >
    > - /** ∞R∞™∞„∞g≠›∂√˜ˇ≠µ≠Ü≠·™B */
    > - private void handleComment(int offset, int end, String text) {
    > - closeAutocloseTags();
    > - FuzzyXMLNode parent = getParent();
    > - FuzzyXMLCommentImpl comment = new FuzzyXMLCommentImpl(parent, text, offset, end - offset);
    > + /** ï¿∏ï¿∏^ï¿∏Oï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B */
    > + private void handleEmptyTag(int offset, int end, boolean synthetic) {
    > + closeAutocloseTags();
    > + TagInfo info = parseTagContents(_originalSource.substring(offset + 1, end - 1));
    > + FuzzyXMLNode parent = getParent();
    > + FuzzyXMLElementImpl element = new FuzzyXMLElementImpl(parent, info.name, offset, end - offset, info.nameOffset);
    > + if (parent == null) {
    > + _roots.add(element);
    > + }
    > + else {
    > + ((FuzzyXMLElement) parent).appendChild(element);
    > + }
    > + // ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Ç≈ï¿∏
    > + AttrInfo[] attrs = info.getAttrs();
    > + for (int i = 0; i < attrs.length; i++) {
    > + FuzzyXMLAttributeImpl attr = createFuzzyXMLAttribute(element, offset, attrs[i]);
    > + element.appendChild(attr);
    > + }
    >
    > - if (parent == null) {
    > - _roots.add(comment);
    > - }
    > - else {
    > - ((FuzzyXMLElement) parent).appendChild(comment);
    > - }
    > -
    > - _stack.push(comment);
    > - _parse(text.replaceFirst("<[^>]+-->$", ""), offset, true);
    > - FuzzyXMLNode poppedNode = _stack.pop();
    > - if (poppedNode != comment) {
    > - _stack.push(poppedNode);
    > - }
    > - }
    > + element.setSynthetic(synthetic);
    >
    > - /** …J⁄n∞^∞O≠›∂√˜ˇ≠µ≠Ü≠·™B */
    > - private void handleStartTag(int offset, int end) {
    > - closeAutocloseTags();
    > - String tagContents = _originalSource.substring(offset, end);
    > - // MS: If you're in the middle of typing, offset + 1 to end - 1 can put
    > - // you in an invalid state (for instance, if you just type "<" that will
    > - // overlap.
    > - if (tagContents.startsWith("<")) {
    > - tagContents = tagContents.substring(1);
    > - }
    > - if (tagContents.endsWith(">")) {
    > - tagContents = tagContents.substring(0, tagContents.length() - 1);
    > - }
    > - TagInfo info = parseTagContents(tagContents);
    > - // System.out.println("FuzzyXMLParser.handleStartTag: open " + info.name);
    > - FuzzyXMLElement element;
    > - if (info.name.equalsIgnoreCase("script")) {
    > - element = new FuzzyXMLScriptImpl(getParent(), info.name, offset, end - offset, info.nameOffset);
    > - }
    > - else if (info.name.equalsIgnoreCase("style")) {
    > - element = new FuzzyXMLStyleImpl(getParent(), info.name, offset, end - offset, info.nameOffset);
    > - }
    > - else {
    > - element = new FuzzyXMLElementImpl(getParent(), info.name, offset, end - offset, info.nameOffset);
    > - }
    > - handleStartTag(element, info, offset, end);
    > - }
    > + checkElement(element);
    > + }
    >
    > - protected FuzzyXMLAttributeImpl createFuzzyXMLAttribute(FuzzyXMLElement element, int offset, AttrInfo attrInfo) {
    > - String namespace = null;
    > - String name = attrInfo.name;
    > - if (name != null) {
    > - int colonIndex = name.indexOf(':');
    > - if (colonIndex != -1) {
    > - namespace = name.substring(0, colonIndex);
    > - name = name.substring(colonIndex + 1);
    > - }
    > - }
    > - if (_wellFormedRequired) {
    > - FuzzyXMLAttributeImpl attr = new FuzzyXMLAttributeImpl(element, namespace, name, FuzzyXMLUtil.decode(attrInfo.value, false), attrInfo.rawValue, attrInfo.offset + offset, attrInfo.end - attrInfo.offset + 1, attrInfo.valueOffset);
    > - attr.setQuoteCharacter(attrInfo.quote);
    > - return attr;
    > - }
    > - FuzzyXMLAttributeImpl attr = new FuzzyXMLAttributeImpl(element, namespace, name, attrInfo.value, attrInfo.rawValue, attrInfo.offset + offset, attrInfo.end - attrInfo.offset + 1, attrInfo.valueOffset);
    > - attr.setQuoteCharacter(attrInfo.quote);
    > - if (attrInfo.value.indexOf('"') >= 0 || attrInfo.value.indexOf('\'') >= 0 || attrInfo.value.indexOf('<') >= 0
    > - || attrInfo.value.indexOf('>') >= 0 || attrInfo.value.indexOf('&') >= 0) {
    > - attr.setEscape(false);
    > - }
    > - return attr;
    > - }
    > -
    > - /** …J⁄n∞^∞O≠›∂√˜ˇ≠µ≠Ü≠·™B */
    > - private void handleStartTag(FuzzyXMLElement element, TagInfo info, int offset, int end) {
    > - // Œ®∆«≠›‚Ç≈Á
    > - AttrInfo[] attrs = info.getAttrs();
    > - for (int i = 0; i < attrs.length; i++) {
    > - // // ˆπŒO—ó…Ô≠Ì∞T∞|™[∞g
    > - // if(attrs[i].name.startsWith("xmlns")){
    > - // String uri = attrs[i].value;
    > - // String prefix = null;
    > - // String[] dim = attrs[i].name.split(":");
    > - // if(dim.length > 1){
    > - // prefix = dim[1];
    > - // }
    > - // element.addNamespaceURI(prefix,uri);
    > - // }
    > - element.appendChild(createFuzzyXMLAttribute(element, offset, attrs[i]));
    > - }
    > - _stack.push(element);
    > - _nonCloseElements.add(element);
    > + protected void checkElement(FuzzyXMLElement element) {
    > + for (FuzzyXMLAttribute attr : element.getAttributes()) {
    > + if (!_wellFormedRequired) {
    > + if (!WodHtmlUtils.isWOTag((FuzzyXMLElement) attr.getParentNode())) {
    > + _stack.push(attr.getParentNode());
    > + _parse(attr.getValue(), element.getOffset() + attr.getValueDataOffset() + 1, true, true);
    > + FuzzyXMLNode poppedNode = _stack.pop();
    > + if (poppedNode != attr.getParentNode()) {
    > + _stack.push(poppedNode);
    > + }
    > + }
    > + }
    > + else {
    > + checkAttributeValue(attr);
    > + }
    > + }
    > + }
    >
    > - FuzzyXMLElement branchNode = new FuzzyXMLElementImpl(element, "", 0, 0, 0) {
    > - ..verride
    > - public void toXMLString(RenderContext renderContext, StringBuffer xmlBuffer) {
    > - }
    > - };
    > + /** ï¿∏Rï¿∏ï¿∏ï¿∏ï¿∏ï¿∏gï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B */
    > + private void handleComment(int offset, int end, String text) {
    > + closeAutocloseTags();
    > + FuzzyXMLNode parent = getParent();
    > + FuzzyXMLCommentImpl comment = new FuzzyXMLCommentImpl(parent, text, offset, end - offset);
    >
    > - if (!_wellFormedRequired) {
    > - element.appendChild(branchNode);
    > - }
    > + if (parent == null) {
    > + _roots.add(comment);
    > + }
    > + else {
    > + ((FuzzyXMLElement) parent).appendChild(comment);
    > + }
    >
    > - for (FuzzyXMLAttribute attr : element.getAttributes()) {
    > - if (!_wellFormedRequired) {
    > - _stack.push(branchNode);
    > - _parse(attr.getValue(), element.getOffset() + attr.getValueDataOffset() + 1, true);
    > - FuzzyXMLNode poppedNode = _stack.pop();
    > - if (poppedNode != branchNode) {
    > - _stack.push(poppedNode);
    > - }
    > - }
    > - else {
    > - checkAttributeValue(attr);
    > - }
    > - }
    > + _stack.push(comment);
    > + _parse(text.replaceFirst("<[^>]+-->$", ""), offset, true, true);
    > + FuzzyXMLNode poppedNode = _stack.pop();
    > + if (poppedNode != comment) {
    > + _stack.push(poppedNode);
    > + }
    > + }
    >
    > - if (!_wellFormedRequired && !branchNode.hasChildren()) {
    > - element.removeChild(branchNode);
    > - }
    > - }
    > + /** ï¿∏Jï¿∏nï¿∏^ï¿∏Oï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B */
    > + private void handleStartTag(int offset, int end, boolean synthetic) {
    > + closeAutocloseTags();
    > + String tagContents = _originalSource.substring(offset, end);
    > + // MS: If you're in the middle of typing, offset + 1 to end - 1 can put
    > + // you in an invalid state (for instance, if you just type "<" that will
    > + // overlap.
    > + if (tagContents.startsWith("<")) {
    > + tagContents = tagContents.substring(1);
    > + }
    > + if (tagContents.endsWith(">")) {
    > + tagContents = tagContents.substring(0, tagContents.length() - 1);
    > + }
    > + TagInfo info = parseTagContents(tagContents);
    > + // System.out.println("FuzzyXMLParser.handleStartTag: open " + info.name);
    > + FuzzyXMLElement element;
    > + if (info.name.equalsIgnoreCase("script")) {
    > + element = new FuzzyXMLScriptImpl(getParent(), info.name, offset, end - offset, info.nameOffset);
    > + }
    > + else if (info.name.equalsIgnoreCase("style")) {
    > + element = new FuzzyXMLStyleImpl(getParent(), info.name, offset, end - offset, info.nameOffset);
    > + }
    > + else {
    > + element = new FuzzyXMLElementImpl(getParent(), info.name, offset, end - offset, info.nameOffset);
    > + }
    > + handleStartTag(element, info, offset, end);
    > + element.setSynthetic(synthetic);
    > + }
    >
    > - /** ∞X∞^∞b∞N≠ÌŸÅ‘ã≠̘vŒf≠›⁄æ„≤≠µ≠Ü≠·(∞X∞^∞b∞N≠©≠ç≠ÍŸí∂˛≠µ≠Ü≠’≠ñ)™B */
    > - private FuzzyXMLNode getParent() {
    > - if (_stack.size() == 0) {
    > - return null;
    > - }
    > - return _stack.get(_stack.size() - 1);
    > - }
    > + protected FuzzyXMLAttributeImpl createFuzzyXMLAttribute(FuzzyXMLElement element, int offset, AttrInfo attrInfo) {
    > + String namespace = null;
    > + String name = attrInfo.name;
    > + if (name != null) {
    > + int colonIndex = name.indexOf(':');
    > + if (colonIndex != -1) {
    > + namespace = name.substring(0, colonIndex);
    > + name = name.substring(colonIndex + 1);
    > + }
    > + }
    > + if (_wellFormedRequired) {
    > + FuzzyXMLAttributeImpl attr = new FuzzyXMLAttributeImpl(element, namespace, name, FuzzyXMLUtil.decode(attrInfo.value, false), attrInfo.rawValue, attrInfo.offset + offset, attrInfo.end - attrInfo.offset + 1, attrInfo.valueOffset);
    > + attr.setHasNestedTag(attrInfo.hasNestedTag);
    > + attr.setQuoteCharacter(attrInfo.quote);
    > + return attr;
    > + }
    > + FuzzyXMLAttributeImpl attr = new FuzzyXMLAttributeImpl(element, namespace, name, attrInfo.value, attrInfo.rawValue, attrInfo.offset + offset, attrInfo.end - attrInfo.offset + 1, attrInfo.valueOffset);
    > + attr.setHasNestedTag(attrInfo.hasNestedTag);
    > + attr.setQuoteCharacter(attrInfo.quote);
    > + if (attrInfo.value.indexOf('"') >= 0 || attrInfo.value.indexOf('\'') >= 0 || attrInfo.value.indexOf('<') >= 0 || attrInfo.value.indexOf('>') >= 0 || attrInfo.value.indexOf('&') >= 0) {
    > + attr.setEscape(false);
    > + }
    > + return attr;
    > + }
    >
    > - /** ∞^∞O‰ª≠›∞p™[∞X≠µ≠Ü≠·™B */
    > - private TagInfo parseTagContents(String text) {
    > - // ∞g∞…∞•
    > - Range trimmedRange = Range.trimmedRange(text);
    > - text = trimmedRange.trim(text);
    > - // Â≠¶∞^∞O≠≤≠Á≠∏≠çŸÅ‘ã≠Ì∞X∞≈∞b∞V∞∑≠›Ÿí∂˛
    > - if (text.endsWith("/")) {
    > - text = text.substring(0, text.length() - 1);
    > - }
    > - // ŸÅ∂≈≠Ì∞X∞y™[∞X≠Ü≠Å≠ª∞^∞Oˆπ
    > - TagInfo info = new TagInfo();
    > - if (FuzzyXMLUtil.getSpaceIndex(text) != -1) {
    > - info.name = text.substring(0, FuzzyXMLUtil.getSpaceIndex(text)).trim();
    > - info.nameOffset = trimmedRange.getOffset();
    > - parseAttributeContents(info, text);
    > - }
    > - else {
    > - info.name = text;
    > - }
    > - return info;
    > - }
    > + /** ï¿∏Jï¿∏nï¿∏^ï¿∏Oï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B */
    > + private void handleStartTag(FuzzyXMLElement element, TagInfo info, int offset, int end) {
    > + // ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Ç≈ï¿∏
    > + AttrInfo[] attrs = info.getAttrs();
    > + for (int i = 0; i < attrs.length; i++) {
    > + // // ï¿∏ï¿∏ï¿∏Oï¿∏ï¿∏Ô≠Ì∞Tï¿∏|ï¿∏[ï¿∏g
    > + // if(attrs[i].name.startsWith("xmlns")){
    > + // String uri = attrs[i].value;
    > + // String prefix = null;
    > + // String[] dim = attrs[i].name.split(":");
    > + // if(dim.length > 1){
    > + // prefix = dim[1];
    > + // }
    > + // element.addNamespaceURI(prefix,uri);
    > + // }
    > + element.appendChild(createFuzzyXMLAttribute(element, offset, attrs[i]));
    > + }
    > + _stack.push(element);
    > + _nonCloseElements.add(element);
    >
    > - /** ∞A∞g∞…∞r∞∑™[∞g‰ª≠›∞p™[∞X≠µ≠Ü≠·™B */
    > - private void parseAttributeContents(TagInfo info, String text) {
    > + checkElement(element);
    > + }
    >
    > - int state = 0;
    > - StringBuffer sb = new StringBuffer();
    > - String name = null;
    > - char quote = 0;
    > - int start = -1;
    > - int valueOffset = -1;
    > - boolean escape = false;
    > + /** ï¿∏Xï¿∏^ï¿∏bï¿∏Nï¿∏ÌŸÅ‘ï¿∏̘vï¿∏fï¿∏ï¿∏ï¿∏æ„≤ï¿∏ï¿∏ï¿∏Ü≠ï¿∏(ï¿∏Xï¿∏^ï¿∏bï¿∏Nï¿∏ï¿∏ï¿∏ï¿∏ÍŸí∂˛ï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏ï¿∏)ï¿∏B */
    > + private FuzzyXMLNode getParent() {
    > + if (_stack.size() == 0) {
    > + return null;
    > + }
    > + return _stack.get(_stack.size() - 1);
    > + }
    >
    > - for (int i = 0; i < text.length(); i++) {
    > - char c = text.charAt(i);
    > - if (state == 0 && FuzzyXMLUtil.isWhitespace(c)) {
    > - state = 1;
    > - }
    > - else if (state == 1 && !FuzzyXMLUtil.isWhitespace(c)) {
    > - if (start == -1) {
    > - start = i;
    > - }
    > - state = 2;
    > - sb.append(c);
    > - }
    > - else if (state == 2) {
    > - if (c == '=') {
    > - state = 3;
    > - name = sb.toString().trim();
    > - sb.setLength(0);
    > - valueOffset = -1;
    > - }
    > - else {
    > - sb.append(c);
    > - }
    > - }
    > - else if (state == 3 && !FuzzyXMLUtil.isWhitespace(c)) {
    > - if (valueOffset == -1) {
    > - valueOffset = i;
    > - }
    > - if (c == '\'' || c == '\"') {
    > - quote = c;
    > - }
    > - else {
    > - quote = 0;
    > - sb.append(c);
    > - }
    > - state = 4;
    > - }
    > - else if (state == 4) {
    > - if (c == quote && escape == true) {
    > - sb.append(c);
    > - escape = false;
    > - }
    > - else if (c == quote || (quote == 0 && FuzzyXMLUtil.isWhitespace(c))) {
    > - // add an attribute
    > - AttrInfo attr = new AttrInfo();
    > - attr.name = FuzzyXMLUtil.decode(name, _isHTML);
    > - attr.rawValue = sb.toString();
    > - attr.value = FuzzyXMLUtil.decode(attr.rawValue, _isHTML);
    > - attr.valueOffset = valueOffset;
    > - attr.offset = start;
    > - attr.end = i + 1;
    > - attr.quote = quote;
    > - info.addAttr(attr);
    > + /** ï¿∏^ï¿∏Oï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏pï¿∏[ï¿∏Xï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B */
    > + private TagInfo parseTagContents(String text) {
    > + // ï¿∏gï¿∏ï¿∏ï¿∏ï¿∏
    > + Range trimmedRange = Range.trimmedRange(text);
    > + text = trimmedRange.trim(text);
    > + // ï¿∏Â≠ï¿∏ï¿∏^ï¿∏Oï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Å‘ï¿∏Ì∞Xï¿∏ï¿∏ï¿∏bï¿∏Vï¿∏ï¿∏ï¿∏ï¿∏ï¿∏í∂˛
    > + if (text.endsWith("/")) {
    > + text = text.substring(0, text.length() - 1);
    > + }
    > + // ï¿∏Å∂ï¿∏ï¿∏Ì∞Xï¿∏yï¿∏[ï¿∏Xï¿∏Ü≠Å≠ï¿∏ï¿∏^ï¿∏Oï¿∏ï¿∏
    > + TagInfo info = new TagInfo();
    > + if (FuzzyXMLUtil.getSpaceIndex(text) != -1) {
    > + info.name = text.substring(0, FuzzyXMLUtil.getSpaceIndex(text)).trim();
    > + info.nameOffset = trimmedRange.getOffset();
    > + parseAttributeContents(info, text);
    > + }
    > + else {
    > + info.name = text;
    > + }
    > + return info;
    > + }
    >
    > - // reset
    > - sb.setLength(0);
    > - state = 1;
    > - start = -1;
    > - }
    > - else if (c == '\\') {
    > - if (escape == true) {
    > - sb.append(c);
    > - escape = false;
    > - }
    > - else {
    > - // MS: I took out escaping .. This is potentially a really sketchy thing to do, but it
    > - // was breaking attributes like numberformat = "\$#,##0.00"
    > - // Q: moved append to following 'else' block
    > - escape = true;
    > - }
    > - }
    > - else {
    > - if (escape) {
    > - sb.append('\\');
    > - escape = false;
    > - }
    > - sb.append(c);
    > - }
    > - }
    > - }
    > - if (state == 4 && quote == 0) {
    > - AttrInfo attr = new AttrInfo();
    > - attr.name = FuzzyXMLUtil.decode(name, _isHTML);
    > - attr.rawValue = sb.toString();
    > - attr.value = FuzzyXMLUtil.decode(attr.rawValue, _isHTML);
    > - attr.valueOffset = valueOffset;
    > - attr.offset = start;
    > - attr.end = text.length();
    > - attr.quote = quote;
    > - info.addAttr(attr);
    > - }
    > - if (state == 4 && quote != 0) {
    > - //System.out.println("FuzzyXMLParser.parseAttributeContents: " + info.name);
    > - }
    > - // Matcher matcher = attr.matcher(text);
    > - // while(matcher.find()){
    > - // AttrInfo attr = new AttrInfo();
    > - // attr.name = matcher.group(1);
    > - // attr.value = FuzzyXMLUtil.decode(matcher.group(3));
    > - // attr.offset = matcher.start();
    > - // attr.end = matcher.end();
    > - // info.addAttr(attr);
    > - // }
    > - }
    > + private static enum AttributeParseState {
    > + Start, BeforeAttributeName, InAttributeName, AfterAttributeName, InAttributeValue, InNestedTag,
    > + }
    >
    > - private class TagInfo {
    > - private String name;
    > - private int nameOffset;
    > - private ArrayList<AttrInfo> attrs = new ArrayList<AttrInfo>();
    > + /** ï¿∏Aï¿∏gï¿∏ï¿∏ï¿∏rï¿∏ï¿∏ï¿∏[ï¿∏gï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏pï¿∏[ï¿∏Xï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B */
    > + private void parseAttributeContents(TagInfo info, String text) {
    >
    > - public void addAttr(AttrInfo attr) {
    > - // „¯≠¶≠à≠Ì≠ª≠ ≠Á≠Ä≠à‚Ç≈Á≠µ≠È≠¢
    > - AttrInfo[] info = getAttrs();
    > - for (int i = 0; i < info.length; i++) {
    > - if (info[i].name.equals(attr.name)) {
    > - return;
    > - }
    > - }
    > - attrs.add(attr);
    > - }
    > + AttributeParseState state = AttributeParseState.Start;
    > + StringBuffer tokenBuffer = new StringBuffer();
    > + String name = null;
    > + char quoteCharacter = 0;
    > + int start = -1;
    > + int valueOffset = -1;
    > + boolean escape = false;
    > + boolean hasNestedTag = false;
    >
    > - public AttrInfo[] getAttrs() {
    > - return attrs.toArray(new AttrInfo[attrs.size()]);
    > - }
    > - }
    > + for (int i = 0; i < text.length(); i++) {
    > + char c = text.charAt(i);
    > + if (state == AttributeParseState.Start && FuzzyXMLUtil.isWhitespace(c)) {
    > + state = AttributeParseState.BeforeAttributeName;
    > + }
    > + else if (state == AttributeParseState.BeforeAttributeName && !FuzzyXMLUtil.isWhitespace(c)) {
    > + if (start == -1) {
    > + start = i;
    > + }
    > + state = AttributeParseState.InAttributeName;
    > + tokenBuffer.append(c);
    > + }
    > + else if (state == AttributeParseState.InAttributeName) {
    > + if (c == '=') {
    > + state = AttributeParseState.AfterAttributeName;
    > + name = tokenBuffer.toString().trim();
    > + tokenBuffer.setLength(0);
    > + valueOffset = -1;
    > + }
    > + else {
    > + tokenBuffer.append(c);
    > + }
    > + }
    > + else if (state == AttributeParseState.AfterAttributeName && !FuzzyXMLUtil.isWhitespace(c)) {
    > + if (valueOffset == -1) {
    > + valueOffset = i;
    > + }
    > + if (c == '\'' || c == '\"') {
    > + quoteCharacter = c;
    > + }
    > + else {
    > + quoteCharacter = 0;
    > + tokenBuffer.append(c);
    > + }
    > + state = AttributeParseState.InAttributeValue;
    > + }
    > + else if (state == AttributeParseState.InAttributeValue) {
    > + if (c == quoteCharacter && escape == true) {
    > + tokenBuffer.append(c);
    > + escape = false;
    > + }
    > + else if (c == quoteCharacter || (quoteCharacter == 0 && FuzzyXMLUtil.isWhitespace(c))) {
    > + // add an attribute
    > + AttrInfo attr = new AttrInfo();
    > + attr.name = FuzzyXMLUtil.decode(name, _isHTML);
    > + attr.rawValue = tokenBuffer.toString();
    > + attr.value = FuzzyXMLUtil.decode(attr.rawValue, _isHTML);
    > + attr.valueOffset = valueOffset;
    > + attr.offset = start;
    > + attr.end = i + 1;
    > + attr.quote = quoteCharacter;
    > + attr.hasNestedTag = hasNestedTag;
    > + info.addAttr(attr);
    >
    > - private class AttrInfo {
    > - private String name;
    > - private String value;
    > - private String rawValue;
    > - private int offset;
    > - private int valueOffset;
    > - private int end;
    > - private char quote;
    > - }
    > + // reset
    > + tokenBuffer.setLength(0);
    > + state = AttributeParseState.BeforeAttributeName;
    > + start = -1;
    > + hasNestedTag = false;
    > + }
    > + else if (c == '\\') {
    > + if (escape == true) {
    > + tokenBuffer.append(c);
    > + escape = false;
    > + }
    > + else {
    > + // MS: I took out escaping .. This is potentially a really sketchy
    > + // thing to do, but it
    > + // was breaking attributes like numberformat = "\$#,##0.00"
    > + // Q: moved append to following 'else' block
    > + escape = true;
    > + }
    > + }
    > + else if (c == '<') {
    > + hasNestedTag = true;
    > + state = AttributeParseState.InNestedTag;
    > + tokenBuffer.append(c);
    > + }
    > + else {
    > + if (escape) {
    > + tokenBuffer.append('\\');
    > + escape = false;
    > + }
    > + tokenBuffer.append(c);
    > + }
    > + }
    > + else if (state == AttributeParseState.InNestedTag) {
    > + tokenBuffer.append(c);
    > + if (c == '>') {
    > + state = AttributeParseState.InAttributeValue;
    > + }
    > + }
    > + }
    > + if ((state == AttributeParseState.InAttributeValue || state == AttributeParseState.InNestedTag) && quoteCharacter == 0) {
    > + AttrInfo attr = new AttrInfo();
    > + attr.name = FuzzyXMLUtil.decode(name, _isHTML);
    > + attr.rawValue = tokenBuffer.toString();
    > + attr.value = FuzzyXMLUtil.decode(attr.rawValue, _isHTML);
    > + attr.valueOffset = valueOffset;
    > + attr.offset = start;
    > + attr.end = text.length();
    > + attr.quote = quoteCharacter;
    > + attr.hasNestedTag = hasNestedTag;
    > + info.addAttr(attr);
    > + }
    > + if (state == AttributeParseState.InAttributeValue && quoteCharacter != 0) {
    > + // System.out.println("FuzzyXMLParser.parseAttributeContents: " +
    > + // info.name);
    > + }
    > + // Matcher matcher = attr.matcher(text);
    > + // while(matcher.find()){
    > + // AttrInfo attr = new AttrInfo();
    > + // attr.name = matcher.group(1);
    > + // attr.value = FuzzyXMLUtil.decode(matcher.group(3));
    > + // attr.offset = matcher.start();
    > + // attr.end = matcher.end();
    > + // info.addAttr(attr);
    > + // }
    > + }
    >
    > - public static class Range {
    > - private int _offset;
    > - private int _length;
    > + private class TagInfo {
    > + private String name;
    > + private int nameOffset;
    > + private ArrayList<AttrInfo> attrs = new ArrayList<AttrInfo>();
    >
    > - public Range() {
    > - }
    > + public void addAttr(AttrInfo attr) {
    > + // ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Ì≠ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Ä≠ï¿∏ï¿∏Ç≈ï¿∏ï¿∏ï¿∏ï¿∏È≠ï¿∏
    > + AttrInfo[] info = getAttrs();
    > + for (int i = 0; i < info.length; i++) {
    > + if (info[i].name.equals(attr.name)) {
    > + return;
    > + }
    > + }
    > + attrs.add(attr);
    > + }
    >
    > - public int getOffset() {
    > - return _offset;
    > - }
    > + public AttrInfo[] getAttrs() {
    > + return attrs.toArray(new AttrInfo[attrs.size()]);
    > + }
    > + }
    >
    > - public int getLength() {
    > - return _length;
    > - }
    > + private class AttrInfo {
    > + private String name;
    > + private String value;
    > + private String rawValue;
    > + private int offset;
    > + private int valueOffset;
    > + private int end;
    > + private char quote;
    > + private boolean hasNestedTag;
    > + }
    >
    > - public String trim(String str) {
    > - return str.substring(_offset, _offset + _length);
    > - }
    > + public static class Range {
    > + private int _offset;
    > + private int _length;
    >
    > - public static Range trimmedRange(String str) {
    > - int i = 0;
    > - int length = str.length();
    > - Range r = new Range();
    > - for (i = 0; i < length && str.charAt(i) <= ' '; i++) {
    > - // DO NOTHING
    > - }
    > - r._offset = i;
    > + public Range() {
    > + }
    >
    > - for (i = length - 1; i > r._offset && str.charAt(i) <= ' '; i--) {
    > - // DO NOTHING
    > - }
    > - r._length = (i - r._offset + 1);
    > - return r;
    > - }
    > - }
    > + public int getOffset() {
    > + return _offset;
    > + }
    >
    > + public int getLength() {
    > + return _length;
    > + }
    > +
    > + public String trim(String str) {
    > + return str.substring(_offset, _offset + _length);
    > + }
    > +
    > + public static Range trimmedRange(String str) {
    > + int i = 0;
    > + int length = str.length();
    > + Range r = new Range();
    > + for (i = 0; i < length && str.charAt(i) <= ' '; i++) {
    > + // DO NOTHING
    > + }
    > + r._offset = i;
    > +
    > + for (i = length - 1; i > r._offset && str.charAt(i) <= ' '; i--) {
    > + // DO NOTHING
    > + }
    > + r._length = (i - r._offset + 1);
    > + return r;
    > + }
    > + }
    > +
    > }
    >
    > Modified: branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/internal/AbstractFuzzyXMLNode.java
    > ===================================================================
    > --- branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/internal/AbstractFuzzyXMLNode.java 2010-10-03 21:15:19 UTC (rev 6167)
    > +++ branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/internal/AbstractFuzzyXMLNode.java 2010-10-03 21:16:16 UTC (rev 6168)
    >.. -65,14 +65,14 @@
    > }
    >
    > /**
    > - * ∞c∞…™[≠ÌŸX∆V∞C∞x∞„∞g≠›‰–≈Î≠µ≠Ü≠·™B
    > + * ï¿∏cï¿∏ï¿∏ï¿∏[ï¿∏ÌŸXï¿∏Vï¿∏Cï¿∏xï¿∏ï¿∏ï¿∏gï¿∏›‰–≈Î≠ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B
    > *
    > *..aram newText
    > *..aram offset
    > *..aram length
    > */
    > protected void fireModifyEvent(String newText, int offset, int length) {
    > - // ≠Ü≠≤∞m™[∞h≠ª∞c∞…™[≠É‚Ç≈Á≠“≠ê≠Ä≠¢≠È≠¢∂êŸΩ≠Í≠È≠É≠à≠µ≠È≠¢
    > + // ï¿∏Ü≠ï¿∏ï¿∏mï¿∏[ï¿∏hï¿∏ï¿∏ï¿∏cï¿∏ï¿∏ï¿∏[ï¿∏É‚Ç≈ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Ä≠ï¿∏ï¿∏È≠ï¿∏ï¿∏êŸΩï¿∏Í≠È≠É≠ï¿∏ï¿∏ï¿∏ï¿∏È≠ï¿∏
    > FuzzyXMLDocumentImpl doc = getDocument();
    > if (doc == null) {
    > return;
    >.. -81,14 +81,14 @@
    > }
    >
    > /**
    > - * ∞m™[∞h≠Ì√Ê‚u∂îñ≠›ŸX∆V≠µ≠Ü≠·™B∞c∞…™[≠ÌÏŸXŒO≠É‘Ä≠Ñ∂o≠µ≠Ü≠·™B
    > + * ï¿∏mï¿∏[ï¿∏hï¿∏Ì√Ê‚uï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Xï¿∏Vï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏Bï¿∏cï¿∏ï¿∏ï¿∏[ï¿∏ÌÏŸXï¿∏Oï¿∏É‘Ä≠Ñ∂oï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B
    > *
    > *..aram parent
    > *..aram offset
    > *..aram append
    > */
    > protected void appendOffset(FuzzyXMLElement parent, int offset, int append) {
    > - // ≠Ü≠≤∞m™[∞h≠ª∞c∞…™[≠É‚Ç≈Á≠“≠ê≠Ä≠¢≠È≠¢∂êŸΩ≠Í≠È≠É≠à≠µ≠È≠¢
    > + // ï¿∏Ü≠ï¿∏ï¿∏mï¿∏[ï¿∏hï¿∏ï¿∏ï¿∏cï¿∏ï¿∏ï¿∏[ï¿∏É‚Ç≈ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Ä≠ï¿∏ï¿∏È≠ï¿∏ï¿∏êŸΩï¿∏Í≠È≠É≠ï¿∏ï¿∏ï¿∏ï¿∏È≠ï¿∏
    > FuzzyXMLDocumentImpl doc = getDocument();
    > if (doc == null) {
    > return;
    >.. -130,4 +130,8 @@
    > public boolean hasLineBreaks() {
    > return true;
    > }
    > +
    > + public boolean isSynthetic() {
    > + return false;
    > + }
    > }
    >
    > Modified: branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/internal/FuzzyXMLAttributeImpl.java
    > ===================================================================
    > --- branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/internal/FuzzyXMLAttributeImpl.java 2010-10-03 21:15:19 UTC (rev 6167)
    > +++ branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/internal/FuzzyXMLAttributeImpl.java 2010-10-03 21:16:16 UTC (rev 6168)
    >.. -15,6 +15,7 @@
    > private String _value;
    > private String _rawValue;
    > private int _valueOffset;
    > + private boolean _hasNestedTag;
    >
    > public FuzzyXMLAttributeImpl(String namespace, String name) {
    > this(null, namespace, name, null, null, -1, -1, -1);
    >.. -34,6 +35,14 @@
    > this._rawValue = rawValue;
    > _valueOffset = valueOffset;
    > }
    > +
    > + public void setHasNestedTag(boolean hasNestedTag) {
    > + _hasNestedTag = hasNestedTag;
    > + }
    > +
    > + public boolean hasNestedTag() {
    > + return _hasNestedTag;
    > + }
    >
    > public String getRawValue() {
    > return _rawValue;
    >.. -106,11 +115,11 @@
    > this._value = (value == null) ? "" : value;
    > this._rawValue = this._value;
    >
    > - // ŸX∆V∞C∞x∞„∞g≠›‰–≈Î
    > + // ï¿∏Xï¿∏Vï¿∏Cï¿∏xï¿∏ï¿∏ï¿∏gï¿∏›‰–≈ï¿∏
    > FuzzyXMLDocumentImpl document = getDocument();
    > boolean html = (document == null) ? true : document.isHTML();
    > fireModifyEvent(toXMLString(new RenderContext(html)), getOffset(), getLength());
    > - // √Ê‚u∂îñ≠›ŸX∆V
    > + // ï¿∏Ê‚uï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Xï¿∏V
    > appendOffset((FuzzyXMLElement) getParentNode(), getOffset(), this._value.length() - length);
    > }
    >
    >.. -191,15 +200,24 @@
    > if (quote != 0) {
    > xmlBuffer.append(quote);
    > }
    > - if (_escape) {
    > + // MS: Technically we want to escape everything BUT the nested tags, but just avoid it all for now
    > + boolean hasNestedTag = hasNestedTag();
    > + if (_escape && hasNestedTag) {
    > // Only do minimal XML escaping on the contents of attribute values
    > xmlBuffer.append(FuzzyXMLUtil.escape(_value, false));
    > }
    > else {
    > + boolean inNestedTag = false;
    > String value = getValue();
    > for (int i = 0; i < value.length(); i++) {
    > char c = value.charAt(i);
    > - if (_quote == c) {
    > + if (hasNestedTag && c == '<') {
    > + inNestedTag = true;
    > + }
    > + else if (c == '>') {
    > + inNestedTag = false;
    > + }
    > + else if (!inNestedTag && _quote == c) {
    > xmlBuffer.append('\\');
    > }
    > xmlBuffer.append(c);
    >
    > Modified: branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/internal/FuzzyXMLElementImpl.java
    > ===================================================================
    > --- branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/internal/FuzzyXMLElementImpl.java 2010-10-03 21:15:19 UTC (rev 6167)
    > +++ branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/internal/FuzzyXMLElementImpl.java 2010-10-03 21:16:16 UTC (rev 6168)
    >.. -37,6 +37,8 @@
    > private int _closeNameOffset;
    >
    > private Boolean _isNonBreaking;
    > +
    > + private boolean _synthetic;
    >
    > // private HashMap namespace = new HashMap();
    >
    >.. -102,24 +104,24 @@
    > }
    >
    > /**
    > - * XML≠Ì‚f‹∞e∞L∞X∞g≠©≠ç⁄q∞m™[∞h‘Q≠›‚Ç≈Á≠µ≠Ü≠·™B
    > + * XMLï¿∏Ì‚fï¿∏‹∞eï¿∏Lï¿∏Xï¿∏gï¿∏ï¿∏ï¿∏ï¿∏qï¿∏mï¿∏[ï¿∏hï¿∏Qï¿∏ï¿∏Ç≈ï¿∏ï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B
    > * <p>
    > - * ‚Ê∂í≠Ì<code>appendChild()</code>≠Å⁄q∞m™[∞h≠›‚Ç≈Á≠µ≠∏∂êŸΩ™A
    > - * ∞…∞X∞i≠É≠Í<code>FuzzyXMLNode#toXMLString()</code>≠Ì‘—≈Ê≠ª∆V≠µ≠¢∞e∞L∞X∞g≠Æ≠µ≠Ä‚Ê‚m≠“≠ê≠Ü≠·≠ª™A
    > - * ≠±≠Ì∞™∞\∞b∞h≠›˜p≠¢≠Ä⁄q∞m™[∞h≠›‚Ç≈Á≠µ≠∏∂êŸΩ™A√ø∆‰≠Å„n≠µ≠∏∞e∞L∞X∞g≠ª∆V≠µ≠¢∞e∞L∞X∞g≠Æ≠µ≠Ä„n≠“≠ê≠Ü≠·™B
    > - * s∆“≠ÈXML≠›∞p™[∞X≠µ™A‘“≠Ì∞e∞L∞X∞g∂îñ≠›€⁄ˇ≠·≠éK˜v≠ª≠ ≠é∂êŸΩ≠É⁄g˜p≠µ≠Ä≠–≠≤≠“≠¢™B
    > + * ï¿∏Ê∂ï¿∏ï¿∏<code>appendChild()</code>ï¿∏Å⁄qï¿∏mï¿∏[ï¿∏hï¿∏ï¿∏Ç≈ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏êŸΩï¿∏A
    > + * ï¿∏ï¿∏ï¿∏Xï¿∏iï¿∏É≠ï¿∏<code>FuzzyXMLNode#toXMLString()</code>ï¿∏Ì‘ï¿∏ï¿∏Ê≠ï¿∏ï¿∏Vï¿∏ï¿∏ï¿∏ï¿∏ï¿∏eï¿∏Lï¿∏Xï¿∏gï¿∏Æ≠ï¿∏ï¿∏Ä‚Ê‚mï¿∏ï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏ï¿∏ï¿∏A
    > + * ï¿∏ï¿∏ï¿∏Ì∞ï¿∏ï¿∏\ï¿∏bï¿∏hï¿∏ï¿∏pï¿∏ï¿∏ï¿∏Ä⁄qï¿∏mï¿∏[ï¿∏hï¿∏ï¿∏Ç≈ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏êŸΩï¿∏Aï¿∏ï¿∏Å„nï¿∏ï¿∏ï¿∏ï¿∏ï¿∏eï¿∏Lï¿∏Xï¿∏gï¿∏ï¿∏ï¿∏Vï¿∏ï¿∏ï¿∏ï¿∏ï¿∏eï¿∏Lï¿∏Xï¿∏gï¿∏Æ≠ï¿∏ï¿∏Ä„nï¿∏ï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B
    > + * ï¿∏sï¿∏ï¿∏ï¿∏ï¿∏XMLï¿∏ï¿∏ï¿∏pï¿∏[ï¿∏Xï¿∏ï¿∏ï¿∏Aï¿∏ï¿∏ï¿∏Ì∞eï¿∏Lï¿∏Xï¿∏gï¿∏ï¿∏ï¿∏ï¿∏€⁄ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Kï¿∏vï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏êŸΩï¿∏É⁄gï¿∏pï¿∏ï¿∏ï¿∏Ä≠ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏B
    > * </p>
    > - *..aram text ‚Ç≈Á≠·≠é⁄q˜vŒf≠›…Ü≠ñ≠≤XML≠Ì‚f‹™B
    > + *..aram text ï¿∏Ç≈ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏qï¿∏vï¿∏fï¿∏ï¿∏ï¿∏Ü≠ï¿∏XMLï¿∏Ì‚fï¿∏‹™B
    > */
    > public void appendChildrenFromText(String text, boolean wo54) {
    > if (text.length() == 0) {
    > return;
    > }
    > - // √ê„x∞G∞‘∞™∞„∞g≠›Œ}„ü≠µ≠Ä∞I∞t∞Z∞b∞g≠›⁄æ„≤
    > + // ï¿∏ï¿∏xï¿∏Gï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏gï¿∏ï¿∏}ï¿∏ï¿∏Ä∞Iï¿∏tï¿∏Zï¿∏bï¿∏gï¿∏ï¿∏ï¿∏æ„≤
    > FuzzyXMLElement test = new FuzzyXMLElementImpl("test");
    > appendChild(test);
    > int offset = test.getOffset();
    > - // ∞I∞t∞Z∞b∞g≠›⁄æ„≤≠µ≠∏≠ç≠·≠®Ÿí∂˛
    > + // ï¿∏Iï¿∏tï¿∏Zï¿∏bï¿∏gï¿∏ï¿∏ï¿∏æ„≤ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ç≠·ï¿∏ï¿∏ï¿∏í∂˛
    > removeChild(test);
    >
    > String parseText = "<root>" + text + "</root>";
    >.. -139,48 +141,48 @@
    > }
    >
    > /**
    > - * ≠±≠Ì∞G∞‘∞™∞„∞g≠É⁄q∞m™[∞h≠›‚Ç≈Á≠µ≠Ü≠·™B
    > - * √È≈º≠Ì∂êŸΩ≠Í∞m™[∞h≠›‚Ç≈Á≠·≠é≠±≠Æ≠Í≠Å≠«≠Ü≠’≠ñ™iFuzzyXMLException≠ª‰–∆¶≠µ≠Ü≠·™j™B
    > + * ï¿∏ï¿∏ï¿∏Ì∞Gï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏gï¿∏É⁄qï¿∏mï¿∏[ï¿∏hï¿∏ï¿∏Ç≈ï¿∏ï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B
    > + * ï¿∏È≈ï¿∏ï¿∏Ì∂êŸΩï¿∏Í∞mï¿∏[ï¿∏hï¿∏ï¿∏Ç≈ï¿∏ï¿∏ï¿∏ï¿∏é≠±ï¿∏Æ≠Í≠Å≠ï¿∏ï¿∏Ü≠ï¿∏ï¿∏ï¿∏iFuzzyXMLExceptionï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏jï¿∏B
    > *
    > * <ul>
    > - * <li>∞G∞‘∞™∞„∞g≠ªŒπ≠Ì∞c∞…™[≠ÉŒ®≠µ≠Ä≠¢≠é∂êŸΩ™i∆e∞G∞‘∞™∞„∞g≠©≠çremove≠·≠ê≠΂Ç≈Á≠Å≠«≠Ü≠·™j</li>
    > - * <li>∞G∞‘∞™∞„∞g≠ª⁄q∞m™[∞h≠›⁄ˇ≠Á≠Ä≠¢≠é∂êŸΩ</li>
    > + * <li>ï¿∏Gï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏gï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Ì∞cï¿∏ï¿∏ï¿∏[ï¿∏ÉŒï¿∏ï¿∏ï¿∏ï¿∏Ä≠ï¿∏ï¿∏ï¿∏êŸΩï¿∏iï¿∏eï¿∏Gï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏gï¿∏ï¿∏ï¿∏ï¿∏removeï¿∏ï¿∏ï¿∏ï¿∏΂Ç≈ï¿∏ï¿∏Å≠ï¿∏ï¿∏Ü≠ï¿∏ï¿∏j</li>
    > + * <li>ï¿∏Gï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏gï¿∏ï¿∏ï¿∏qï¿∏mï¿∏[ï¿∏hï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Ä≠ï¿∏ï¿∏ï¿∏êŸΩ</li>
    > * </ul>
    > *
    > - *..aram node ‚Ç≈Á≠·≠é∞m™[∞h™B
    > - * ∞G∞‘∞™∞„∞g≠Ì∂êŸΩ™A⁄q≠›⁄ˇ≠∏≠È≠¢∞G∞‘∞™∞„∞g≠›⁄w‚è≠µ≠Ä≠–≠≤≠“≠¢™B
    > - * ≠·≠Å≠É⁄q˜vŒf≠›Ÿ\‚zŸÏ≠†≠Ì∞G∞‘∞™∞„∞g≠›„n≠·≠Æ„à‰≠Å€⁄ˇ≠µ≠Ä≠¢≠é√Ê‚u∂îñ≠ª„¯…ú≠“≠ê≠Ü≠’≠ñ™B
    > + *..aram node ï¿∏Ç≈ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏mï¿∏[ï¿∏hï¿∏B
    > + * ï¿∏Gï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏gï¿∏Ì∂êŸΩï¿∏Aï¿∏qï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏È≠ï¿∏ï¿∏Gï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏gï¿∏ï¿∏ï¿∏wï¿∏è≠µï¿∏Ä≠ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏B
    > + * ï¿∏ï¿∏ï¿∏Å≠É⁄qï¿∏vï¿∏fï¿∏ï¿∏ï¿∏\ï¿∏zï¿∏Ï≠†≠Ì∞Gï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏gï¿∏ï¿∏nï¿∏ï¿∏ï¿∏Æ„ï¿∏ï¿∏ï¿∏ï¿∏Å€⁄ï¿∏ï¿∏ï¿∏ï¿∏Ä≠ï¿∏ï¿∏ï¿∏Ê‚uï¿∏ï¿∏ñ≠ª„ï¿∏ï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏ï¿∏B
    > *
    > - *..xception jp.aonir.fuzzyxml.FuzzyXMLException ∞m™[∞h≠›‚Ç≈Á≠Å≠«≠È≠¢∂êŸΩ
    > + *..xception jp.aonir.fuzzyxml.FuzzyXMLException ï¿∏mï¿∏[ï¿∏hï¿∏ï¿∏Ç≈ï¿∏ï¿∏Å≠ï¿∏ï¿∏È≠ï¿∏ï¿∏êŸΩ
    > */
    > public void appendChild(FuzzyXMLNode node) {
    > appendChild(node, true, true);
    > }
    >
    > /**
    > - * ∞p™[∞X⁄ı≠É<code>appendChild()</code>∞™∞\∞b∞h≠ÌŒã≠í≠è≠É⁄g˜p≠µ≠Ü≠·™B
    > + * ï¿∏pï¿∏[ï¿∏Xï¿∏ï¿∏ï¿∏ï¿∏<code>appendChild()</code>ï¿∏ï¿∏ï¿∏\ï¿∏bï¿∏hï¿∏ÌŒï¿∏ï¿∏ï¿∏É⁄gï¿∏pï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B
    > */
    > public void appendChildWithNoCheck(FuzzyXMLNode node) {
    > appendChild(node, true, false);
    > }
    >
    > /**
    > - * ≠±≠Ì∞G∞‘∞™∞„∞g≠É⁄q∞m™[∞h≠›‚Ç≈Á™B
    > + * ï¿∏ï¿∏ï¿∏Ì∞Gï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏gï¿∏É⁄qï¿∏mï¿∏[ï¿∏hï¿∏ï¿∏Ç≈ï¿∏ï¿∏B
    > *
    > - *..aram node ‚Ç≈Á≠·≠é∞m™[∞h™B
    > - * ∞G∞‘∞™∞„∞g≠Ì∂êŸΩ™A⁄q≠›⁄ˇ≠∏≠È≠¢∞G∞‘∞™∞„∞g≠›⁄w‚è≠µ≠Ä≠–≠≤≠“≠¢™B
    > - * ≠·≠Å≠É⁄q˜vŒf≠›Ÿ\‚zŸÏ≠†≠Ì∞G∞‘∞™∞„∞g≠›„n≠·≠Æ„à‰≠Å€⁄ˇ≠µ≠Ä≠¢≠é√Ê‚u∂îñ≠ª„¯…ú≠“≠ê≠Ü≠’≠ñ™B
    > - *..aram fireEvent ∞C∞x∞„∞g≠›‰–≈Î≠·≠é≠©≠Ç≠¤≠©™B
    > - * false≠›⁄w‚è≠µ≠∏∂êŸΩ™A∞m™[∞h≠ª⁄ˇ≠Á≠Ä≠¢≠é√Ê‚u∂îñ≠Ì„¯…ú∂√˜ˇ≠àŸs≠¢≠Ü≠’≠ñ™B
    > - *..aram check ‚Ç≈Á≠·≠é∞m™[∞h≠Ì‘ƒ∂Ø≠›Ÿs≠¤≠©≠Ç≠¤≠©™B
    > - * true≠›⁄w‚è≠µ≠∏∂êŸΩ™A√È≈º≠Ì≠É…Y„ˆ≠·≠é∂êŸΩFuzzyXMLException≠›throw≠µ≠Ü≠·™B
    > + *..aram node ï¿∏Ç≈ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏mï¿∏[ï¿∏hï¿∏B
    > + * ï¿∏Gï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏gï¿∏Ì∂êŸΩï¿∏Aï¿∏qï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏È≠ï¿∏ï¿∏Gï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏gï¿∏ï¿∏ï¿∏wï¿∏è≠µï¿∏Ä≠ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏B
    > + * ï¿∏ï¿∏ï¿∏Å≠É⁄qï¿∏vï¿∏fï¿∏ï¿∏ï¿∏\ï¿∏zï¿∏Ï≠†≠Ì∞Gï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏gï¿∏ï¿∏nï¿∏ï¿∏ï¿∏Æ„ï¿∏ï¿∏ï¿∏ï¿∏Å€⁄ï¿∏ï¿∏ï¿∏ï¿∏Ä≠ï¿∏ï¿∏ï¿∏Ê‚uï¿∏ï¿∏ñ≠ª„ï¿∏ï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏ï¿∏B
    > + *..aram fireEvent ï¿∏Cï¿∏xï¿∏ï¿∏ï¿∏gï¿∏›‰–≈Î≠ï¿∏ï¿∏é≠©ï¿∏Ç≠ï¿∏ï¿∏ï¿∏ï¿∏B
    > + * falseï¿∏ï¿∏ï¿∏wï¿∏è≠µï¿∏ï¿∏ï¿∏êŸΩï¿∏Aï¿∏mï¿∏[ï¿∏hï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Ä≠ï¿∏ï¿∏ï¿∏Ê‚uï¿∏ï¿∏ï¿∏Ì„ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏sï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏ï¿∏B
    > + *..aram check ï¿∏Ç≈ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏mï¿∏[ï¿∏hï¿∏Ì‘ï¿∏ï¿∏Ø≠ï¿∏ï¿∏sï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Ç≠ï¿∏ï¿∏ï¿∏ï¿∏B
    > + * trueï¿∏ï¿∏ï¿∏wï¿∏è≠µï¿∏ï¿∏ï¿∏êŸΩï¿∏Aï¿∏È≈ï¿∏ï¿∏Ì≠É…Yï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏êŸΩFuzzyXMLExceptionï¿∏ï¿∏throwï¿∏ï¿∏ï¿∏Ü≠ï¿∏ï¿∏B
    > * <ul>
    > - * <li>∞m™[∞h≠ªŒπ≠Ì∞c∞…™[≠ÉŒ®≠µ≠Ä≠¢≠é∂êŸΩ</li>
    > - * <li>∞G∞‘∞™∞„∞g≠ª≠·≠Å≠É⁄q—ƒ≠›⁄ˇ≠Á≠Ä≠¢≠é∂êŸΩ</li>
    > + * <li>ï¿∏mï¿∏[ï¿∏hï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Ì∞cï¿∏ï¿∏ï¿∏[ï¿∏ÉŒï¿∏ï¿∏ï¿∏ï¿∏Ä≠ï¿∏ï¿∏ï¿∏êŸΩ</li>
    > + * <li>ï¿∏Gï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏gï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Å≠É⁄qï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Ä≠ï¿∏ï¿∏ï¿∏êŸΩ</li>
    > * </ul>
    > - * ∞p™[∞X⁄ı≠È≠Ç™A‘ƒ∂Ø≠›Ÿs≠¢≠∏≠–≠È≠¢∂êŸΩ≠Ífalse≠›⁄w‚è≠µ≠Ü≠·™B
    > + * ï¿∏pï¿∏[ï¿∏Xï¿∏ï¿∏ï¿∏È≠Ç™Aï¿∏ï¿∏ï¿∏Ø≠ï¿∏ï¿∏sï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏È≠ï¿∏ï¿∏êŸΩï¿∏ï¿∏falseï¿∏ï¿∏ï¿∏wï¿∏è≠µï¿∏Ü≠ï¿∏ï¿∏B
    > *
    > - *..xception jp.aonir.fuzzyxml.FuzzyXMLException ∞m™[∞h≠›‚Ç≈Á≠Å≠«≠È≠¢∂êŸΩ
    > + *..xception jp.aonir.fuzzyxml.FuzzyXMLException ï¿∏mï¿∏[ï¿∏hï¿∏ï¿∏Ç≈ï¿∏ï¿∏Å≠ï¿∏ï¿∏È≠ï¿∏ï¿∏êŸΩ
    > */
    > private void appendChild(FuzzyXMLNode node, boolean fireEvent, boolean check) {
    > if (check) {
    >.. -209,7 +211,7 @@
    > _children.add(node);
    > return;
    > }
    > - // ‚Ç≈Á≠·≠é∞m™[∞h≠Ì√Ê‚u(ŸÅ‘ã)≠›‘v⁄Z
    > + // ï¿∏Ç≈ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏mï¿∏[ï¿∏hï¿∏Ì√Ê‚u(ï¿∏Å‘ï¿∏)ï¿∏ï¿∏ï¿∏vï¿∏Z
    > FuzzyXMLNode[] nodes = getChildren();
    > int offset = 0;
    > if (nodes.length == 0) {
    >.. -219,7 +221,7 @@
    > for (int i = 0; i < attrs.length; i++) {
    > offset = offset + attrs[i].toXMLString(new RenderContext(getDocument().isHTML())).length();
    > }
    > - // ≠±≠±‰÷ˆ–™H
    > + // ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏H
    > offset = offset + 2;
    >
    > nodeImpl.setOffset(offset);
    >.. -231,10 +233,10 @@
    > String xml = toXMLString(new RenderContext(getDocument().isHTML()));
    > _children.remove(node);
    >
    > - // ∞C∞x∞„∞g≠̉–≈Î
    > + // ï¿∏Cï¿∏xï¿∏ï¿∏ï¿∏gï¿∏̉ï¿∏ï¿∏ï¿∏
    > if (fireEvent) {
    > fireModifyEvent(xml, getOffset(), getLength());
    > - // √Ê‚u∂îñ≠ÌŸX∆V
    > + // ï¿∏Ê‚uï¿∏ï¿∏ï¿∏ÌŸXï¿∏V
    > appendOffset(this, offset, xml.length() - length);
    > }
    >
    >.. -245,14 +247,14 @@
    > for (int i = 0; i < nodes.length; i++) {
    > offset = nodes[i].getOffset() + nodes[i].getLength();
    > }
    > - // ∞C∞x∞„∞g≠̉–≈Î
    > + // ï¿∏Cï¿∏xï¿∏ï¿∏ï¿∏gï¿∏̉ï¿∏ï¿∏ï¿∏
    > if (fireEvent) {
    > fireModifyEvent(nodeImpl.toXMLString(new RenderContext(getDocument().isHTML())), offset, 0);
    > - // √Ê‚u∂îñ≠ÌŸX∆V
    > + // ï¿∏Ê‚uï¿∏ï¿∏ï¿∏ÌŸXï¿∏V
    > appendOffset(this, offset, node.toXMLString(new RenderContext(getDocument().isHTML())).length());
    > }
    >
    > - // ŸÅ‘ã≠É‚Ç≈Á
    > + // ï¿∏Å‘ï¿∏É‚Ç≈ï¿∏
    > nodeImpl.setOffset(offset);
    > if (fireEvent) {
    > nodeImpl.setLength(node.toXMLString(new RenderContext(getDocument().isHTML())).length());
    >.. -276,7 +278,7 @@
    > }
    >
    > public FuzzyXMLNode[] getChildren() {
    > - // ∞A∞g∞…∞r∞∑™[∞g≠Í…Ü≠Ü≠È≠¢™H
    > + // ï¿∏Aï¿∏gï¿∏ï¿∏ï¿∏rï¿∏ï¿∏ï¿∏[ï¿∏gï¿∏Í…Ü≠Ü≠È≠ï¿∏ï¿∏H
    > return _children.toArray(new FuzzyXMLNode[_children.size()]);
    > }
    >
    >.. -307,11 +309,11 @@
    > }
    >
    > public void insertAfter(FuzzyXMLNode newChild, FuzzyXMLNode refChild) {
    > - // ∞A∞g∞…∞r∞∑™[∞g≠Ì∂êŸΩ≠Í≠È≠É≠à≠µ≠È≠¢
    > + // ï¿∏Aï¿∏gï¿∏ï¿∏ï¿∏rï¿∏ï¿∏ï¿∏[ï¿∏gï¿∏Ì∂êŸΩï¿∏Í≠È≠É≠ï¿∏ï¿∏ï¿∏ï¿∏È≠ï¿∏
    > if (newChild instanceof FuzzyXMLAttribute || refChild instanceof FuzzyXMLAttribute) {
    > return;
    > }
    > - // Œ}„ü≠·≠é√Ê‚u≠›‚T≠·
    > + // ï¿∏}ï¿∏ï¿∏ï¿∏Ê‚uï¿∏ï¿∏Tï¿∏ï¿∏
    > FuzzyXMLNode[] children = getChildren();
    > FuzzyXMLNode targetNode = null;
    > boolean flag = false;
    >.. -332,11 +334,11 @@
    > }
    >
    > public void insertBefore(FuzzyXMLNode newChild, FuzzyXMLNode refChild) {
    > - // ∞A∞g∞…∞r∞∑™[∞g≠Ì∂êŸΩ≠Í≠È≠É≠à≠µ≠È≠¢
    > + // ï¿∏Aï¿∏gï¿∏ï¿∏ï¿∏rï¿∏ï¿∏ï¿∏[ï¿∏gï¿∏Ì∂êŸΩï¿∏Í≠È≠É≠ï¿∏ï¿∏ï¿∏ï¿∏È≠ï¿∏
    > if (newChild instanceof FuzzyXMLAttribute || refChild instanceof FuzzyXMLAttribute) {
    > return;
    > }
    > - // Œ}„ü≠·≠é√Ê‚u≠›‚T≠·
    > + // ï¿∏}ï¿∏ï¿∏ï¿∏Ê‚uï¿∏ï¿∏Tï¿∏ï¿∏
    > FuzzyXMLNode target = null;
    > int index = -1;
    > FuzzyXMLNode[] children = getChildren();
    >.. -351,7 +353,7 @@
    > return;
    > }
    > int offset = target.getOffset();
    > - // ∞C∞x∞„∞g≠̉–≈Î
    > + // ï¿∏Cï¿∏xï¿∏ï¿∏ï¿∏gï¿∏̉ï¿∏ï¿∏ï¿∏
    > fireModifyEvent(newChild.toXMLString(new RenderContext(getDocument().isHTML())), offset, 0);
    >
    > AbstractFuzzyXMLNode nodeImpl = (AbstractFuzzyXMLNode) newChild;
    >.. -360,19 +362,19 @@
    > nodeImpl.setOffset(offset);
    > nodeImpl.setLength(newChild.toXMLString(new RenderContext(getDocument().isHTML())).length());
    >
    > - // √Ê‚u∂îñ≠ÌŸX∆V
    > + // ï¿∏Ê‚uï¿∏ï¿∏ï¿∏ÌŸXï¿∏V
    > appendOffset(this, offset, nodeImpl.toXMLString(new RenderContext(getDocument().isHTML())).length());
    >
    > - // ŸÅ‘ã≠É‚Ç≈Á
    > + // ï¿∏Å‘ï¿∏É‚Ç≈ï¿∏
    > this._children.add(index, nodeImpl);
    > }
    >
    > public void replaceChild(FuzzyXMLNode newChild, FuzzyXMLNode refChild) {
    > - // ∞A∞g∞…∞r∞∑™[∞g≠Ì∂êŸΩ≠Í≠È≠É≠à≠µ≠È≠¢
    > + // ï¿∏Aï¿∏gï¿∏ï¿∏ï¿∏rï¿∏ï¿∏ï¿∏[ï¿∏gï¿∏Ì∂êŸΩï¿∏Í≠È≠É≠ï¿∏ï¿∏ï¿∏ï¿∏È≠ï¿∏
    > if (newChild instanceof FuzzyXMLAttribute || refChild instanceof FuzzyXMLAttribute) {
    > return;
    > }
    > - // ‚u…·≠·≠é∞m™[∞h≠Ì∞C∞„∞f∞b∞N∞X≠›⁄æ„≤
    > + // ï¿∏uï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏mï¿∏[ï¿∏hï¿∏Ì∞Cï¿∏ï¿∏ï¿∏fï¿∏bï¿∏Nï¿∏Xï¿∏ï¿∏ï¿∏æ„≤
    > int index = -1;
    > for (int i = 0; i < _children.size(); i++) {
    > if (refChild == _children.get(i)) {
    >.. -380,7 +382,7 @@
    > break;
    > }
    > }
    > - // ∞m™[∞h≠ª‘©≠Â≠©≠ç≠È≠©≠Á≠∏≠ç≠È≠É≠à≠µ≠È≠¢
    > + // ï¿∏mï¿∏[ï¿∏hï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Â≠ï¿∏ï¿∏ï¿∏È≠ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏È≠É≠ï¿∏ï¿∏ï¿∏ï¿∏È≠ï¿∏
    > if (index == -1) {
    > return;
    > }
    >.. -392,9 +394,9 @@
    > nodeImpl.setOffset(refChild.getOffset());
    > nodeImpl.setLength(newChild.toXMLString(new RenderContext(getDocument().isHTML())).length());
    >
    > - // ∞C∞x∞„∞g≠̉–≈Î
    > + // ï¿∏Cï¿∏xï¿∏ï¿∏ï¿∏gï¿∏̉ï¿∏ï¿∏ï¿∏
    > fireModifyEvent(newChild.toXMLString(new RenderContext(getDocument().isHTML())), refChild.getOffset(), refChild.getLength());
    > - // √Ê‚u∂îñ≠ÌŸX∆V
    > + // ï¿∏Ê‚uï¿∏ï¿∏ï¿∏ÌŸXï¿∏V
    > appendOffset(this, refChild.getOffset(), newChild.getLength() - refChild.getLength());
    >
    > _children.add(index, newChild);
    >.. -406,14 +408,14 @@
    > return;
    > }
    > if (_children.contains(oldChild)) {
    > - // ∞f∞^∞b∞`
    > + // ï¿∏fï¿∏^ï¿∏bï¿∏`
    > ((AbstractFuzzyXMLNode) oldChild).setParentNode(null);
    > ((AbstractFuzzyXMLNode) oldChild).setDocument(null);
    > - // ∞…∞X∞g≠©≠çŸí∂˛
    > + // ï¿∏ï¿∏ï¿∏Xï¿∏gï¿∏ï¿∏ï¿∏ï¿∏í∂˛
    > _children.remove(oldChild);
    > - // ∞C∞x∞„∞g≠̉–≈Î
    > + // ï¿∏Cï¿∏xï¿∏ï¿∏ï¿∏gï¿∏̉ï¿∏ï¿∏ï¿∏
    > fireModifyEvent("", oldChild.getOffset(), oldChild.getLength());
    > - // √Ê‚u∂îñ≠ÌŸX∆V
    > + // ï¿∏Ê‚uï¿∏ï¿∏ï¿∏ÌŸXï¿∏V
    > appendOffset(this, oldChild.getOffset(), oldChild.getLength() * -1);
    > }
    > }
    >.. -431,23 +433,23 @@
    > FuzzyXMLAttributeImpl attrImpl = (FuzzyXMLAttributeImpl) attr;
    > attrImpl.setDocument(getDocument());
    > attrImpl.setParentNode(this);
    > - // ‚Ç≈Á≠·≠é∞A∞g∞…∞r∞∑™[∞g≠Ì√Ê‚u≠›‘ƒŸõ
    > + // ï¿∏Ç≈ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Aï¿∏gï¿∏ï¿∏ï¿∏rï¿∏ï¿∏ï¿∏[ï¿∏gï¿∏Ì√Ê‚uï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏
    > FuzzyXMLAttribute[] attrs = getAttributes();
    > int offset = getOffset() + getName().length() + 1;
    > for (int i = 0; i < attrs.length; i++) {
    > offset = offset + attrs[i].toXMLString(new RenderContext(getDocument().isHTML())).length();
    > }
    > - // ŸX∆V∞C∞x∞„∞g≠›‰–≈Î
    > + // ï¿∏Xï¿∏Vï¿∏Cï¿∏xï¿∏ï¿∏ï¿∏gï¿∏›‰–≈ï¿∏
    > fireModifyEvent(attr.toXMLString(new RenderContext(getDocument().isHTML())), offset, 0);
    > - // √Ê‚u∂îñ≠ÌŸX∆V
    > + // ï¿∏Ê‚uï¿∏ï¿∏ï¿∏ÌŸXï¿∏V
    > appendOffset(this, offset, attr.toXMLString(new RenderContext(getDocument().isHTML())).length());
    > - // ŸÅ‘ã≠É‚Ç≈Á
    > + // ï¿∏Å‘ï¿∏É‚Ç≈ï¿∏
    > attrImpl.setOffset(offset);
    > attrImpl.setLength(attrImpl.toXMLString(new RenderContext(getDocument().isHTML())).length());
    > _attributes.add(attrImpl);
    > }
    > else {
    > - // ≠±≠Ì∂êŸΩ≠Í∞A∞g∞…∞r∞∑™[∞g≠ÌsetValue∞™∞\∞b∞h„à≠Å∞C∞x∞„∞g‰–≈Î
    > + // ï¿∏ï¿∏ï¿∏Ì∂êŸΩï¿∏Í∞Aï¿∏gï¿∏ï¿∏ï¿∏rï¿∏ï¿∏ï¿∏[ï¿∏gï¿∏ï¿∏setValueï¿∏ï¿∏ï¿∏\ï¿∏bï¿∏hï¿∏ï¿∏ï¿∏Å∞Cï¿∏xï¿∏ï¿∏ï¿∏gï¿∏ï¿∏ï¿∏ï¿∏
    > FuzzyXMLAttributeImpl attrImpl = (FuzzyXMLAttributeImpl) attrNode;
    > attrImpl.setValue(attr.getValue());
    > }
    >.. -479,14 +481,14 @@
    >
    > public void removeAttributeNode(FuzzyXMLAttribute attr) {
    > if (_attributes.contains(attr)) {
    > - // ∞f∞^∞b∞`
    > + // ï¿∏fï¿∏^ï¿∏bï¿∏`
    > ((AbstractFuzzyXMLNode) attr).setParentNode(null);
    > ((AbstractFuzzyXMLNode) attr).setDocument(null);
    > - // ∞…∞X∞g≠©≠çŸí∂˛
    > + // ï¿∏ï¿∏ï¿∏Xï¿∏gï¿∏ï¿∏ï¿∏ï¿∏í∂˛
    > _attributes.remove(attr);
    > - // ∞C∞x∞„∞g≠̉–≈Î
    > + // ï¿∏Cï¿∏xï¿∏ï¿∏ï¿∏gï¿∏̉ï¿∏ï¿∏ï¿∏
    > fireModifyEvent("", attr.getOffset(), attr.getLength());
    > - // √Ê‚u∂îñ≠ÌŸX∆V
    > + // ï¿∏Ê‚uï¿∏ï¿∏ï¿∏ÌŸXï¿∏V
    > appendOffset(this, attr.getOffset(), attr.getLength() * -1);
    > }
    > }
    >.. -549,6 +551,10 @@
    > }
    >
    > public void toXMLString(RenderContext renderContext, StringBuffer xmlBuffer) {
    > + if (isSynthetic()) {
    > + return;
    > + }
    > +
    > boolean isHTML = renderContext.isHtml();
    >
    > boolean renderSurroundingTags = true;
    >.. -614,12 +620,12 @@
    > if (obj instanceof FuzzyXMLElement) {
    > FuzzyXMLElement element = (FuzzyXMLElement) obj;
    >
    > - // ∞^∞O≠̈πŒO≠ª√á≠Á≠∏≠çfalse
    > + // ï¿∏^ï¿∏Oï¿∏̈ï¿∏ï¿∏Oï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏false
    > if (!element.getName().equals(getName())) {
    > return false;
    > }
    >
    > - // ∆e≠ª˜πû≠Æ≠ànull≠≤≠Á≠∏≠çtrue
    > + // ï¿∏eï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏Æ≠ï¿∏nullï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏true
    > FuzzyXMLNode parent = element.getParentNode();
    > if (parent == null) {
    > if (getParentNode() == null) {
    >.. -628,7 +634,7 @@
    > return false;
    > }
    >
    > - // …J⁄n∞I∞t∞Z∞b∞g≠ª„¯≠¶≠≤≠Á≠∏≠çtrue
    > + // ï¿∏Jï¿∏nï¿∏Iï¿∏tï¿∏Zï¿∏bï¿∏gï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏ï¿∏true
    > if (element.getOffset() == getOffset()) {
    > return true;
    > }
    >.. -781,4 +787,12 @@
    > public boolean isHidden() {
    > return getName() == null || getName().equals("");
    > }
    > +
    > + public void setSynthetic(boolean synthetic) {
    > + _synthetic = synthetic;
    > + }
    > +
    > + public boolean isSynthetic() {
    > + return _synthetic;
    > + }
    > }
    >
    > Modified: branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/internal/FuzzyXMLFormatComposite.java
    > ===================================================================
    > --- branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/internal/FuzzyXMLFormatComposite.java 2010-10-03 21:15:19 UTC (rev 6167)
    > +++ branches/eclipse_3_6/wolips/core/plugins/org.objectstyle.wolips.wodclipse.core/java/jp/aonir/fuzzyxml/internal/FuzzyXMLFormatComposite.java 2010-10-03 21:16:16 UTC (rev 6168)
    >.. -332,4 +332,9 @@
    > }
    > return false;
    > }
    > +
    > + public boolean isSynthetic() {
    > + FuzzyXMLNode _node = unwrap(delegate);
    > + return _node.isSynthetic();
    > + }
    > }
    >



    This archive was generated by hypermail 2.0.0 : Sun Oct 03 2010 - 21:18:33 UTC