/*******************************************************************************
 * Copyright (c) 2004, 2014 IBM Corporation and Others
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.actf.examples.adesigner.eval.html.internal;

import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeSet;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.actf.model.dom.dombycom.IDocumentEx;
import org.eclipse.actf.model.dom.dombycom.IStyleSheet;
import org.eclipse.actf.model.dom.dombycom.IStyleSheets;
import org.eclipse.actf.model.dom.html.DocumentTypeUtil;
import org.eclipse.actf.visualization.engines.blind.TextCheckResult;
import org.eclipse.actf.visualization.engines.blind.TextChecker;
import org.eclipse.actf.visualization.eval.html.HtmlEvalUtil;
import org.eclipse.actf.visualization.eval.html.HtmlTagUtil;
import org.eclipse.actf.visualization.eval.problem.HighlightTargetId;
import org.eclipse.actf.visualization.eval.problem.HighlightTargetNodeInfo;
import org.eclipse.actf.visualization.eval.problem.IProblemItem;
import org.eclipse.actf.visualization.eval.problem.ProblemItemImpl;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.html.HTMLImageElement;

import com.ibm.icu.text.MessageFormat;

@SuppressWarnings("unused")
public class CheckEngine extends HtmlTagUtil {

	// use org.w3c.dom.traversal, XPath

	private static final String SPACE_STR = " "; //$NON-NLS-1$

	private static final String WINDOW_OPEN = "window.open"; //$NON-NLS-1$

	public static final int ITEM_COUNT = 1000;

	private static final int QUOTATION_SHORT_NUM = 10;

	private static final int TABLE_CELL_ABBR_CHARS = 30;

	private static final int TABLE_CELL_ABBR_WORDS = 10;

	private static final Pattern COMMENT = Pattern.compile("/\\*.*?\\*/",
			Pattern.DOTALL | Pattern.CASE_INSENSITIVE);

	private static final Pattern FIXSIZE_PATTERN = Pattern
			.compile(
					".*\\{[^\\}]*font-size(\\p{Space})*:[^;]*(mm|cm|in|pt|pc|px).*\\}.*",
					Pattern.DOTALL | Pattern.CASE_INSENSITIVE);

	private static final Pattern FIXSIZE_PATTERN_ATTR = Pattern.compile(
			"font-size(\\p{Space})*:[^;]*(mm|cm|in|pt|pc|px)", Pattern.DOTALL
					| Pattern.CASE_INSENSITIVE);

	private static final Pattern BLINK_PATTERN = Pattern.compile(
			".*\\{[^\\}]*text-decoration(\\p{Space})*:[^;]*blink.*\\}.*",
			Pattern.DOTALL | Pattern.CASE_INSENSITIVE);

	private static final Pattern BLINK_PATTERN_ATTR = Pattern.compile(
			"text-decoration(\\p{Space})*:[^;]*blink.*", Pattern.DOTALL
					| Pattern.CASE_INSENSITIVE);

	private static final Pattern BEFORE_PATTERN = Pattern.compile(
			".*:before(\\p{Space})*\\{[^\\}]*content(\\p{Space})*:.*\\}.*",
			Pattern.DOTALL | Pattern.CASE_INSENSITIVE);

	private static final Pattern AFTER_PATTERN = Pattern.compile(
			".*:after(\\p{Space})*\\{[^\\}]*content(\\p{Space})*:.*\\}.*",
			Pattern.DOTALL | Pattern.CASE_INSENSITIVE);

	// not strict check
	private static final String CSS_COLORS = "(aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen|ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText|inherit|currentColor|rgb[a]?\\(.*\\)|hsl[a]?\\(.*\\)|#[a-f0-9]{3}|#[a-f0-9]{6})";

	// TODO media / import / comment <!-- -->
	private static final Pattern STYLEITEM = Pattern.compile(".*?\\{.*?\\}",
			Pattern.DOTALL);
	private static final Pattern COLOR = Pattern.compile(
			"\\{(.*[^-]+)?color(\\p{Space})*:.*\\}", Pattern.DOTALL
					| Pattern.CASE_INSENSITIVE);
	private static final Pattern BGCOLOR = Pattern.compile(
			"\\{.*background-color(\\p{Space})*:.*\\}", Pattern.DOTALL
					| Pattern.CASE_INSENSITIVE);
	private static final Pattern BGCOLOR2 = Pattern.compile(
			"\\{.*background(\\p{Space})*:.*" + CSS_COLORS + ".*\\}",
			Pattern.DOTALL | Pattern.CASE_INSENSITIVE);

	private static final Pattern COLOR_ATTR = Pattern.compile(
			"(((.*[^\\-]+)color)|(\\p{Space})*color)(\\p{Space})*:.*",
			Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
	private static final Pattern BGCOLOR_ATTR = Pattern.compile(
			".*background-color(\\p{Space})*:.*", Pattern.DOTALL
					| Pattern.CASE_INSENSITIVE);
	private static final Pattern BGCOLOR2_ATTR = Pattern.compile(
			".*background(\\p{Space})*:.*" + CSS_COLORS + ".*", Pattern.DOTALL
					| Pattern.CASE_INSENSITIVE);

	@SuppressWarnings("nls")
	private static final String[] ASCII_ART_CHAR = { "\u2227", "\uff3f",
			"\uffe3", "\uff20", "\uff0f", "\uff3c", "\u03b3", "\u03a6",
			"\u2229", "\u222a", "\u03b9", "\uff2f", "\u2282", "\uff9f",
			"\u0414", "\u03c3", "\uff65", "\u2200", "\u2211", "i", "o", "0",
			"_", "\uff3f", "\uffe3", "\u00b4", "\uff40", "\u30fe" };

	private static Set<String> artCharSet;

	static {
		artCharSet = new HashSet<String>();
		for (int i = 0; i < ASCII_ART_CHAR.length; i++) {
			artCharSet.add(ASCII_ART_CHAR[i]);
		}
	}

	private static Method[] checkMethods;
	private static Method[] mobileCheckMethods;

	static {
		Method[] tmpM = CheckEngine.class.getDeclaredMethods();
		checkMethods = new Method[1000];// TODO
		mobileCheckMethods = new Method[1000];// TODO
		for (Method m : tmpM) {
			String name = m.getName();
			if (name.startsWith("item_")) { //$NON-NLS-1$
				try {
					int itemNum = Integer.parseInt(name.substring(5));
					checkMethods[itemNum] = m;
				} catch (Exception e) {
				}
			} else if (name.startsWith("mobile_")) { //$NON-NLS-1$
				try {
					int itemNum = Integer.parseInt(name.substring(7));
					mobileCheckMethods[itemNum] = m;
				} catch (Exception e) {
				}
			}
		}
	}

	private static final String[] AUDIO_FILE_EXTENSION = {
			"mp3", "mid", "mrm", "mrl", "vqf", "wav" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$

	private static final String[] MULTIMEDIA_FILE_EXTENSION = {
			"avi", "ram", "rm", "asf", "wm", "wmx", "wmv", "asx", "mpeg", "mpg" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$

	/**
	 * debug flag for developers!
	 */
	private static final boolean DEBUG = false;

	private Set<String> blockEleSet = HtmlTagUtil.getBlockElementSet();

	private Document target;

	private Document resultDoc;

	private URL baseUrl;

	private Map<Node, Integer> document2IdMap;

	// private Vector html2ViewMapData;

	private boolean isDBCS;

	private Vector<IProblemItem> result;

	private boolean[] items;

	private int validate_str_len;

	private int valid_total_text_len;

	private boolean hasAwithHref = false;

	private Element[] aWithHref_elements;

	private String[] aWithHref_hrefs;

	private String[] aWithHref_strings;

	private HTMLImageElement[] img_elements;

	private Element[] table_elements;

	private Element[] body_elements;

	private Element[] frame_elements;

	private Element[] iframe_elements;

	private Element[] object_elements;

	private Element[] embed_elements;

	private Element[] parent_table_elements;

	private Element[] bottom_data_tables;

	private Element[] bottom_1row1col_tables;

	private Element[] bottom_notdata_tables;

	private Element[] headings;

	private double invalidLinkRatio;

	private boolean isXHTML = false;

	private List<Element> labelList;
	private List<Element> formList;
	private Vector<Node> formVwithText;
	private List<Element> layoutTableList;
	private List<Element> dataTableList;
	private TextChecker checker;

	private List<Element> elementsWithStyleList;
	private Map<Element, String> styleElementMap = new HashMap<Element, String>();

	private int liveObject = 0;
	private int liveEmbed = 0;

	// private int invisibleElementCount = 0;
	// private String[] invisibleLinkStrings = new String[0];

	private HtmlEvalUtil edu;

	private String docTypeS;

	private Map<IStyleSheet, String> styleSheetsMap = new HashMap<IStyleSheet, String>();

	/**
	 * 
	 */
	public CheckEngine(HtmlEvalUtil edu, boolean[] checkItems) {
		this.edu = edu;
		this.target = edu.getTarget();
		this.resultDoc = edu.getResult();
		Document tmpD = edu.getLiveDom();
		if (tmpD instanceof IDocumentEx) {
			IStyleSheets styleSheets = ((IDocumentEx) tmpD).getStyleSheets();
			prepStyleSheets(styleSheets);
			liveObject = tmpD.getElementsByTagName("object").getLength();
			liveEmbed = tmpD.getElementsByTagName("embed").getLength();
		}

		baseUrl = edu.getBaseUrl();

		invalidLinkRatio = 0;

		this.items = checkItems;

		this.document2IdMap = edu.getDocument2IdMap();
		// this.html2ViewMapData = edu.getHtml2ViewMapData();

		this.isDBCS = edu.isDBCS();
		if (isDBCS) {
			validate_str_len = 20;
			valid_total_text_len = 50;
		} else {
			validate_str_len = 50;
			valid_total_text_len = 100;
		}
		result = new Vector<IProblemItem>();

		hasAwithHref = edu.isHasAwithHref();

		aWithHref_elements = edu.getAWithHref_elements();
		aWithHref_hrefs = edu.getAWithHref_hrefs();
		aWithHref_strings = edu.getAWithHref_strings();

		img_elements = edu.getImg_elements();

		table_elements = edu.getTable_elements();
		bottom_data_tables = edu.getBottom_data_tables();
		bottom_1row1col_tables = edu.getBottom_1row1col_tables();
		bottom_notdata_tables = edu.getBottom_notdata_tables();
		parent_table_elements = edu.getParent_table_elements();
		// for new JIS
		layoutTableList = new ArrayList<Element>();
		layoutTableList.addAll(Arrays.asList(parent_table_elements));
		layoutTableList.addAll(Arrays.asList(bottom_1row1col_tables));
		layoutTableList.addAll(Arrays.asList(bottom_notdata_tables));
		dataTableList = new ArrayList<Element>();
		dataTableList.addAll(Arrays.asList(bottom_data_tables));
		assert table_elements.length == layoutTableList.size()
				+ dataTableList.size();

		body_elements = edu.getBody_elements();
		frame_elements = edu.getFrame_elements();
		iframe_elements = edu.getIframe_elements();
		object_elements = edu.getObject_elements();
		embed_elements = edu.getEmbed_elements();

		formList = edu.getElementsList(target, "form"); //$NON-NLS-1$

		elementsWithStyleList = edu.getElementsWithStyle();
		List<Element> styleElementList = edu.getStyleElements();
		for (Element e : styleElementList) {
			if (e.hasChildNodes()) {
				Node n = e.getFirstChild();
				String style = n.getNodeValue();

				String[] results = COMMENT.split(style);
				String resultS = "";
				for (String tmpS : results) {
					resultS = resultS + tmpS;
				}
				styleElementMap.put(e, resultS);
			}
		}

		headings = edu.getHeadings();

		DocumentType docType = target.getDoctype();
		docTypeS = DocumentTypeUtil.getOriginalID(docType);
		if (docTypeS.indexOf("XHTML") > 0) {
			isXHTML = true;
		}
		checker = TextChecker.getInstance();

	}

	private void prepStyleSheets(IStyleSheets styleSheets) {
		if (styleSheets != null) {
			for (int i = 0; i < styleSheets.getLength(); i++) {
				IStyleSheet ss = styleSheets.item(i);

				// comments are already removed
				// String[] results = COMMENT.split(ss.getCssText());
				// String resultS = "";
				// for (String tmpS : results) {
				// resultS = resultS + tmpS;
				// }
				// styleSheetsMap.put(ss, resultS);

				styleSheetsMap.put(ss, ss.getCssText());
				prepStyleSheets(ss.getImports());
			}
		}
	}

	/**
	 * Checking main routine. This method invokes each item_*() methods by Java
	 * reflection, based on user's guidelines preference.
	 * 
	 * @return
	 */
	public Vector<IProblemItem> check() {
		// show list of techniques used in all problem items
		/*
		 * if (DEBUG) { if (false) { for (ITechniquesItem tech :
		 * GuidelineHolder.getInstance() .getTechniquesItemSet()) {
		 * System.out.println(tech.getId()); } }
		 * 
		 * Set<ITechniquesItem> techSet = GuidelineHolder.getInstance()
		 * .getTechniquesItemSet(); Map<String, Set<IProblemItem>> techProbMap =
		 * GuidelineHolder .getInstance().getTechProbMap();
		 * 
		 * for (ITechniquesItem tech : techSet) { for (IProblemItem pitem :
		 * techProbMap.get(tech.getId())) { System.out.println(tech.getId() +
		 * "\t" + pitem.getId() + "\t" + pitem.getSeverityStr() + "\t" +
		 * pitem.getDescription()); } }
		 * System.out.println(GuidelineHolder.getInstance()); }
		 */

		// not required to use for WCAG 2.0
		// checkDomDifference();

		validateHtml();

		Object[] tmpO = null;
		for (int i = 0; i < items.length; i++) {
			if (items[i] && null != checkMethods[i]) {
				try {
					checkMethods[i].invoke(this, tmpO);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		// always
		if (items.length < 90 || !items[89]) {
			item_89();
		}

		formCheck();
		styleCheck();
		mediaCheck();
		always();

		for (int i = 0; i < mobileCheckMethods.length; i++) {
			if (null != mobileCheckMethods[i]) {
				try {
					mobileCheckMethods[i].invoke(this, tmpO);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

		edu.getPageData().setInvalidLinkRatio(invalidLinkRatio);

		return (result);
	}

	private IProblemItem addCheckerProblem(String strId) {
		IProblemItem tmpCP = new ProblemItemImpl(strId);
		result.add(tmpCP);
		return (tmpCP);
	}

	private IProblemItem addCheckerProblem(String strId, String targetStr) {
		IProblemItem tmpCP = new ProblemItemImpl(strId);
		tmpCP.setTargetString(targetStr);
		result.add(tmpCP);
		return (tmpCP);
	}

	private IProblemItem addCheckerProblem(String strId, Element target) {
		return addCheckerProblem(strId, "", target); //$NON-NLS-1$
	}

	private IProblemItem addCheckerProblem(String strId, String targetStr,
			Element target) {
		IProblemItem tmpCP = new ProblemItemImpl(strId, target);
		tmpCP.setHighlightTargetNodeInfo(new HighlightTargetNodeInfo(target));
		tmpCP.setTargetString(targetStr);
		result.add(tmpCP);

		return (tmpCP);
	}

	private IProblemItem addCheckerProblem(String strId, Element startTarget,
			Element endTarget) {
		IProblemItem tmpCP = new ProblemItemImpl(strId, startTarget);
		tmpCP.setHighlightTargetNodeInfo(new HighlightTargetNodeInfo(
				startTarget, endTarget));
		result.add(tmpCP);
		return (tmpCP);
	}

	private IProblemItem addCheckerProblem(String strId, String targetStr,
			Vector<Node> targetV) {
		IProblemItem tmpCP = new ProblemItemImpl(strId);
		tmpCP.setTargetString(targetStr);
		tmpCP.setHighlightTargetNodeInfo(new HighlightTargetNodeInfo(targetV));
		result.add(tmpCP);
		return tmpCP;
	}

	private IProblemItem addCheckerProblem(String strId, String targetStr,
			NodeList targetNL) {
		Vector<Node> targetV = new Vector<Node>();
		for (int i = 0; i < targetNL.getLength(); i++) {
			targetV.add(targetNL.item(i));
		}
		return addCheckerProblem(strId, targetStr, targetV);
	}

	private void item_0() {
		for (Element applet : edu.getAppletElements()) {
			boolean bHasAlt = false;
			boolean bHasText = false;

			// justify if has alt attribute

			String strAlt = applet.getAttribute(ATTR_ALT);
			if (strAlt.length() > 0) {
				bHasAlt = true;
			}

			String desText = getTextAltDescendant(applet);
			bHasText = (desText.length() > 0);

			if (!bHasAlt)
				addCheckerProblem("C_0.0", applet); //$NON-NLS-1$
			if (!bHasText) {
				addCheckerProblem("C_0.1", applet); //$NON-NLS-1$

				// alternative link alert
				// check descendant text or image
				// addCheckerProblem("C_0.1", el);
			}
		}
	}

	private void item_1() {

		for (int i = 0; i < object_elements.length; i++) {
			Element el = object_elements[i];

			/*
			 * boolean bReported = false;
			 * 
			 * boolean bHasTextImg = hasTextDescendant(el); if (!bHasTextImg) {
			 * NodeList imgNl = el.getElementsByTagName("img"); //$NON-NLS-1$ if
			 * (imgNl.getLength() > 0) { // need alt description check
			 * bHasTextImg = true; } } if (!bHasTextImg) { // text or img check
			 * addCheckerProblem("C_1.1", el); //$NON-NLS-1$ bReported = true; }
			 * 
			 * if (!bReported) { // alert // check links inside an OBJECT
			 * element, or a description link. // addCheckerProblem("C_1.2",
			 * el); }
			 */

			if (getTextAltDescendant(el).trim().length() == 0) {
				addCheckerProblem("C_1.1", el); //$NON-NLS-1$
			}
		}

	}

	private void item_2() {

		NodeList nl = target.getElementsByTagName("input"); //$NON-NLS-1$
		int length = nl.getLength();
		for (int i = 0; i < length; i++) {
			Element el = (Element) nl.item(i);
			String strType = el.getAttribute("type"); //$NON-NLS-1$
			if (strType != null && strType.equalsIgnoreCase("image")) { //$NON-NLS-1$
				String strUsemap;
				boolean bIsMap;
				try {
					bIsMap = ((HTMLImageElement) el).getIsMap();
					strUsemap = ((HTMLImageElement) el).getUseMap();
				} catch (RuntimeException e) {
					bIsMap = false;
					strUsemap = ""; //$NON-NLS-1$
				}
				if (bIsMap || !strUsemap.equals("")) { //$NON-NLS-1$
					// 1.1 server-side image map as submit button alert
					addCheckerProblem("C_2.0", el); //$NON-NLS-1$

					// // 9.1 alert: please use client-side image map
					// addCheckerProblem("C_2.2",el);
				}
			}
		}

		// nl = target.getElementsByTagName("img");
		// length = nl.getLength();
		for (int i = 0; i < img_elements.length; i++) {
			Element el = img_elements[i];
			String strUsemap = ((HTMLImageElement) el).getUseMap();
			if (((HTMLImageElement) el).getIsMap() && strUsemap.equals("")) { //$NON-NLS-1$
				// 1.2 server side image map
				addCheckerProblem("C_2.1", el); //$NON-NLS-1$

				// 9.1 alert: please use client-side image map
				addCheckerProblem("C_2.2", el); //$NON-NLS-1$
			}
		}
	}

	private void item_3() {
		for (Element el : img_elements) {
			if (el.hasAttribute("longdesc")) { //$NON-NLS-1$
				String strLongDesc = el.getAttribute("longdesc"); //$NON-NLS-1$
				// original aDesigner routine
				if (strLongDesc.length() > 0) {
					boolean isDlink = false;
					// need to check distance
					int length = aWithHref_hrefs.length;
					for (int j = 0; j < length; j++) {
						// must use URL as in 58?
						if (strLongDesc.equalsIgnoreCase(aWithHref_hrefs[j])) {
							String strValue = aWithHref_strings[j];
							if (strValue.trim().equalsIgnoreCase("d")) { //$NON-NLS-1$
								isDlink = true;
								break;
							}
						}
					}
					if (!isDlink) { // d link check
						addCheckerProblem("C_3.0", el); //$NON-NLS-1$
					}
				}
				// For new JIS
				addCheckerProblem("C_3.1", el); //$NON-NLS-1$
			}
		}
	}

	private void item_4() {
		// need to refine conditions
		Vector<Node> nodeV = new Vector<Node>();
		for (int i = 0; i < img_elements.length; i++) {
			Element el = img_elements[i];
			if (isNormalImage(el)) {
				if (el.hasAttribute(ATTR_ALT)) {
					String strAlt = el.getAttribute(ATTR_ALT);
					if (getWordCount(strAlt) >= 3
							|| strAlt.length() >= validate_str_len) {
						if (!strAlt.matches("\\p{ASCII}*") //$NON-NLS-1$
								|| strAlt.length() > 30) {
							nodeV.add(el);
						}
					}
				}
			}
		}
		if (nodeV.size() > 0) {
			addCheckerProblem("C_4.0", "", nodeV); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	private void item_5() {
		int length = aWithHref_elements.length;
		for (int i = 0; i < length; i++) {
			Element el = aWithHref_elements[i];
			String strHref = aWithHref_hrefs[i];
			if (strHref != null && strHref.length() > 0) {
				String strExt = getFileExtension(strHref);
				if (isAudioFileExt(strExt)) {
					// 1.1 audio alert
					addCheckerProblem("C_5.0", el); //$NON-NLS-1$
					break;
				} else if (isMultimediaFileExt(strExt)) {
					// 1.1
					addCheckerProblem("C_5.1", el); //$NON-NLS-1$
					// 1.3
					addCheckerProblem("C_5.2", el); //$NON-NLS-1$
					// 1.4
					addCheckerProblem("C_5.3", el); //$NON-NLS-1$
					break;
				}
			}
		}
	}

	private void item_6() {
		if (body_elements.length > 0) {
			Element bodyEl = body_elements[0];
			Stack<Node> stack = new Stack<Node>();
			Node curNode = bodyEl;

			while (curNode != null) {
				boolean isArtStr = false;
				if (isLeafBlockEle(curNode)
						&& isAsciiArtString(getTextAltDescendant(curNode))) {
					addCheckerProblem("C_6.0", (Element) curNode); //$NON-NLS-1$
					addCheckerProblem("C_6.1", (Element) curNode); //$NON-NLS-1$
					isArtStr = true;
				}

				if (!isArtStr && curNode.hasChildNodes()) {
					stack.push(curNode);
					curNode = curNode.getFirstChild();
				} else if (curNode.getNextSibling() != null) {
					curNode = curNode.getNextSibling();
				} else {
					curNode = null;
					while ((curNode == null) && (stack.size() > 0)) {
						curNode = stack.pop();
						curNode = curNode.getNextSibling();
					}
				}
			}
		}
	}

	private void item_7() {
		int aLength = aWithHref_elements.length;
		NodeList nl = target.getElementsByTagName("area"); //$NON-NLS-1$
		int areaLen = nl.getLength();
		for (int i = 0; i < areaLen; i++) {
			boolean bHasLink = false;
			Element el = (Element) nl.item(i);
			String strHref = ""; //$NON-NLS-1$
			if (el.hasAttribute(HtmlTagUtil.ATTR_HREF)) {
				strHref = el.getAttribute(HtmlTagUtil.ATTR_HREF);
				if (strHref.length() > 0) {
					for (int j = 0; j < aLength; j++) {
						// TODO use URL
						if (strHref.equalsIgnoreCase(aWithHref_hrefs[j])) {
							bHasLink = true;
							break;
						}
					}
				}
			}
			if (!bHasLink) { // link check
				addCheckerProblem("C_7.0", " (href=\"" + strHref + "\")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			}
		}
	}

	private void item_8() {
		// TODO add color info to Description
		NodeList nl = target.getElementsByTagName("font"); //$NON-NLS-1$
		Vector<Node> nodeV = new Vector<Node>();
		int length = nl.getLength();
		for (int i = 0; i < length; i++) {
			Element el = (Element) nl.item(i);
			if (el.hasAttribute("color") || el.hasAttribute("bgcolor")) { //$NON-NLS-1$ //$NON-NLS-2$
				String strColor, strBgColor;
				strColor = el.getAttribute("color"); //$NON-NLS-1$
				strBgColor = el.getAttribute("bgcolor"); //$NON-NLS-1$
				if (!strColor.equals("") || !strBgColor.equals("")) { //$NON-NLS-1$ //$NON-NLS-2$
					nodeV.add(el);
				}
			}
		}
		if (nodeV.size() > 0) {
			addCheckerProblem("C_8.0", "", nodeV); //$NON-NLS-1$ //$NON-NLS-2$
		}

		// need to handle CSS
	}

	private void item_9() {
		// Use markup language alert
		boolean bHasNormalImage = false;
		for (int i = 0; i < img_elements.length; i++) {
			Element el = img_elements[i];
			if (isNormalImage(el)) {
				bHasNormalImage = true;
				break;
			}
		}
		if (bHasNormalImage)
			addCheckerProblem("C_9.0"); //$NON-NLS-1$
	}

	private void item_10() {
		// formal grammars alert
		addCheckerProblem("C_10.0"); //$NON-NLS-1$
	}

	private void item_12() {
		for (int i = 0; i < parent_table_elements.length; i++) {
			Element el = parent_table_elements[i];
			Stack<Node> stack = new Stack<Node>();
			Node curNode = el.getFirstChild();
			int tableCount = 0;
			int maxCount = 0;
			String strName = ""; //$NON-NLS-1$
			while (curNode != null) {
				strName = curNode.getNodeName();
				if (curNode.getNodeType() == Node.ELEMENT_NODE
						&& strName.equalsIgnoreCase("table")) { //$NON-NLS-1$
					tableCount++;
					if (maxCount < tableCount)
						maxCount = tableCount;
				}

				if (curNode.hasChildNodes()) {
					stack.push(curNode);
					curNode = curNode.getFirstChild();
				} else if (curNode.getNextSibling() != null) {
					if ((curNode.getNodeType() == Node.ELEMENT_NODE)
							&& curNode.getNodeName().equals("table")) { //$NON-NLS-1$
						tableCount--;
					}
					curNode = curNode.getNextSibling();
				} else {
					if ((curNode.getNodeType() == Node.ELEMENT_NODE)
							&& curNode.getNodeName().equals("table")) { //$NON-NLS-1$
						tableCount--;
					}
					curNode = null;
					while ((curNode == null) && (stack.size() > 0)) {
						curNode = stack.pop();
						if ((curNode.getNodeType() == Node.ELEMENT_NODE)
								&& curNode.getNodeName().equals("table")) { //$NON-NLS-1$
							tableCount--;
						}
						curNode = curNode.getNextSibling();
					}
				}
			}
			if (maxCount > 0) {
				String str = null;
				if (maxCount == 1) {
					str = Messages.CheckEngine_ChildTable;
				} else {
					str = MessageFormat.format(
							Messages.CheckEngine_TieredChildTable,
							new Object[] { String.valueOf(maxCount) });
				}
				addCheckerProblem("C_12.0", str, el); //$NON-NLS-1$
			} else
				; // Unreachable code!
		} // end of top-most for loop
		for (int i = 0; i < bottom_1row1col_tables.length; i++) {
			addCheckerProblem("C_12.1", //$NON-NLS-1$
					bottom_1row1col_tables[i]);
		}

		for (int i = 0; i < bottom_notdata_tables.length; i++) {
			addCheckerProblem("C_12.2", //$NON-NLS-1$
					bottom_notdata_tables[i]);
		}
	}

	private void item_13() {
		// font
		NodeList nl = target.getElementsByTagName("font"); //$NON-NLS-1$
		int length = nl.getLength();
		Vector<Node> nodeV = new Vector<Node>();
		for (int i = 0; i < length; i++) {
			Element el = (Element) nl.item(i);
			if (el.hasAttribute("size")) { //$NON-NLS-1$
				String strSize = el.getAttribute("size"); //$NON-NLS-1$
				if (strSize != null && strSize.length() > 0) {
					if (strSize.indexOf("+") == -1 //$NON-NLS-1$
							&& strSize.indexOf("-") == -1) { // absolute size  //$NON-NLS-1$
						nodeV.add(el);
					}
				}
			}
		}
		if (nodeV.size() > 0) {
			addCheckerProblem("C_13.0", "", nodeV); //$NON-NLS-1$ //$NON-NLS-2$
		}

		// table
		checkAbsoluteSize("table"); //$NON-NLS-1$
		// tr
		checkAbsoluteSize("tr"); //$NON-NLS-1$
		// td
		checkAbsoluteSize("td"); //$NON-NLS-1$
		// col
		checkAbsoluteSize("col"); //$NON-NLS-1$
		// frames,style sheets?
	}

	private void item_14() {

		int curLevel = 0;
		int lastLevel = 0;
		for (int i = 0; i < headings.length; i++) {
			curLevel = edu.getHeadingLevel(headings[i].getNodeName());
			if (curLevel > 0) {
				if (lastLevel > 0) {
					if (curLevel - lastLevel > 1) {
						// heading level check

						String targetStr = MessageFormat.format(
								Messages.CheckEngine_Headings, new Object[] {
										curLevel, lastLevel });
						Vector<Node> tmpV = new Vector<Node>();
						tmpV.add(headings[i - 1]);
						tmpV.add(headings[i]);
						addCheckerProblem("C_14.0", targetStr, tmpV); //$NON-NLS-1$
					}
				}
				lastLevel = curLevel;
			}
		}

	}

	private void item_15() {
		Vector<Node> targetV = new Vector<Node>();

		for (int i = 0; i < headings.length; i++) {
			targetV.add(headings[i]);
		}

		if (targetV.size() > 0) {
			addCheckerProblem("C_15.0", "", targetV); //$NON-NLS-1$  //$NON-NLS-2$
		}
	}

	private void item_16() {
		// DL, DT, DD, UL, OL, LI
		// checkListElement("dl");
		// checkListElement("dt");
		// checkListElement("dd");
		// checkListElement("ul");
		// checkListElement("ol");
		// checkListElement("li");
		NodeList nl = target.getElementsByTagName("ol"); //$NON-NLS-1$
		int length = nl.getLength();
		for (int i = 0; i < length; i++) {
			Element el = (Element) nl.item(i);
			NodeList liNl = el.getElementsByTagName("li"); //$NON-NLS-1$
			if (liNl.getLength() == 0) { // list element alert
				addCheckerProblem("C_16.1", el); //$NON-NLS-1$
			}
		}

		nl = target.getElementsByTagName("ul"); //$NON-NLS-1$
		length = nl.getLength();
		for (int i = 0; i < length; i++) {
			Element el = (Element) nl.item(i);
			NodeList liNl = el.getElementsByTagName("li"); //$NON-NLS-1$
			if (liNl.getLength() == 0) { // list element alert
				addCheckerProblem("C_16.1", el); //$NON-NLS-1$
			}
		}

		nl = target.getElementsByTagName("li"); //$NON-NLS-1$
		length = nl.getLength();
		Vector<Node> liVec = new Vector<Node>();
		for (int i = 0; i < length; i++) {
			boolean bHasUlOl = false;
			Node curNode = nl.item(i);
			if (liVec.contains(curNode))
				continue;
			String strName = ""; //$NON-NLS-1$
			while (curNode != null) {
				strName = curNode.getNodeName();
				if (strName.equalsIgnoreCase("ol") //$NON-NLS-1$
						|| strName.equalsIgnoreCase("ul")) { //$NON-NLS-1$
					bHasUlOl = true;
					break;
				} else if (strName.equalsIgnoreCase("body")) { //$NON-NLS-1$
					break;
				}
				curNode = curNode.getParentNode();
			}
			if (!bHasUlOl) {
				Node startNode = nl.item(i);
				Node endNode = nl.item(i);
				liVec.add(nl.item(i));
				Node preNode = nl.item(i).getPreviousSibling();
				while (preNode != null) {
					if (preNode.getNodeName().equalsIgnoreCase("li") //$NON-NLS-1$
							&& !liVec.contains(preNode)) {
						liVec.add(preNode);
						startNode = preNode;
					} else
						break;
					preNode = preNode.getPreviousSibling();
				}
				Node nextNode = nl.item(i).getNextSibling();
				while (nextNode != null) {
					if (nextNode.getNodeName().equalsIgnoreCase("li") //$NON-NLS-1$
							&& !liVec.contains(nextNode)) {
						liVec.add(nextNode);
						endNode = nextNode;
					} else
						break;
					nextNode = nextNode.getNextSibling();
				}
				// list element alert
				addCheckerProblem(
						"C_16.2", (Element) startNode, (Element) endNode); //$NON-NLS-1$
			}
		}

		// dl,dt,dd
		// dir,menu > obsolete
	}

	private void item_17() {
		NodeList nl = target.getElementsByTagName("q"); //$NON-NLS-1$
		int length = nl.getLength();
		for (int i = 0; i < length; i++) {
			boolean bHasText = false;
			Node qNode = nl.item(i);
			bHasText = hasTextDescendant(qNode);
			if (!bHasText) { // quotation check
				Element el = (Element) qNode;
				addCheckerProblem("C_17.0", el); //$NON-NLS-1$
			}
		} // blockquote
		nl = target.getElementsByTagName("blockquote"); //$NON-NLS-1$
		length = nl.getLength();
		for (int i = 0; i < length; i++) {
			boolean bHasText = false;
			Node qNode = nl.item(i);
			bHasText = hasTextDescendant(qNode);
			if (!bHasText) { // quotation check
				Element el = (Element) qNode;
				addCheckerProblem("C_17.0", el); //$NON-NLS-1$
			}
		}
		if (length > 0) {
			addCheckerProblem("C_17.1", "", nl); //$NON-NLS-1$
		}
	}

	private void item_18() {
		NodeList nl = target.getElementsByTagName("q"); //$NON-NLS-1$
		int length = nl.getLength();
		for (int i = 0; i < length; i++) {
			Node qNode = nl.item(i);
			String str = getTextDescendant(qNode);
			if (str.length() > QUOTATION_SHORT_NUM) { // longer quotation
				// check
				Element el = (Element) qNode;
				addCheckerProblem("C_18.0", el); //$NON-NLS-1$

				str = el.getAttribute("cite"); //$NON-NLS-1$
				if (str.equals("")) { //$NON-NLS-1$
					// cite attribute check
					addCheckerProblem("C_18.2", el); //$NON-NLS-1$
				}
			}
		}

		// blockquote
		nl = target.getElementsByTagName("blockquote"); //$NON-NLS-1$
		length = nl.getLength();
		for (int i = 0; i < length; i++) {
			Node qNode = nl.item(i);
			Element el = (Element) qNode;
			String str = getTextDescendant(qNode);
			if (str.length() <= QUOTATION_SHORT_NUM) {
				// short quotation check
				addCheckerProblem("C_18.1", el); //$NON-NLS-1$
			}

			str = el.getAttribute("cite"); //$NON-NLS-1$
			if (str.equals("")) { //$NON-NLS-1$
				// cite attribute check
				addCheckerProblem("C_18.2", el); //$NON-NLS-1$
			}
		}
	}

	private void item_21() {
		Element el = target.getDocumentElement();
		String attName = isXHTML ? "xml:lang" : "lang";
		String strLang = el.getAttribute(attName);
		// System.out.println("(xml:)lang = " + strLang); // debug

		if (isEmptyString(strLang)) {
			// no lang attribute
			addCheckerProblem("C_21.0", attName, el); //$NON-NLS-1$
		} else {
			// check conformance to "BCP 47"
			LanguageTag tag = new LanguageTag(strLang, false);

			if (!tag.isWellFormed()) {
				addCheckerProblem("C_21.1", attName, el); //$NON-NLS-1$
			} else {
				// valid language
				addCheckerProblem("C_21.2", attName, el); //$NON-NLS-1$
			}
		}
	}

	private void item_22() {
		if (table_elements.length > 0) {
			Vector<Node> tables = new Vector<Node>(
					Arrays.asList(table_elements));
			addCheckerProblem("C_22.0", null, tables); //$NON-NLS-1$
		}

	}

	private void item_23() {
		for (int i = 0; i < parent_table_elements.length; i++) {
			boolean bHasTh = false;
			boolean bHasSummary = false;
			boolean bHasCaption = false;
			Element tNode = parent_table_elements[i];

			bHasSummary = (tNode.getAttribute("summary") != null && tNode
					.getAttribute("summary").length() > 0);
			bHasCaption = tNode.getElementsByTagName("caption").getLength() > 0;

			Stack<Node> stack = new Stack<Node>();
			Node curNode = tNode.getFirstChild();
			while (curNode != null) {
				String strName = ""; //$NON-NLS-1$
				strName = curNode.getNodeName();
				if (strName.equalsIgnoreCase("th")) { //$NON-NLS-1$
					bHasTh = true;
					break;
				}

				if (curNode.hasChildNodes()
						&& !strName.equalsIgnoreCase("table")) { //$NON-NLS-1$
					stack.push(curNode);
					curNode = curNode.getFirstChild();
				} else if (curNode.getNextSibling() != null) {
					curNode = curNode.getNextSibling();
				} else {
					curNode = null;
					while ((curNode == null) && (stack.size() > 0)) {
						curNode = stack.pop();
						curNode = curNode.getNextSibling();
					}
				}
			}

			if (bHasTh || bHasCaption || bHasSummary) { // table aleret
				addCheckerProblem("C_23.0", tNode); //$NON-NLS-1$
			}

			// bottom table check(layout / not)
		}

		// C_23.1/2 check. For new JIS
		List<Element> tables = new ArrayList<Element>();
		Vector<Node> table_25_1 = new Vector<Node>();
		Vector<Node> table_25_2 = new Vector<Node>();

		for (Element table : dataTableList) {
			boolean added = false;
			if (getDirectDescendantElements(table, "th").size() > 0) {
				tables.add(table);
				added = true;
			}
			if (getDirectDescendantElements(table, "caption").size() > 0) {
				if (!added) {
					tables.add(table);
					added = true;
				}
				addCheckerProblem("C_25.3", table); //$NON-NLS-1$
			} else {
				table_25_1.add(table);
			}
			if (table.hasAttribute("summary")
					&& !isEmptyString(table.getAttribute("summary"))) {
				if (!added) {
					tables.add(table);
					added = true;
				}
				addCheckerProblem("C_25.4", table); //$NON-NLS-1$
			} else {
				table_25_2.add(table);
			}
		}

		if (tables.size() > 0) {
			Vector<Node> tablesV = new Vector<Node>(tables);
			addCheckerProblem("C_23.1", "", tablesV); //$NON-NLS-1$
		}
		if (table_25_1.size() > 0)
			addCheckerProblem("C_25.1", null, table_25_1); //$NON-NLS-1$
		if (table_25_2.size() > 0)
			addCheckerProblem("C_25.2", null, table_25_2); //$NON-NLS-1$

		tables.clear();
		for (Element table : layoutTableList) {
			if (getDirectDescendantElements(table, "th").size() > 0) {
				tables.add(table);
			} else if (getDirectDescendantElements(table, "caption").size() > 0) {
				tables.add(table);
			} else if (table.hasAttribute("summary")
					&& !isEmptyString(table.getAttribute("summary"))) {
				tables.add(table);
			}
		}

		if (tables.size() > 0) {
			Vector<Node> tablesV = new Vector<Node>(tables);
			addCheckerProblem("C_23.2", "", tablesV); //$NON-NLS-1$
		}

	}

	// private void item_25() {
	// // moved to item_23()!
	// }

	private void item_26() {
		NodeList nl = target.getElementsByTagName("th"); //$NON-NLS-1$
		int length = nl.getLength();
		for (int i = 0; i < length; i++) {
			Element el = (Element) nl.item(i);
			String str = getTextAltDescendant(el);
			if (isDBCS) {
				if (str.length() > TABLE_CELL_ABBR_CHARS) {
					addCheckerProblem("C_26.0", el); //$NON-NLS-1$            		
				}
			} else {
				if (getWordCount(str) > TABLE_CELL_ABBR_WORDS) {
					addCheckerProblem("C_26.0", el); //$NON-NLS-1$
				}
			}
		}
	}

	private void item_27() {
		for (int i = 0; i < frame_elements.length; i++) {
			Element el = frame_elements[i];
			String strSrc = el.getAttribute(ATTR_SRC);

			if (!isHtmlFile(strSrc)) { // no-html file check
				addCheckerProblem("C_27.0", "(src=" + strSrc + ")", el); //$NON-NLS-1$
			}
		}

		// nl = target.getElementsByTagName("iframe"); //$NON-NLS-1$
		// length = nl.getLength();
		// for (int i = 0; i < length; i++) {
		// boolean bHasHtml = true;
		// Element el = (Element)nl.item(i);
		// String strSrc = el.getAttribute("src"); //$NON-NLS-1$
		//
		// if (!isHtmlFile(strSrc)) { // no-html file check
		// addCheckerProblem("C_27.1", el); //$NON-NLS-1$
		// }
		// }
	}

	private void item_28() {
		// need to check script/noscript mapping
		int scrSize = edu.getScript_elements().length;
		if (scrSize > 0) {
			NodeList nl = target.getElementsByTagName("noscript"); //$NON-NLS-1$
			if (scrSize > nl.getLength()) { // noscript check
				addCheckerProblem("C_28.0"); //$NON-NLS-1$
			}
		}
	}

	private void item_29() {
		if (edu.isHasJavascript() || edu.getScript_elements().length > 0) {
			addCheckerProblem("C_29.0"); //$NON-NLS-1$
		}

		for (Element applet : edu.getAppletElements()) {
			addCheckerProblem("C_29.2", //$NON-NLS-1$
					applet);
		}

		for (int i = 0; i < aWithHref_hrefs.length; i++) {
			String str = aWithHref_hrefs[i];
			if (str.toLowerCase().startsWith("javascript:")) { //$NON-NLS-1$
				addCheckerProblem("C_29.1", //$NON-NLS-1$
						" (href=\"" + str + "\")", //$NON-NLS-2$ //$NON-NLS-1$
						aWithHref_elements[i]);
			}
		}
	}

	private void mediaCheck() {
		boolean bHasObject = false;
		Vector<Node> tmpV = new Vector<Node>();
		for (Element e : object_elements) {
			tmpV.add(e);
		}
		for (Element e : embed_elements) {
			tmpV.add(e);
		}
		tmpV.addAll(edu.getAppletElements());
		if (tmpV.size() > 0) {
			addCheckerProblem("C_30.0", "", tmpV); //$NON-NLS-1$
			addCheckerProblem("C_30.1", "", tmpV); //$NON-NLS-1$

			// TODO check if these two items should be shown
			addCheckerProblem("C_500.0", "", tmpV);
			addCheckerProblem("C_500.1", "", tmpV);

			addCheckerProblem("C_600.1", "", tmpV);
			addCheckerProblem("C_600.2", "", tmpV);
			addCheckerProblem("C_600.6", "", tmpV);
			addCheckerProblem("C_600.7", "", tmpV);

			addCheckerProblem("C_600.16", "", tmpV); //$NON-NLS-1$
		}
		if (edu.isHasJavascript()) {
			addCheckerProblem("C_30.1", "(JavaScript)"); //$NON-NLS-1$			
		}

		String tmpS = "";
		if (object_elements.length < liveObject) {
			tmpS = tmpS + " object";
		}
		if (object_elements.length < liveObject) {
			tmpS = tmpS + " embed";
		}
		if (tmpS.length() > 0) {
			addCheckerProblem("C_30.0", "(" + Messages.Dynamic + tmpS + ")"); //$NON-NLS-1$
			addCheckerProblem("C_30.1", "(" + Messages.Dynamic + tmpS + ")"); //$NON-NLS-1$			

			// TODO check if these two items should be shown
			addCheckerProblem("C_500.0", "(" + Messages.Dynamic + tmpS + ")");
			addCheckerProblem("C_500.1", "(" + Messages.Dynamic + tmpS + ")");

			addCheckerProblem("C_600.1", "(" + Messages.Dynamic + tmpS + ")");
			addCheckerProblem("C_600.2", "(" + Messages.Dynamic + tmpS + ")");
			addCheckerProblem("C_600.6", "(" + Messages.Dynamic + tmpS + ")");
			addCheckerProblem("C_600.7", "(" + Messages.Dynamic + tmpS + ")");

			addCheckerProblem("C_600.16", "(" + Messages.Dynamic + tmpS + ")"); //$NON-NLS-1$
		}

	}

	private void item_31() {
		NodeList nl = target.getElementsByTagName("frameset"); //$NON-NLS-1$
		if (nl.getLength() > 0) {
			NodeList noNl = target.getElementsByTagName("noframes"); //$NON-NLS-1$
			if (noNl.getLength() == 0) { // noframes check
				Element el = (Element) nl.item(0);
				addCheckerProblem("C_31.0", el); //$NON-NLS-1$
			}
		}
	}

	private void item_32() {
		if (object_elements.length > 0) { // object alert
			result.add(new ProblemItemImpl("C_32.0")); //$NON-NLS-1$
		} else {
			if (edu.getAppletElements().size() > 0) { // object alert
				result.add(new ProblemItemImpl("C_32.0")); //$NON-NLS-1$
			}
		}
	}

	private void item_33() {
		NodeList nl = target.getElementsByTagName("blink"); //$NON-NLS-1$
		int length = nl.getLength();
		for (int i = 0; i < length; i++) {
			boolean bHasText = false;
			Element el = (Element) nl.item(i);
			bHasText = hasTextDescendant(el);
			if (bHasText) { // blink text check
				addCheckerProblem("C_33.0", el); //$NON-NLS-1$
			}
		}

		// TODO move to styleCheck
		for (Element e : elementsWithStyleList) {
			String style = e.getAttribute("style");
			if (BLINK_PATTERN_ATTR.matcher(style).matches()) {
				addCheckerProblem("C_33.1", "style=\"" + style + "\"", e); //$NON-NLS-1$
			}
		}

		Set<Element> styleElementList = styleElementMap.keySet();
		for (Element e : styleElementList) {
			String style = styleElementMap.get(e);
			if (style != null) {
				if (BLINK_PATTERN.matcher(style).matches()) {
					addCheckerProblem("C_33.2", "", e);
				}
			}
		}

		Set<IStyleSheet> keys = styleSheetsMap.keySet();
		for (IStyleSheet ss : keys) {
			if (ss.getHref() != null && ss.getHref().length() > 0
			// avoid duplication
					&& BLINK_PATTERN.matcher(styleSheetsMap.get(ss)).matches()) {
				addCheckerProblem("C_33.2", "(" + ss.getHref() + ")");
			}
		}

	}

	private void item_34() {
		NodeList nl = target.getElementsByTagName("marquee"); //$NON-NLS-1$
		int length = nl.getLength();
		for (int i = 0; i < length; i++) {
			Element el = (Element) nl.item(i);
			// marquee check
			addCheckerProblem("C_34.0", el); //$NON-NLS-1$
		}
	}

	private void item_35() {
		Vector<Node> gifImages = new Vector<Node>();

		for (int i = 0; i < img_elements.length; i++) {
			Element el = img_elements[i];
			if (isNormalImage(el) && el.hasAttribute(ATTR_SRC)) {
				String strSrc = el.getAttribute(ATTR_SRC);
				if (strSrc != null && strSrc.length() > 0) {
					String strExt = getFileExtension(strSrc);
					if (strExt.equalsIgnoreCase("gif")) { //$NON-NLS-1$
						// TODO gif image check
						gifImages.add(el);
					}
				}
			}
		}
		if (gifImages.size() > 0)
			addCheckerProblem("C_35.0", //$NON-NLS-1$
					// " (src=\"" + strSrc + "\")", //$NON-NLS-1$ //$NON-NLS-2$
					"", gifImages);

	}

	private void item_36() {
		NodeList nl = target.getElementsByTagName("meta"); //$NON-NLS-1$
		int length = nl.getLength();
		for (int i = 0; i < length; i++) {
			Element el = (Element) nl.item(i);

			if (el.hasAttribute("http-equiv")) { //$NON-NLS-1$
				String strMeta = el.getAttribute("http-equiv"); //$NON-NLS-1$
				if (strMeta != null && strMeta.equalsIgnoreCase("refresh")) { //$NON-NLS-1$
					String strCon = el.getAttribute("content"); //$NON-NLS-1$
					if (strCon == null
							|| strCon.toLowerCase().indexOf("url") < 0) { //$NON-NLS-1$
						// refresh
						// refresh itself check
						addCheckerProblem("C_36.0", el); //$NON-NLS-1$
					} else {
						// redirect
						Matcher m = Pattern.compile("(\\d+);.*")
								.matcher(strCon);
						if (m.matches() && Integer.parseInt(m.group(1)) > 0)
							addCheckerProblem("C_36.1", el); //$NON-NLS-1$
					}
				}
			}
		}
	}

	private void item_38() {
		Element[] mouseButton = edu.getEventMouseButtonElements();
		Element[] mouseFocus = edu.getEventOnMouseElements();
		// Element[] onKey = edu.getEventOnKeyElements();

		// TODO update message

		HashSet<Element> tmpSet = new HashSet<Element>();
		Vector<Node> nodeV = new Vector<Node>();
		for (int i = 0; i < mouseButton.length; i++) {
			Element el = mouseButton[i];
			tmpSet.add(el);
			if (el.hasAttribute(ATTR_ONKEYDOWN)
					|| el.hasAttribute(ATTR_ONKEYPRESS)
					|| el.hasAttribute(ATTR_ONKEYUP)) {
				// info (confirm)
			} else {
				nodeV.add(el);
			}
		}
		if (nodeV.size() > 0) {
			addCheckerProblem("C_38.0", "", nodeV); //$NON-NLS-1$ //$NON-NLS-2$
		}
		nodeV.clear();
		for (int i = 0; i < mouseFocus.length; i++) {
			Element el = mouseFocus[i];
			if (tmpSet.add(el)) {
				if (el.hasAttribute(ATTR_ONFOCUS)
						|| el.hasAttribute(ATTR_ONBLUR)
						|| el.hasAttribute(ATTR_ONSELECT)) {
					// info (confirm)
				} else {
					nodeV.add(el);
				}
			}
		}
		if (nodeV.size() > 0) {
			addCheckerProblem("C_38.0", "", nodeV); //$NON-NLS-1$ //$NON-NLS-2$
		}

	}

	private void item_39() {
		boolean bHasTabIndex = false;
		if (body_elements.length > 0) {
			Element bodyEl = body_elements[0];
			Stack<Node> stack = new Stack<Node>();
			Node curNode = bodyEl;
			while (curNode != null) {
				if (curNode.getNodeType() == Node.ELEMENT_NODE) {
					Element el = (Element) curNode;
					if (el.hasAttribute("tabindex")) { //$NON-NLS-1$
						String str = el.getAttribute("tabindex"); //$NON-NLS-1$
						if (!str.equals("")) { //$NON-NLS-1$
							bHasTabIndex = true;
							break;
						}
					}
				}

				if (curNode.hasChildNodes()) {
					stack.push(curNode);
					curNode = curNode.getFirstChild();
				} else if (curNode.getNextSibling() != null) {
					curNode = curNode.getNextSibling();
				} else {
					curNode = null;
					while ((curNode == null) && (stack.size() > 0)) {
						curNode = stack.pop();
						curNode = curNode.getNextSibling();
					}
				}
			}
		}
		if (!bHasTabIndex) {
			// tabindex check
			addCheckerProblem("C_39.0"); //$NON-NLS-1$
		}
	}

	private void item_40() {
		boolean bHasAccess = false;
		for (int i = 0; i < aWithHref_elements.length; i++) {
			Element el = aWithHref_elements[i];
			if (el.hasAttribute("accesskey")) { //$NON-NLS-1$
				String str = el.getAttribute("accesskey"); //$NON-NLS-1$
				if (str.length() > 0) {
					bHasAccess = true;
					break;
				}
			}
		}
		if (!bHasAccess) {
			// alert to add keyboard shortcut to frequently used links
			addCheckerProblem("C_40.0"); //$NON-NLS-1$
		}
	}

	private void item_41() {
		boolean bHasAccess = false;
		int length = formList.size();
		if (length == 0)
			return;
		for (Element formEl : formList) {
			Stack<Node> stack = new Stack<Node>();
			Node curNode = formEl.getFirstChild();
			while (curNode != null) {
				if (curNode.getNodeType() == Node.ELEMENT_NODE) {
					Element el = (Element) curNode;
					if (el.hasAttribute("accesskey")) { //$NON-NLS-1$
						String str = el.getAttribute("accesskey"); //$NON-NLS-1$
						if (!str.equals("")) { //$NON-NLS-1$
							bHasAccess = true;
							break;
						}
					}
				}

				if (curNode.hasChildNodes()) {
					stack.push(curNode);
					curNode = curNode.getFirstChild();
				} else if (curNode.getNextSibling() != null) {
					curNode = curNode.getNextSibling();
				} else {
					curNode = null;
					while ((curNode == null) && (stack.size() > 0)) {
						curNode = stack.pop();
						curNode = curNode.getNextSibling();
					}
				}
			}

			if (bHasAccess)
				break;
		}
		if (!bHasAccess) {
			// alert to furnish keyboard shortcut for form elements
			addCheckerProblem("C_41.0"); //$NON-NLS-1$
		}

	}

	private void item_42() {
		Vector<Node> anchors = new Vector<Node>();

		for (int i = 0; i < aWithHref_elements.length; i++) {
			Element el = aWithHref_elements[i];
			if (el.hasAttribute("target")) { //$NON-NLS-1$
				String strTarget = el.getAttribute("target"); //$NON-NLS-1$
				if (!strTarget.equals("") //$NON-NLS-1$
						&& !strTarget.equalsIgnoreCase("_top") //$NON-NLS-1$
						&& !strTarget.equalsIgnoreCase("_self") //$NON-NLS-1$
						&& !strTarget.equalsIgnoreCase("top") //$NON-NLS-1$
						&& !strTarget.equalsIgnoreCase("self")) { //$NON-NLS-1$
					// && (strTarget.equalsIgnoreCase("_blank")
					// || strTarget.equalsIgnoreCase("blank")
					// || strTarget.equalsIgnoreCase("_new")
					// || strTarget.equalsIgnoreCase("new")
					// || strTarget.equalsIgnoreCase("_top")
					// || strTarget.equalsIgnoreCase("top"))) {
					// popup new window alert
					anchors.add(el);
				}
			}
		}

		if (anchors.size() > 0)
			addCheckerProblem("C_42.0", null, anchors); //$NON-NLS-1$
	}

	private void item_43() {

		boolean bHasProblem = false;
		Element[] tmpE = edu.getScript_elements();
		int length = tmpE.length;
		for (int i = 0; i < length; i++) {
			Element el = tmpE[i];
			Node curChild = el.getFirstChild();
			while (curChild != null) {
				if (curChild.getNodeType() == Node.CDATA_SECTION_NODE) {
					String strTxt = curChild.getNodeValue();
					if (strTxt != null
							&& strTxt.toLowerCase().indexOf(WINDOW_OPEN) >= 0) {
						bHasProblem = true;
						break;
					}
				}
				curChild = curChild.getNextSibling();
			}
			if (bHasProblem) {
				result.add(new ProblemItemImpl("C_43.0")); //$NON-NLS-1$  
				break;
			}
		}

		HashSet<Element> tmpSet = new HashSet<Element>();
		tmpE = edu.getEventFocusElements();
		for (int i = 0; i < tmpE.length; i++) {
			if (hasOpenWndEvent(tmpE[i], HtmlEvalUtil.EVENT_FOCUS)
					&& tmpSet.add(tmpE[i])) {
				result.add(new ProblemItemImpl("C_43.0", tmpE[i])); //$NON-NLS-1$
			}
		}
		tmpE = edu.getEventLoadElements();
		for (int i = 0; i < tmpE.length; i++) {
			if (hasOpenWndEvent(tmpE[i], HtmlEvalUtil.EVENT_LOAD)
					&& tmpSet.add(tmpE[i])) {
				result.add(new ProblemItemImpl("C_43.0", tmpE[i])); //$NON-NLS-1$
			}
		}
		tmpE = edu.getEventMouseButtonElements();
		for (int i = 0; i < tmpE.length; i++) {
			if (hasOpenWndEvent(tmpE[i], HtmlEvalUtil.EVENT_MOUSE_BUTTON)
					&& tmpSet.add(tmpE[i])) {
				result.add(new ProblemItemImpl("C_43.0", tmpE[i])); //$NON-NLS-1$
			}
		}
		tmpE = edu.getEventOnMouseElements();
		for (int i = 0; i < tmpE.length; i++) {
			if (hasOpenWndEvent(tmpE[i], HtmlEvalUtil.EVENT_MOUSE_FOCUS)
					&& tmpSet.add(tmpE[i])) {
				result.add(new ProblemItemImpl("C_43.0", tmpE[i])); //$NON-NLS-1$
			}
		}
		tmpE = edu.getEventOnKeyElements();
		for (int i = 0; i < tmpE.length; i++) {
			if (hasOpenWndEvent(tmpE[i], HtmlEvalUtil.EVENT_ON_KEY)
					&& tmpSet.add(tmpE[i])) {
				result.add(new ProblemItemImpl("C_43.0", tmpE[i])); //$NON-NLS-1$
			}
		}
		tmpE = edu.getEventWindowElements();
		for (int i = 0; i < tmpE.length; i++) {
			if (hasOpenWndEvent(tmpE[i], HtmlEvalUtil.EVENT_WINDOW)
					&& tmpSet.add(tmpE[i])) {
				result.add(new ProblemItemImpl("C_43.0", tmpE[i])); //$NON-NLS-1$
			}
		}
	}

	private void item_45() {
		// input: text, text area, radio
		NodeList nl = target.getElementsByTagName("input"); //$NON-NLS-1$
		int length = nl.getLength();
		for (int i = 0; i < length; i++) {
			boolean bHasDefault = false;
			Element el = (Element) nl.item(i);
			if (!el.hasAttribute("type")) //$NON-NLS-1$
				continue;
			String strType = el.getAttribute("type"); //$NON-NLS-1$
			if (strType.equalsIgnoreCase("text") //$NON-NLS-1$
					|| strType.equalsIgnoreCase("textbox") //$NON-NLS-1$
					|| strType.equalsIgnoreCase("textarea") //$NON-NLS-1$
					|| strType.equals("")) { //$NON-NLS-1$
				String strValue = el.getAttribute("value"); //$NON-NLS-1$
				if (strValue != null && strValue.length() > 0)
					bHasDefault = true;
				else {
					bHasDefault = hasTextDescendant(el);
				}

				if (!bHasDefault) { // default value check
					addCheckerProblem("C_45.0", el); //$NON-NLS-1$
				}
			} else if (strType.equalsIgnoreCase("radio")) { //$NON-NLS-1$
				String strChecked = el.getAttribute("checked"); //$NON-NLS-1$
				if (strChecked != null && !strChecked.equals("")) //$NON-NLS-1$
					bHasDefault = true;
				else {
					if (!el.hasAttribute("name")) //$NON-NLS-1$
						continue;
					String strName1 = el.getAttribute("name"); //$NON-NLS-1$

					for (int j = 0; j < length; j++) {
						if (i == j)
							continue;
						Element el2 = (Element) nl.item(j);
						if (!el2.hasAttribute("type")) //$NON-NLS-1$
							continue;
						String strType2 = el2.getAttribute("type"); //$NON-NLS-1$

						if (strType2.equalsIgnoreCase("radio")) { //$NON-NLS-1$
							String strName2 = el2.getAttribute("name"); //$NON-NLS-1$
							if (strName2 != null
									&& strName1.equalsIgnoreCase(strName2)) { // this
								// radio
								// group
								// has
								// been
								// checked
								if (j < i) {
									bHasDefault = true;
									break;
								}
								String strChecked2 = el2
										.getAttribute("checked"); //$NON-NLS-1$
								if (strChecked2 != null
										&& !strChecked2.equals("")) { //$NON-NLS-1$
									bHasDefault = true;
									break;
								}
							}
						}
					}
				}

				if (!bHasDefault) { // default value check
					addCheckerProblem("C_45.1", el); //$NON-NLS-1$
				}
			} else {
				continue;
			}

		}

		// select
		nl = target.getElementsByTagName("select"); //$NON-NLS-1$
		length = nl.getLength();
		for (int i = 0; i < length; i++) {
			boolean bHasDefault = false;
			Element el = (Element) nl.item(i);
			NodeList opNl = el.getElementsByTagName("option"); //$NON-NLS-1$
			int opLength = opNl.getLength();
			for (int j = 0; j < opLength; j++) {
				String strSelected = ((Element) opNl.item(j))
						.getAttribute("selected"); //$NON-NLS-1$
				if (strSelected != null) {
					bHasDefault = true;
					break;
				}
			}
			if (!bHasDefault) { // default value check
				addCheckerProblem("C_45.1", el); //$NON-NLS-1$
			}
		} // html:text
		nl = target.getElementsByTagName("html:text"); //$NON-NLS-1$
		length = nl.getLength();
		for (int i = 0; i < length; i++) {
			boolean bHasDefault = false;
			Element el = (Element) nl.item(i);
			String strValue = el.getAttribute("value"); //$NON-NLS-1$
			if (strValue != null && strValue.length() > 0) {
				bHasDefault = true;
			} else {
				bHasDefault = hasTextDescendant(el);
			}
			if (!bHasDefault) { // default value check
				addCheckerProblem("C_45.0", el); //$NON-NLS-1$
			}
		} // textarea
		nl = target.getElementsByTagName("textarea"); //$NON-NLS-1$
		length = nl.getLength();
		for (int i = 0; i < length; i++) {
			boolean bHasDefault = false;
			Element el = (Element) nl.item(i);
			String strValue = el.getAttribute("value"); //$NON-NLS-1$
			if (strValue != null && strValue.length() > 0) {
				bHasDefault = true;
			} else {
				bHasDefault = hasTextDescendant(el);
			}
			if (!bHasDefault) { // default value check
				addCheckerProblem("C_45.0", el); //$NON-NLS-1$
			}
		} // html:radio
		nl = target.getElementsByTagName("html:radio"); //$NON-NLS-1$
		length = nl.getLength();
		for (int i = 0; i < length; i++) {
			boolean bHasDefault = false;
			Element el = (Element) nl.item(i);
			String strName1 = el.getAttribute("name"); //$NON-NLS-1$
			if (strName1 == null)
				continue;
			for (int j = i + 1; i < length; j++) {
				Element el2 = (Element) nl.item(j);
				String strName2 = el2.getAttribute("name"); //$NON-NLS-1$
				if (strName2 != null && strName1.equalsIgnoreCase(strName2)) {
					String strChecked2 = el2.getAttribute("checked"); //$NON-NLS-1$
					if (strChecked2 != null) {
						bHasDefault = true;
						break;
					}
				}
			}
			if (!bHasDefault) { // default value check
				addCheckerProblem("C_45.1", el); //$NON-NLS-1$
			}
		}
	}

	private void item_46() {
		Vector<Element> eleVec = new Vector<Element>();
		for (int i = 0; i < aWithHref_elements.length; i++) {
			boolean bAdjacentLink = false;
			Element el = aWithHref_elements[i];
			if (eleVec.contains(el))
				continue;
			Element endEl = null;
			Node nextNode = el.getNextSibling();
			String url1 = aWithHref_hrefs[i];
			String url2;
			try {
				url1 = new URL(baseUrl, aWithHref_hrefs[i]).toString();
			} catch (MalformedURLException e) {
			}
			while (nextNode != null) {
				if (nextNode.getNodeType() == Node.ELEMENT_NODE) {
					String strName = nextNode.getNodeName();
					if (strName != null) {
						if (strName.equalsIgnoreCase("br") //$NON-NLS-1$
								|| strName.equalsIgnoreCase("p")) { //$NON-NLS-1$
							nextNode = nextNode.getNextSibling();
							continue;
						} else if (strName.equalsIgnoreCase("a")) { //$NON-NLS-1$
							try {
								url2 = new URL(
										baseUrl,
										((Element) nextNode)
												.getAttribute(HtmlTagUtil.ATTR_HREF))
										.toString();
							} catch (MalformedURLException e) {
								url2 = ((Element) nextNode)
										.getAttribute(HtmlTagUtil.ATTR_HREF);
							}
							if (!url1.equals(url2)) {
								endEl = (Element) nextNode;
								if (!eleVec.contains(el))
									eleVec.add(el);
								if (!eleVec.contains(endEl))
									eleVec.add(endEl);
								bAdjacentLink = true;
							} else
								break;
						} else {
							break;
						}
					}
					// break;
				} else if (nextNode.getNodeType() == Node.TEXT_NODE) {
					String strText = nextNode.getNodeValue();
					if (strText != null && !strText.trim().equals("")) //$NON-NLS-1$
						break;
				}
				nextNode = nextNode.getNextSibling();
			}
			if (bAdjacentLink) { // adjacent link check
				addCheckerProblem("C_46.0", el, endEl); //$NON-NLS-1$
			}
		}
	}

	@SuppressWarnings("nls")
	private void item_48() {
		// Applet
		checkObsoluteEle("C_48.1", "applet"); //$NON-NLS-1$
		// BASEFONT, CENTER, FONT, STRIKE, U
		checkObsoluteEle("C_48.2", "basefont"); //$NON-NLS-1$
		checkObsoluteEle("C_48.2", "center"); //$NON-NLS-1$
		checkObsoluteEle("C_48.2", "font"); //$NON-NLS-1$
		// ?
		checkObsoluteEle("C_48.2", "strike"); //$NON-NLS-1$
		checkObsoluteEle("C_48.2", "u"); //$NON-NLS-1$
		checkObsoluteEle("C_48.2", "s"); //$NON-NLS-1$
		// DIR, MENU
		checkObsoluteEle("C_48.3", "dir"); //$NON-NLS-1$
		checkObsoluteEle("C_48.3", "menu"); //$NON-NLS-1$
		// ISINDEX
		checkObsoluteEle("C_48.4", "isindex"); //$NON-NLS-1$
		// LISTING, PLAINTEXT, XMP
		checkObsoluteEle("C_48.5", "listing"); //$NON-NLS-1$
		checkObsoluteEle("C_48.5", "plaintext"); //$NON-NLS-1$
		checkObsoluteEle("C_48.5", "xmp"); //$NON-NLS-1$
		// em/strong
		checkObsoluteEle("C_48.6", "b"); //$NON-NLS-1$
		checkObsoluteEle("C_48.6", "i"); //$NON-NLS-1$
	}

	private void item_49() {
		// alert about customize experience
		addCheckerProblem("C_49.0"); //$NON-NLS-1$
	}

	private void item_50() {
		// alert about accessible version
		addCheckerProblem("C_50.0"); //$NON-NLS-1$
	}

	/**
	 * Checks for title attributes of frame/iframe elements.
	 */
	private void item_51() {
		for (int i = 0; i < frame_elements.length; i++) {
			Element el = frame_elements[i];
			if (!hasTitle(el)) {
				addCheckerProblem("C_51.0", el); //$NON-NLS-1$
			} else if (hasBlankTitle(el)) {
				addCheckerProblem("C_51.4", el); //$NON-NLS-1$
			} else {
				addCheckerProblem("C_51.2", el.getAttribute(ATTR_TITLE), el); //$NON-NLS-1$
			}
		}

		for (int i = 0; i < iframe_elements.length; i++) {
			Element el = iframe_elements[i];
			if (!hasTitle(el)) {
				addCheckerProblem("C_51.1", //$NON-NLS-1$
						": src=" + el.getAttribute(ATTR_SRC), //$NON-NLS-1$ 
						el);
			} else if (hasBlankTitle(el)) {
				addCheckerProblem("C_51.5", //$NON-NLS-1$
						": src=" + el.getAttribute(ATTR_SRC), //$NON-NLS-1$ 
						el);
			} else {
				addCheckerProblem("C_51.3", el.getAttribute(ATTR_TITLE), el); //$NON-NLS-1$ 				
			}
		}
	}

	private void item_52() {
		// add longdesc/title into description
		for (int i = 0; i < frame_elements.length; i++) {
			Element el = frame_elements[i];
			String strTitle = el.getAttribute(ATTR_TITLE);
			if (!strTitle.equals("")) { //$NON-NLS-1$
				String strLongdesc = el.getAttribute("longdesc"); //$NON-NLS-1$
				if (strLongdesc == null || strLongdesc.equals("")) { // alert //$NON-NLS-1$
					// about
					// frame
					// description
					// //$NON-NLS-1$
					addCheckerProblem("C_52.0", el); //$NON-NLS-1$
				}
			}
		}
		// www.cnn.com --target has <iframe but source does not
		for (int i = 0; i < iframe_elements.length; i++) {
			Element el = iframe_elements[i];
			String strTitle = el.getAttribute(ATTR_TITLE);
			if (!strTitle.equals("")) { //$NON-NLS-1$
				String strLongdesc = el.getAttribute("longdesc"); //$NON-NLS-1$
				if (strLongdesc == null || strLongdesc.equals("")) { // alert //$NON-NLS-1$
					// about
					// frame
					// description
					// //$NON-NLS-1$
					addCheckerProblem("C_52.1", el); //$NON-NLS-1$
				}
			}
		}
	}

	private void item_53() {
		NodeList nl = target.getElementsByTagName("select"); //$NON-NLS-1$
		int length = nl.getLength();
		for (int i = 0; i < length; i++) {
			// alert to group long lists of selections
			Element select = (Element) nl.item(i);

			NodeList optGpNl = select.getElementsByTagName("optgroup"); //$NON-NLS-1$
			if (optGpNl.getLength() == 0) {
				addCheckerProblem("C_53.2", select); //$NON-NLS-1$
				NodeList optList = select.getElementsByTagName("option"); //$NON-NLS-1$
				if (optList.getLength() > 10) {
					addCheckerProblem("C_53.1", select); //$NON-NLS-1$
				}
			}
		}
	}

	/**
	 * Fieldset and legend checking
	 */
	private void item_54() {

		// move into initialization
		// if (formList == null)
		//			formList = edu.getElementsList(target, "form"); //$NON-NLS-1$

		Vector<Node> noFieldSetForms = new Vector<Node>();
		Vector<Node> fieldSetForms = new Vector<Node>();
		for (Element form : formList) {
			if (getFormControlNum(form) <= 1)
				continue;
			List<Element> fieldsets = edu.getElementsList(form, "fieldset"); //$NON-NLS-1$
			if (fieldsets.size() == 0) {
				noFieldSetForms.add(form);
			} else {
				for (Element fieldset : fieldsets) {
					fieldSetForms.add(fieldset);
					List<Element> legends = edu.getElementsList(fieldset,
							"legend"); //$NON-NLS-1$
					if (legends.size() == 0) {
						addCheckerProblem("C_54.1", fieldset); //$NON-NLS-1$
					} else {
						for (Element e : legends)
							addCheckerProblem("C_54.4", e); //$NON-NLS-1$
					}
				}
			}
			// C_54.3 check
			FieldsetManager map = new FieldsetManager();
			for (Element ctrl : getRadioAndCheck(form)) {
				map.addEntry(ctrl.getAttribute("name"), ctrl);
			}
			for (Vector<Node> error : map.getErrorList()) {
				addCheckerProblem("C_54.3", "", error); //$NON-NLS-1$
			}
		}
		if (noFieldSetForms.size() > 0)
			addCheckerProblem("C_54.0", null, noFieldSetForms); //$NON-NLS-1$
		if (fieldSetForms.size() > 0)
			addCheckerProblem("C_54.2", null, fieldSetForms); //$NON-NLS-1$
	}

	@SuppressWarnings("nls")
	private void item_57() {
		// need more detailed check
		Element el = null;
		int errorCount = 0;
		int exceptCount = 0;

		int length = aWithHref_elements.length;
		Vector<Node> item57V = new Vector<Node>();
		Vector<Node> linkTitle = new Vector<Node>();

		for (int i = 0; i < length; i++) {
			el = aWithHref_elements[i];

			String strTxt = aWithHref_strings[i];

			if (el.hasAttribute(ATTR_TITLE)) {
				if (hasBlankTitle(el))
					addCheckerProblem("C_57.3", el); //$NON-NLS-1$
				else
					linkTitle.add(el);
			}

			if (getWordCount(strTxt) < 3 && strTxt.length() < validate_str_len) {
				String strTitle = el.getAttribute(ATTR_TITLE);
				if (strTitle.equals("")) { //$NON-NLS-1$
					if (strTxt.trim().length() > 0) {
						item57V.add(el);
					} else {
						// can't use link

						if (!aWithHref_hrefs[i].startsWith("#")) { //$NON-NLS-1$

							String noScriptText = getNoScriptText(el);

							if ((!el.hasChildNodes() || el
									.getElementsByTagName("img").getLength() == 0)) { //$NON-NLS-1$
								exceptCount++;
								// alert
							} else if (noScriptText.length() > 0) {
								// script + noscript(Text)
								exceptCount++;
								// alert
							} else {
								errorCount++;
								String current = aWithHref_hrefs[i];
								boolean sequenceOk = false;
								if (i - 1 > 0) {
									if (current.equals(aWithHref_hrefs[i - 1])
											&& aWithHref_strings[i - 1]
													.length() > 0) {
										sequenceOk = true;
									}
								}
								if (!sequenceOk
										&& i + 1 < aWithHref_hrefs.length) {
									if (current.equals(aWithHref_hrefs[i + 1])
											&& aWithHref_strings[i + 1]
													.length() > 0) {
										sequenceOk = true;
									}
								}

								if (sequenceOk) {
									// USER
									IProblemItem tmpCP = addCheckerProblem(
											"C_57.5", //$NON-NLS-1$
											" (href=\"" + aWithHref_hrefs[i] //$NON-NLS-1$
													+ "\")", el); //$NON-NLS-1$
									edu.appendErrorIcon(tmpCP, el);
								} else {
									// WARN
									IProblemItem tmpCP = addCheckerProblem(
											"C_57.2", //$NON-NLS-1$
											" (href=\"" + aWithHref_hrefs[i] //$NON-NLS-1$
													+ "\")", el); //$NON-NLS-1$
									edu.appendErrorIcon(tmpCP, el);
								}
							}
						} else {
							// need to count # (intra page link)
							errorCount++;
						}
					}
				} else {
					if (getWordCount(strTitle) < 3
							&& strTitle.length() < validate_str_len) {
						// link title check
						// show always?
						addCheckerProblem("C_57.1", //$NON-NLS-1$
								" (linktext=\"" //$NON-NLS-1$
										+ strTxt + "\", title=\"" //$NON-NLS-1$
										+ strTitle + "\", href=\"" //$NON-NLS-1$
										+ aWithHref_hrefs[i] + "\")", //$NON-NLS-1$
								el);
					}
				}
			}
		}
		if (item57V.size() > 0) {
			addCheckerProblem("C_57.0", "", item57V); //$NON-NLS-1$ //$NON-NLS-2$
		}
		/*
		 * if (linkTitle.size() > 0) addCheckerProblem("C_57.4", "", linkTitle);
		 * //$NON-NLS-1$ //$NON-NLS-2$
		 */
		for (Node link : linkTitle) {
			addCheckerProblem("C_57.4",
					((Element) link).getAttribute(ATTR_TITLE), (Element) link);
		}

		// need URL check

		length = length - exceptCount;

		if (length > 0) {
			invalidLinkRatio = (double) errorCount / (double) length;
			// System.out.println(invalidLinkRatio);
		}

	}

	private void item_58() {

		int[] countStrLen = { 0, 0, 0, 0, 0 };
		for (int i = 0; i < aWithHref_elements.length; i++) {
			// strArray[i] = getTextAltDescendant(nl.item(i));
			int length = aWithHref_strings[i].length();

			if (length == 0) {
				continue;
			}

			if (length > 9) {
				if (length < 20) {
					countStrLen[3]++;
				} else {
					countStrLen[4]++;
				}
			} else if (length < 7) {
				if (length < 4)
					countStrLen[0]++;
				else
					countStrLen[1]++;
			} else {
				countStrLen[2]++;
			}
		}

		// 0 (exclusion)
		// length 1-3
		// length 4-6
		// length 7-9
		// length 10-20
		// length 20-

		int[][] strHash = new int[5][];
		Node[][] nodeArray = new Node[5][];
		String[][] strArray = new String[5][];
		String[][] urlArray = new String[5][];
		boolean[][] bDuplicate = new boolean[5][];
		for (int i = 0; i < 5; i++) {
			strHash[i] = new int[countStrLen[i]];
			bDuplicate[i] = new boolean[countStrLen[i]];
			nodeArray[i] = new Node[countStrLen[i]];
			strArray[i] = new String[countStrLen[i]];
			urlArray[i] = new String[countStrLen[i]];
			// System.out.print(countStrLen[i] + " ");
			countStrLen[i] = 0;
		}
		// System.out.println();

		int nlLength = aWithHref_elements.length;
		for (int i = 0; i < nlLength; i++) {
			int length = aWithHref_strings[i].length();
			if (length == 0)
				continue;
			if (length > 9) {
				if (length < 20) {
					strHash[3][countStrLen[3]] = aWithHref_strings[i]
							.hashCode();
					nodeArray[3][countStrLen[3]] = aWithHref_elements[i];
					strArray[3][countStrLen[3]] = aWithHref_strings[i];
					urlArray[3][countStrLen[3]] = aWithHref_hrefs[i];
					countStrLen[3]++;
				} else {
					strHash[4][countStrLen[4]] = aWithHref_strings[i]
							.hashCode();
					nodeArray[4][countStrLen[4]] = aWithHref_elements[i];
					strArray[4][countStrLen[4]] = aWithHref_strings[i];
					urlArray[4][countStrLen[4]] = aWithHref_hrefs[i];
					countStrLen[4]++;
				}
			} else if (length < 7) {
				if (length < 4) {
					strHash[0][countStrLen[0]] = aWithHref_strings[i]
							.hashCode();
					nodeArray[0][countStrLen[0]] = aWithHref_elements[i];
					strArray[0][countStrLen[0]] = aWithHref_strings[i];
					urlArray[0][countStrLen[0]] = aWithHref_hrefs[i];
					countStrLen[0]++;
				} else {
					strHash[1][countStrLen[1]] = aWithHref_strings[i]
							.hashCode();
					nodeArray[1][countStrLen[1]] = aWithHref_elements[i];
					strArray[1][countStrLen[1]] = aWithHref_strings[i];
					urlArray[1][countStrLen[1]] = aWithHref_hrefs[i];
					countStrLen[1]++;
				}
			} else {
				strHash[2][countStrLen[2]] = aWithHref_strings[i].hashCode();
				nodeArray[2][countStrLen[2]] = aWithHref_elements[i];
				strArray[2][countStrLen[2]] = aWithHref_strings[i];
				urlArray[2][countStrLen[2]] = aWithHref_hrefs[i];
				countStrLen[2]++;
			}
		}

		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < strHash[i].length - 1; j++) {
				if (bDuplicate[i][j])
					continue;
				Vector<Node> idVec = new Vector<Node>();

				for (int k = j + 1; k < strHash[i].length; k++) {
					if (bDuplicate[i][k])
						continue;
					if (strHash[i][j] == strHash[i][k]) {

						String url1 = urlArray[i][j];
						try {
							url1 = new URL(baseUrl, url1).toString();
						} catch (MalformedURLException e) {
							// e.printStackTrace();
						}

						String url2 = urlArray[i][k];
						try {
							url2 = new URL(baseUrl, url2).toString();
						} catch (MalformedURLException e1) {
							// e1.printStackTrace();
						}

						// System.out.println(url1 + " " + url2);
						if (!url1.equalsIgnoreCase(url2)) {
							if (!bDuplicate[i][j]) {
								idVec.add(nodeArray[i][j]);
								bDuplicate[i][j] = true;
							}
							idVec.add(nodeArray[i][k]);
							bDuplicate[i][k] = true;
						}
					}

				}

				if (idVec.size() > 0) {
					addCheckerProblem("C_58.0", " (linktext=\"" //$NON-NLS-1$ //$NON-NLS-2$
							+ strArray[i][j] + "\")", idVec); //$NON-NLS-1$
				}
			}
		}

	}

	private void item_59() {

		// 59.0 was identical with 68

		boolean bHasKeyWdDesc = false;
		NodeList nl = target.getElementsByTagName("meta"); //$NON-NLS-1$
		int length = nl.getLength();
		for (int i = 0; i < length; i++) {
			Element el = (Element) nl.item(i);
			String strName = el.getAttribute("name"); //$NON-NLS-1$
			if (strName != null && strName.equalsIgnoreCase("keywords")) //$NON-NLS-1$
				bHasKeyWdDesc = true;
			else if (strName != null && strName.equalsIgnoreCase("description")) //$NON-NLS-1$
				bHasKeyWdDesc = true;
		}
		if (!bHasKeyWdDesc) {
			// Use the keywords
			addCheckerProblem("C_59.1"); //$NON-NLS-1$
		}

		nl = target.getElementsByTagName("address"); //$NON-NLS-1$
		if (nl.getLength() == 0) {
			// Use the ADDRESS element
			addCheckerProblem("C_59.2"); //$NON-NLS-1$
		}

		// Use the Resource Description Framework (RDF) in the header of your
		// document
		addCheckerProblem("C_59.3"); //$NON-NLS-1$
	}

	private void item_60() {
		boolean bHasTitle = false;
		Element firstTitle = null;
		NodeList nl = target.getElementsByTagName("head"); //$NON-NLS-1$
		if (nl.getLength() > 0) {
			NodeList hdNl = ((Element) nl.item(0))
					.getElementsByTagName(ATTR_TITLE);
			int length = hdNl.getLength();
			for (int i = 0; i < length; i++) {
				Element titleEl = (Element) hdNl.item(i);
				if (firstTitle == null)
					firstTitle = titleEl;
				bHasTitle = hasTextDescendant(titleEl);
			}
		}
		if (!bHasTitle) { // document title check
			result.add(new ProblemItemImpl("C_60.0")); //$NON-NLS-1$
		} else {
			List<String> ngPatterns = new ArrayList<String>();
			ngPatterns.add("\u7121\u984c.*");
			ngPatterns.add(".*untitled.*");
			ngPatterns.add(".*no title.*");
			ngPatterns.add(".*\\.html?");
			ngPatterns.add("[\\p{Punct}\\d]+");
			String title = getTextDescendant(firstTitle).toLowerCase().trim();

			for (String pattern : ngPatterns) {
				if (title.matches(pattern)) {
					addCheckerProblem("C_60.1", title, firstTitle);
					break;
				}
			}

		}
	}

	private void item_66() {
		// need to check descendant text (or href txt) contains "search","go",
		// etc.
		// exist text box / text area

		for (Element formE : formList) {
			// alert if there are different types of searches
			addCheckerProblem("C_66.0", formE); //$NON-NLS-1$
		}
	}

	private void item_68() {
		boolean bHasRel = false;
		NodeList nl = target.getElementsByTagName("link"); //$NON-NLS-1$
		int length = nl.getLength();
		for (int i = 0; i < length; i++) {
			Element el = (Element) nl.item(i);
			String strRel = el.getAttribute("rel"); //$NON-NLS-1$
			if (strRel != null && !strRel.equals("") //$NON-NLS-1$
					&& !strRel.equalsIgnoreCase("stylesheet")) { //$NON-NLS-1$
				bHasRel = true;
				break;
			} else {
				strRel = el.getAttribute("rev"); //$NON-NLS-1$
				if (strRel != null && !strRel.equals("")) { //$NON-NLS-1$
					bHasRel = true;
					break;
				}
			}
		}
		if (!bHasRel) { // alert about identifying document location
			addCheckerProblem("C_68.0"); //$NON-NLS-1$
		}

		// //alert to use the Resource Description Framework (RDF) in the header
		// result.add(new CheckerProblem("68.1"));
	}

	private void item_69() {
		if (body_elements.length > 0) {
			Element bodyEl = body_elements[0];
			Stack<Node> stack = new Stack<Node>();
			Node curNode = bodyEl;

			while (curNode != null) {
				// TODO have means to skip over?
				boolean isArtStr = false;
				if (isLeafBlockEle(curNode)
						&& isAsciiArtString(getTextAltDescendant(curNode))) {
					addCheckerProblem("C_69.0", (Element) curNode); //$NON-NLS-1$
					isArtStr = true;
				}

				if (!isArtStr && curNode.hasChildNodes()) {
					stack.push(curNode);
					curNode = curNode.getFirstChild();
				} else if (curNode.getNextSibling() != null) {
					curNode = curNode.getNextSibling();
				} else {
					curNode = null;
					while ((curNode == null) && (stack.size() > 0)) {
						curNode = stack.pop();
						curNode = curNode.getNextSibling();
					}
				}

			}
		}
	}

	private void item_73() {
		Vector<Node> nodeV = new Vector<Node>();
		for (int i = 0; i < object_elements.length; i++) {
			Element el = object_elements[i];
			String str = el.getAttribute("data"); //$NON-NLS-1$
			str = getFileExtension(str);
			if (str.equalsIgnoreCase("pdf") //$NON-NLS-1$
					|| str.equalsIgnoreCase("ppt") //$NON-NLS-1$
					|| isAudioFileExt(str) || isMultimediaFileExt(str)) {
				nodeV.add(el);
			}
		}
		for (int i = 0; i < aWithHref_hrefs.length; i++) {
			Element el = aWithHref_elements[i];
			String str = aWithHref_hrefs[i];
			str = getFileExtension(str);
			if (str.equalsIgnoreCase("pdf") //$NON-NLS-1$
					|| str.equalsIgnoreCase("ppt") //$NON-NLS-1$
					|| isAudioFileExt(str) || isMultimediaFileExt(str)) {
				nodeV.add(el);
			}
		}

		for (Element applet : edu.getAppletElements()) {
			NodeList parNl = applet.getElementsByTagName("param"); //$NON-NLS-1$
			int parLength = parNl.getLength();
			for (int j = 0; j < parLength; j++) {
				String str = ((Element) parNl.item(j)).getAttribute("value"); //$NON-NLS-1$
				str = getFileExtension(str);
				if (str.equalsIgnoreCase("pdf") //$NON-NLS-1$
						|| str.equalsIgnoreCase("ppt") //$NON-NLS-1$
						|| isAudioFileExt(str) || isMultimediaFileExt(str)) {
					nodeV.add(applet);
				}
			}
		}
		if (nodeV.size() > 0) {
			addCheckerProblem("C_73.0", "", nodeV); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	private void item_74() {
		boolean hasHeader = false;
		NodeList nl = target.getElementsByTagName("meta"); //$NON-NLS-1$
		int length = nl.getLength();
		for (int i = 0; i < length; i++) {
			Element el = (Element) nl.item(i);
			String strMeta = el.getAttribute("http-equiv"); //$NON-NLS-1$
			if (strMeta.equalsIgnoreCase("refresh") //$NON-NLS-1$
					|| strMeta.equalsIgnoreCase("location")) { //$NON-NLS-1$
				addCheckerProblem("C_74.1", el); //$NON-NLS-1$
				hasHeader = true;
			}
		}
		// timeout process alert
		if (!hasHeader) {
			addCheckerProblem("C_74.0"); //$NON-NLS-1$
		}

		if (formList.size() > 0) {
			addCheckerProblem("C_74.2"); //$NON-NLS-1$
		}
	}

	private void item_75() {
		for (int i = 0; i < bottom_data_tables.length; i++) {
			Element tNode = bottom_data_tables[i];
			NodeList nl = tNode.getElementsByTagName("th"); //$NON-NLS-1$
			if (nl.getLength() == 0) {
				// table header check
				addCheckerProblem("C_75.0", tNode); //$NON-NLS-1$
			}
		}
	}

	private void item_76() {
		Vector<Node> rowColTables = new Vector<Node>();

		for (Element el : dataTableList) {
			// duplicated with C_331
			// int thNum = 0;
			// boolean hasScopeAxis = false;
			//			for (Element tr : edu.getElementsList(el, "tr")) { //$NON-NLS-1$
			//				List<Element> cells = edu.getElementsList(tr, "th"); //$NON-NLS-1$
			// if (cells.size() > 0)
			// thNum++;
			// cells.addAll(edu.getElementsList(tr, "td"));
			// for (Element cell : cells) {
			// if (getAttribute(cell, "scope") != null
			// || getAttribute(cell, "axis") != null) {
			// hasScopeAxis = true;
			// break;
			// }
			// }
			// if (hasScopeAxis)
			// break;
			// }
			// if (!hasScopeAxis && thNum > 1) {
			// // TODO check table header structure
			//				addCheckerProblem("C_76.0", el); //$NON-NLS-1$
			// }
			//

			if (hasRowColSpan(el)) {
				// the table has rowspan and/or colspan
				rowColTables.add(el);
			}
		}

		if (rowColTables.size() > 0)
			addCheckerProblem("C_76.1", "", rowColTables);
	}

	/**
	 * Returns true if the specified table has any td or th elements which has
	 * rowspan and/or colspan attribute. for new JIS.
	 * 
	 * @param table
	 *            a leaf table element
	 * @return a boolean value that indicates if the specified table has any td
	 *         or th elements which has rowspan and/or colspan attribute.
	 */
	private boolean hasRowColSpan(Element table) {
		boolean bHasRowColSpan = false;

		for (Element cell : edu.getElementsList(table, "th", "td")) {
			String rowspan = getAttribute(cell, "rowspan");
			String colspan = getAttribute(cell, "colspan");
			if ((rowspan != null && Integer.parseInt(rowspan) > 1)
					|| (colspan != null && Integer.parseInt(colspan) > 1)) {
				bHasRowColSpan = true;
				break;
			}
		}

		return bHasRowColSpan;
	}

	private void item_77() {
		Element el = null;
		boolean bHasCSS = false;
		NodeList nl = target.getElementsByTagName("link"); //$NON-NLS-1$
		int length = nl.getLength();
		for (int i = 0; i < length; i++) {
			el = (Element) nl.item(i);
			String strRel = el.getAttribute("rel"); //$NON-NLS-1$
			if (strRel != null && strRel.equalsIgnoreCase("stylesheet")) { //$NON-NLS-1$
				bHasCSS = true;
				break;
			}
		}
		if (bHasCSS) { // alert about style sheet
			addCheckerProblem("C_77.0", //$NON-NLS-1$
					// AdditionalDescription.getString("CheckEngine._(link_tag_for_include_stylesheet)_492"),
					// //$NON-NLS-1$
					el);
			// multi?
		}

		nl = target.getElementsByTagName("style"); //$NON-NLS-1$
		if (nl.getLength() > 0) {
			addCheckerProblem("C_77.1", "", nl); //$NON-NLS-1$ //$NON-NLS-2$
		}

		Vector<Node> nodeV = new Vector<Node>();

		if (body_elements.length > 0) {
			Element bodyEl = body_elements[0];
			Stack<Node> stack = new Stack<Node>();
			Node curNode = bodyEl;
			while (curNode != null) {
				if (curNode.getNodeType() == Node.ELEMENT_NODE) {
					el = (Element) curNode;
					String strAlt = el.getAttribute("style"); //$NON-NLS-1$
					if (!strAlt.equals("")) { //$NON-NLS-1$
						// alert about style
						nodeV.add(el);
					}
				}

				if (curNode.hasChildNodes()) {
					stack.push(curNode);
					curNode = curNode.getFirstChild();
				} else if (curNode.getNextSibling() != null) {
					curNode = curNode.getNextSibling();
				} else {
					curNode = null;
					while ((curNode == null) && (stack.size() > 0)) {
						curNode = stack.pop();
						curNode = curNode.getNextSibling();
					}
				}
			}
		}
		if (nodeV.size() > 0) {
			addCheckerProblem("C_77.2", "", nodeV); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	@SuppressWarnings("nls")
	private void item_78() {
		Vector<Node> textInputs = new Vector<Node>();
		NodeList nl = target.getElementsByTagName("input");
		int length = nl.getLength();
		for (int i = 0; i < length; i++) {
			Element el = (Element) nl.item(i);
			if (!el.hasAttribute("type"))
				continue;
			String strType = el.getAttribute("type");
			if (strType.equalsIgnoreCase("text")
					|| strType.equalsIgnoreCase("textbox")
					|| strType.equals("")) {
				textInputs.add(el);
			}
		}

		nl = target.getElementsByTagName("html:text");
		length = nl.getLength();
		for (int i = 0; i < length; i++) {
			textInputs.add((Element) nl.item(i));
		}
		if (textInputs.size() > 0)
			addCheckerProblem("C_78.2", null, textInputs);
	}

	/**
	 * Checks labels and titles for form controls
	 */
	private void item_79() {
		if (labelList == null)
			labelList = edu.getElementsList(target, "label"); //$NON-NLS-1$
		Vector<Node> noTitleControls = new Vector<Node>();
		Vector<Node> noLabelEmptyTitleControls = new Vector<Node>();
		Vector<Node> implicitLabelControls = new Vector<Node>();
		for (Element body : body_elements) { //$NON-NLS-1$
			for (Element el : getFormControl(body)) {
				// checks for each input controls
				TitleCheckResult res = item_79_title(el);
				if (res == TitleCheckResult.NO_TITLE)
					noTitleControls.add(el);
				item_79_label(el, res, noLabelEmptyTitleControls,
						implicitLabelControls);
			}
		}

		if (noTitleControls.size() > 0)
			addCheckerProblem("C_79.6", "", noTitleControls);
		if (noLabelEmptyTitleControls.size() > 0)
			addCheckerProblem("C_79.0", "", noLabelEmptyTitleControls);
		if (implicitLabelControls.size() > 0)
			addCheckerProblem("C_79.2", "", implicitLabelControls);
	}

	private void item_79_label(Element ctrl, TitleCheckResult res,
			Vector<Node> noLabelEmptyTitleControls,
			Vector<Node> implicitLabelControls) {
		String elType = getFormControlType(ctrl);
		Element l;
		if ((l = hasImplicitLabel(ctrl)) != null) {
			implicitLabelControls.add(l);
			return;
		}
		if (!isLabelable(elType)) {
			return;
		}

		String strid = ctrl.getAttribute("id"); //$NON-NLS-1$
		boolean bHasLabel = this.hasLabel(ctrl);
		boolean bHasTitle = this.hasTitle(ctrl);

		if (!bHasLabel && !(res == TitleCheckResult.G167)) {
			if (res == TitleCheckResult.EMPTY_TITLE) {
				noLabelEmptyTitleControls.add(ctrl);
			}
		} else {
			// TODO highlight the label as well
			if (!hasProperLabel(ctrl)) {
				// in case of TYPE was removed by IE
				addCheckerProblem(
						"C_79.1", //$NON-NLS-1$
						" (input type: " + (elType.equals("") ? "text" : elType) + ")", //$NON-NLS-1$ //$NON-NLS-2$
						ctrl);
			} else {
				// H44 OK
				addCheckerProblem("C_79.5", ctrl); //$NON-NLS-1$

			}
		}
	}

	/**
	 * If a control passes check, it returns true.
	 * 
	 * @param ctrl
	 * @return
	 */
	private TitleCheckResult item_79_title(Element ctrl) {
		if (hasTitle(ctrl)) {
			if (hasBlankTitle(ctrl)) {
				return TitleCheckResult.EMPTY_TITLE;
			}
			addCheckerProblem("C_79.4", ctrl.getAttribute(ATTR_TITLE), ctrl);
			return TitleCheckResult.OK;
		} else {
			if (isLabelable(getFormControlType(ctrl)) && hasLabel(ctrl))
				return TitleCheckResult.OK;
			else { // no title?
				if (check_G167(ctrl))
					return TitleCheckResult.G167;
				else
					return TitleCheckResult.NO_TITLE;
			}
		}
	}

	/**
	 * Looks for an adjacent button to a text. If such text field is found, this
	 * method returns true, otherwise false.
	 * 
	 * @param ctrl
	 *            a form control element
	 */
	private boolean check_G167(Element ctrl) {
		if (HtmlTagUtil.isTextControl(ctrl)) {
			// looks for next control
			Element next = findNextElementNode(ctrl);
			if (next == null || !isButtonControl(next)) {
				return false;
			} else {
				Vector<Node> ctrls = new Vector<Node>();
				ctrls.add(ctrl);
				ctrls.add(next);
				addCheckerProblem("C_79.7", null, ctrls);
				return true;
			}
		} else if (HtmlTagUtil.isButtonControl(ctrl)) {
			// does not occur
			return false;
		} else
			return false;
	}

	/**
	 * Finds most close element node that comes after the given element.
	 * 
	 * @param el
	 * @return the next element node if any. returns null if no such element is
	 *         found.
	 */
	private Element findNextElementNode(Element el) {
		Node current = el;
		while ((current = current.getNextSibling()) != null) {
			short t = current.getNodeType();
			if (current.getNodeType() == Node.TEXT_NODE) {
				if (!isBlankString(current.getNodeValue()))
					return null;
			} else if (current.getNodeType() == Node.ELEMENT_NODE)
				break;
			else {
				// skips other node types (CDATA?)
				// CDATA section treated as comment node
				;
			}
		}
		return (Element) current;
	}

	/**
	 * Checks whether any label attribute exists in controls temporally
	 * implemented as separated method. For new JIS
	 */
	/*
	 * private void item_79_label() { NodeList nl =
	 * target.getElementsByTagName("form"); //$NON-NLS-1$ int length =
	 * nl.getLength(); NodeList labelNl = target.getElementsByTagName("label");
	 * //$NON-NLS-1$ // checks for each <form> element for (int i = 0; i <
	 * length; i++) { Element fEl = (Element) nl.item(i); Vector<Element>
	 * fcVector = getFormControl(fEl); int labelLen = labelNl.getLength(); //
	 * checks for each input controls for (int j = 0; j < fcVector.size(); j++)
	 * { Element el = fcVector.get(j); boolean bTitle = this.hasTitle(el); if
	 * (!bTitle) { // no title for a form control System.out.println("C_79.6");
	 * addCheckerProblem("C_79.6", el); //$NON-NLS-1$ } } } }
	 */

	private void item_80() {
		// NodeList bodyNl = target.getElementsByTagName("body");
		if (body_elements.length > 0) {
			Element bodyEl = body_elements[0];
			Stack<Node> stack = new Stack<Node>();
			Node curNode = bodyEl;
			while (curNode != null) {
				if (curNode.getNodeType() == Node.ELEMENT_NODE) {
					Element el = (Element) curNode;
					String strAlt = el.getAttribute(ATTR_ALT);
					if (strAlt != null && strAlt.length() > 150) {
						// alt text length check
						addCheckerProblem("C_80.0", el); //$NON-NLS-1$
					}
				}

				if (curNode.hasChildNodes()) {
					stack.push(curNode);
					curNode = curNode.getFirstChild();
				} else if (curNode.getNextSibling() != null) {
					curNode = curNode.getNextSibling();
				} else {
					curNode = null;
					while ((curNode == null) && (stack.size() > 0)) {
						curNode = stack.pop();
						curNode = curNode.getNextSibling();
					}
				}
			}
		}
	}

	private void item_85() {
		boolean bHasBgsound = false;
		NodeList nl = target.getElementsByTagName("head"); //$NON-NLS-1$
		Element targetE = null;
		for (int i = 0; i < nl.getLength(); i++) {
			NodeList bgNl = ((Element) nl.item(i))
					.getElementsByTagName("bgsound"); //$NON-NLS-1$
			if (bgNl.getLength() > 0) {
				bHasBgsound = true;
				targetE = (Element) bgNl.item(0);
				break;
			}
		}
		if (bHasBgsound) {
			addCheckerProblem("C_85.0", targetE); //$NON-NLS-1$
		}
	}

	private void item_86() {
		boolean bHasMulti = false;
		for (int i = 0; i < object_elements.length; i++) {
			Element el = object_elements[i];
			String str = el.getAttribute("data"); //$NON-NLS-1$
			str = getFileExtension(str);
			if (isAudioFileExt(str) || isMultimediaFileExt(str)) {
				bHasMulti = true;
				break;
			}
		}

		if (!bHasMulti) {
			for (Element applet : edu.getAppletElements()) {
				NodeList parNl = applet.getElementsByTagName("param"); //$NON-NLS-1$
				int parLength = parNl.getLength();
				for (int j = 0; j < parLength; j++) {
					String str = ((Element) parNl.item(j))
							.getAttribute("value"); //$NON-NLS-1$
					str = getFileExtension(str);
					if (isAudioFileExt(str) || isMultimediaFileExt(str)) {
						bHasMulti = true;
						break;
					}
				}
				if (bHasMulti) {
					break;
				}
			}
		}

		if (!bHasMulti) {
			for (int i = 0; i < aWithHref_hrefs.length; i++) {
				// Element el = aWithHref_elements[i];
				String str = aWithHref_hrefs[i];
				str = getFileExtension(str);
				if (isAudioFileExt(str) || isMultimediaFileExt(str)) {
					bHasMulti = true;
					break;
				}
			}
		}

		if (bHasMulti) {
			addCheckerProblem("C_86.0"); //$NON-NLS-1$
		}

	}

	@SuppressWarnings("nls")
	private void item_88() {
		String charset = "";
		NodeList nl = target.getElementsByTagName("meta");
		int length = nl.getLength();
		for (int i = 0; i < length; i++) {
			Element el = (Element) nl.item(i);
			if (el.hasAttribute("http-equiv") && el.hasAttribute("content")) { //$NON-NLS-1$
				String strMeta = el.getAttribute("http-equiv"); //$NON-NLS-1$
				String strCon = el.getAttribute("content");
				if (strMeta != null && strMeta.equalsIgnoreCase("Content-Type")
						&& strCon != null) {
					int index = strCon.toLowerCase().indexOf("text/html");
					if (index >= 0) {
						strCon = strCon.substring(index + 9);
						index = strCon.indexOf(";");
						if (index >= 0) {
							strCon = strCon.substring(index + 1);
							index = strCon.toLowerCase().indexOf("charset");
							if (index >= 0) {
								strCon = strCon.substring(index + 7);
								index = strCon.indexOf("=");
								if (index >= 0) {
									charset = strCon.substring(index + 1);
								}
							}
						}
					}
				}
			}
		}

		// System.out.println("charset: " + charset);
		if (charset.length() == 0) {
			result.add(new ProblemItemImpl("C_88.0")); //$NON-NLS-1$
		} else {
			// check coding (EUC-JP, Shift_JIS, UTF-8...)
			// addCheckerProblem("C_88.1", charset); //$NON-NLS-1$
		}
	}

	@SuppressWarnings("nls")
	private void item_89() {

		if (body_elements.length == 1
				&& target.getElementsByTagName("frameset").getLength() == 0) {
			Node curNode = body_elements[0].getFirstChild();
			StringBuffer strBuf = new StringBuffer(512);
			Stack<Node> stack = new Stack<Node>();
			while (curNode != null && strBuf.length() < valid_total_text_len) {
				if (curNode.getNodeType() == Node.TEXT_NODE) {
					// &#nbsp; (160)
					strBuf.append(curNode.getNodeValue()
							.replaceAll(String.valueOf((char) 160), "").trim());
				} else if (curNode.getNodeType() == Node.ELEMENT_NODE) {
					Element tmpE = (Element) curNode;

					// need to check element name

					if (tmpE.hasAttribute(ATTR_ALT)) {
						strBuf.append(tmpE
								.getAttribute(ATTR_ALT)
								.replaceAll(String.valueOf((char) 160), "").trim()); //$NON-NLS-1$
					}
					if (tmpE.hasAttribute(ATTR_TITLE)) {
						strBuf.append(tmpE.getAttribute(ATTR_TITLE)
								.replaceAll(String.valueOf((char) 160), "")
								.trim());
					}
				}

				if (curNode.hasChildNodes()) {
					stack.push(curNode);
					curNode = curNode.getFirstChild();
				} else if (curNode.getNextSibling() != null) {
					curNode = curNode.getNextSibling();
				} else {
					curNode = null;
					while ((curNode == null) && (stack.size() > 0)) {
						curNode = stack.pop();
						curNode = curNode.getNextSibling();
					}
				}
			}
			if (strBuf.length() == 0) {
				addCheckerProblem("C_89.0");
			} else if (strBuf.length() < valid_total_text_len) {
				if (img_elements.length > 0) {
					addCheckerProblem("C_89.1");
				} else {
					addCheckerProblem("C_89.2");
				}
			}
		}

	}

	private void item_90() {
		// TODO move to styleCheck

		Set<Element> styleElementList = styleElementMap.keySet();
		for (Element e : styleElementList) {
			String style = styleElementMap.get(e);
			if (style != null) {
				if (BEFORE_PATTERN.matcher(style).matches()) {
					addCheckerProblem("C_90.0", "", e);
				}
				if (AFTER_PATTERN.matcher(style).matches()) {
					addCheckerProblem("C_90.1", "", e);
				}
			}
		}

		Set<IStyleSheet> keys = styleSheetsMap.keySet();
		for (IStyleSheet ss : keys) {
			if (ss.getHref() != null && ss.getHref().length() > 0) {
				// avoid duplication
				String style = styleSheetsMap.get(ss);
				if (BEFORE_PATTERN.matcher(style).matches())
					addCheckerProblem("C_90.0", "(" + ss.getHref() + ")");
				if (AFTER_PATTERN.matcher(style).matches())
					addCheckerProblem("C_90.1", "(" + ss.getHref() + ")");
			}
		}
	}

	/**
	 * ALT text check for image buttons, area elements.
	 */
	// For new JIS
	private void item_300() {
		for (Element button : edu.getImageButtons()) {
			String alt = getAttribute(button, "alt");
			if (alt == null)
				; // B_1 error
			else {
				TextCheckResult result = checker.checkAlt(alt);
				if (!TextCheckResult.OK.equals(result)) {
					if (TextCheckResult.SPACE_SEPARATED.equals(result)
							|| TextCheckResult.SPACE_SEPARATED_JP
									.equals(result))
						addCheckerProblem("C_300.3", alt, button);
					else if (result.equals(TextCheckResult.NULL)
							|| result.equals(TextCheckResult.BLANK))
						addCheckerProblem("C_300.4", alt, button);
					else
						addCheckerProblem("C_300.0", alt, button);
				}
			}
		}
		for (Element button : edu.getTextButtons()) {
			String value = getAttribute(button, "value");
			if (value == null)
				; // ??? error
			else {
				TextCheckResult result = checker.checkAlt(value);
				if (!TextCheckResult.OK.equals(result)) {
					// addCheckerProblem("C_300.0", alt, button);
				}
			}
		}
		for (Element area : edu.getAreaElements()) {
			String alt = getAttribute(area, "alt");
			if (alt == null) {
				; // B_2 error
			} else {
				Set<String> ngWord = new TreeSet<String>();
				ngWord.add("area");
				TextCheckResult result = checker.checkAlt(alt, ngWord);
				if (result.equals(TextCheckResult.OK)) {
					;
				} else if (result.equals(TextCheckResult.SPACE_SEPARATED)
						|| result.equals(TextCheckResult.SPACE_SEPARATED_JP)) {
					;
				} else if (!result.equals(TextCheckResult.BLANK)
						|| area.hasAttribute("href")) {

					Element map = (Element) area.getParentNode();
					for (Element image : HtmlTagUtil.getImgElementsFromMap(
							target, map)) {
						int id = document2IdMap.get(image);

						IProblemItem tmpP = addCheckerProblem("C_300.1", alt,
								area);
						tmpP.setHighlightTargetIds(new HighlightTargetId(id, id));
						edu.appendErrorIcon(tmpP, area);
					}
				}
			}
		}
		for (Element applet : edu.getAppletElements()) {
			String alt = getAttribute(applet, "alt");
			if (alt == null)
				; // B_2 error
			else {
				Set<String> ngWord = new TreeSet<String>();
				ngWord.add("applet");
				ngWord.add("\u30a2\u30d7\u30ec\u30c3\u30c8"); // "applet" in
				// Japanese
				ngWord.add("\u30d7\u30ed\u30b0\u30e9\u30e0"); // "program" in
				// Japanese
				TextCheckResult result = checker.checkAlt(alt, ngWord);
				if (!TextCheckResult.OK.equals(result)) {
					addCheckerProblem("C_300.2", alt, applet);
				}
			}
		}
	}

	// moved into 600.18
	// // For new JIS
	// @SuppressWarnings("nls")
	// private void item_320() {
	// addCheckerProblem("C_320.0");
	// }

	// For new JIS
	private void item_331() {
		Vector<Node> withoutScope = new Vector<Node>();
		Vector<Node> invalidScope = new Vector<Node>();

		for (Element table : dataTableList) {
			int thCount = 0;
			boolean isFirstRow = true;
			boolean isHeaderRow = false;
			boolean isHeaderColumn = true;
			int firstRowLength = 0;
			int trCount = 0;

			for (Element tr : edu.getElementsList(table, "tr")) { //$NON-NLS-1$
				trCount++;
				List<Element> cells = edu.getElementsList(tr, "th"); //$NON-NLS-1$
				if (isFirstRow) {
					isFirstRow = false;
					firstRowLength = tr.getChildNodes().getLength();
					if (cells.size() == firstRowLength) {
						isHeaderRow = true;
					}
				}
				if (isHeaderColumn) {
					isHeaderColumn = tr.hasChildNodes()
							&& tr.getFirstChild().getNodeName()
									.equalsIgnoreCase("th");
				}
				if (cells.size() > 0) {
					thCount += cells.size();
				}
			}

			boolean isSimpleTable = (isHeaderRow && firstRowLength == thCount)
					|| (isHeaderColumn && trCount == thCount);

			// all data tables are leaf tables, so getElements() suffice.
			for (Element th : edu.getElementsList(table, "th")) {
				if (!th.hasAttribute("scope")) {
					if (!isSimpleTable) {
						withoutScope.add(th);
					}
				} else if (!th.getAttribute("scope").matches(
						"row(group)?|col(group)?")) {
					invalidScope.add(th);
				}
			}
		}
		if (withoutScope.size() > 0)
			addCheckerProblem("C_331.0", "", withoutScope);
		if (invalidScope.size() > 0)
			addCheckerProblem("C_331.1", "", invalidScope);
	}

	// For new JIS
	private void item_332() {
		for (Element table : dataTableList) {
			List<Element> cells = edu.getElementsList(target, "th", "td");
			for (Element cell : cells) {
				if (cell.hasAttribute("headers")) {
					for (String id : cell.getAttribute("headers").split(
							"[ \t]+")) {
						Element referred = target.getElementById(id);
						if (referred == null) {
							addCheckerProblem("C_332.1", "(id=" + id + ")",
									cell);
						} else if (!referred.getTagName().toLowerCase()
								.matches("td|th")) {
							addCheckerProblem("C_332.2", referred.getTagName()
									.toLowerCase(), cell);
						}
					}
				}
			}
		}
	}

	// For new JIS
	@SuppressWarnings("nls")
	private void item_380() {
		Vector<Node> noSubmitForms = new Vector<Node>();
		for (Element form : formList) {
			boolean hasSubmit = false;
			NodeList inputs = form.getElementsByTagName("input");
			for (int j = 0; j < inputs.getLength(); j++) {
				Element input = (Element) inputs.item(j);
				String typeS = input.getAttribute("type");
				if ("submit".equals(typeS) || "image".equals(typeS)) {
					hasSubmit = true;
					break;
				}
			}
			if (!hasSubmit) {
				NodeList buttons = form.getElementsByTagName("button");
				for (int j = 0; j < buttons.getLength(); j++) {
					Element button = (Element) buttons.item(j);
					String typeS = button.getAttribute("type");
					if ("submit".equals(typeS)) {
						hasSubmit = true;
						break;
					}
				}
			}
			if (!hasSubmit)
				noSubmitForms.add(form);
		}
		if (noSubmitForms.size() > 0)
			addCheckerProblem("C_380.0", null, noSubmitForms);
	}

	@SuppressWarnings("nls")
	private void formCheck() {
		for (Element form : formList) {
			if (form.getElementsByTagName("select").getLength() > 0)
				addCheckerProblem("C_381.0", form);
		}

		NodeList nl = null;
		if ((nl = target.getElementsByTagName("form")).getLength() > 0) { //$NON-NLS-1$
			addCheckerProblem("C_382.0", "", nl);
			addCheckerProblem("C_383.0", "", nl);
			addCheckerProblem("C_387.0", "", nl);
			addCheckerProblem("C_388.0", "", nl);
		}

	}

	// For new JIS
	@SuppressWarnings("nls")
	private void item_384() {
		if (formVwithText == null)
			formVwithText = getFormsWithTextinput();
		if (formVwithText.size() > 0)
			addCheckerProblem("C_384.0", "", formVwithText); //$NON-NLS-1$ //$NON-NLS-1$
	}

	// For new JIS
	@SuppressWarnings("nls")
	private void item_385() {
		if (formVwithText == null)
			formVwithText = getFormsWithTextinput();
		if (formVwithText.size() > 0)
			addCheckerProblem("C_385.0", "", formVwithText);
	}

	// For new JIS
	@SuppressWarnings("nls")
	private void item_386() {
		if (formVwithText == null)
			formVwithText = getFormsWithTextinput();
		if (formVwithText.size() > 0)
			addCheckerProblem("C_386.0", "", formVwithText);
	}

	// For new JIS
	@SuppressWarnings("nls")
	private void item_389() {
		if (formVwithText == null)
			formVwithText = getFormsWithTextinput();
		if (formVwithText.size() > 0)
			addCheckerProblem("C_389.0", "", formVwithText);
	}

	// For new JIS
	@SuppressWarnings("nls")
	private void item_422() {
		List<Element> accesskeys = edu.getAccessKeyElements();
		Map<String, List<Element>> map = new HashMap<String, List<Element>>();
		for (Element element : accesskeys) {
			String key = element.getAttribute("accesskey");
			if (!map.containsKey(key))
				map.put(key, new ArrayList<Element>());
			map.get(key).add(element);
		}
		for (String key : map.keySet()) {
			if (map.get(key).size() > 1) {
				addCheckerProblem("C_422.0", key,
						new Vector<Node>(map.get(key)));
			}
		}
	}

	private void item_423() {
		List<Element> idElementList = edu.getElementsWithId();
		Map<String, List<Element>> map = new HashMap<String, List<Element>>();
		for (Element element : idElementList) {
			String key = element.getAttribute("id");
			if (!map.containsKey(key)) {
				map.put(key, new ArrayList<Element>());
			}
			map.get(key).add(element);
		}
		for (String key : map.keySet()) {
			if (map.get(key).size() > 1) {
				addCheckerProblem("C_423.0", key,
						new Vector<Node>(map.get(key)));
			}
		}
	}

	/**
	 * Displays AA items
	 */
	private void always() {

		// language check
		addCheckerProblem("C_19.0"); //$NON-NLS-1$

		// Use the ABBR and ACRONYM elements alert
		// check sequence of capital
		addCheckerProblem("C_20.0"); //$NON-NLS-1$

		// alert to use latest technology
		addCheckerProblem("C_47.0"); //$NON-NLS-1$

		// alert to group related elements
		addCheckerProblem("C_55.0"); //$NON-NLS-1$

		if (hasAwithHref) {
			// link phrase alert
			addCheckerProblem("C_56.1"); //$NON-NLS-1$

			// TBD estimation
			// alert to identify logical groups of links
			addCheckerProblem("C_64.0"); //$NON-NLS-1$

			addCheckerProblem("C_65.0"); //$NON-NLS-1$

			addCheckerProblem("C_81.0"); //$NON-NLS-1$
		}

		// alert if there is a site map or...
		addCheckerProblem("C_61.0"); //$NON-NLS-1$

		// alert if there is a clear navigation structure
		addCheckerProblem("C_62.0"); //$NON-NLS-1$

		// TBD estimation
		// alert if there are navigation bars for navigation structure
		addCheckerProblem("C_63.0"); //$NON-NLS-1$

		// alert if there is distinguishing information
		addCheckerProblem("C_67.0"); //$NON-NLS-1$

		// alert about language
		addCheckerProblem("C_70.0"); //$NON-NLS-1$

		// alert
		addCheckerProblem("C_71.0"); //$NON-NLS-1$

		// alert about consistant style
		addCheckerProblem("C_72.0"); //$NON-NLS-1$

		addCheckerProblem("C_82.0"); //$NON-NLS-1$
		addCheckerProblem("C_83.0"); //$NON-NLS-1$
		addCheckerProblem("C_84.0"); //$NON-NLS-1$

		addCheckerProblem("C_87.0"); //$NON-NLS-1$

		// moved into mediaCheck
		// if (SHOW_ALWAYS || object_elements.length > 0
		// || embed_elements.length > 0
		// || edu.getAppletElements().size() > 0) {
		// addCheckerProblem("C_500.0");
		// addCheckerProblem("C_500.1");
		// }

		addCheckerProblem("C_321.0");
		addCheckerProblem("C_322.0");

		addCheckerProblem("C_421.0");
		addCheckerProblem("C_421.1", isXHTML ? "XHTML" : "HTML");

		addCheckerProblem("C_500.11");
		addCheckerProblem("C_500.12");
		addCheckerProblem("C_500.2");
		addCheckerProblem("C_500.3");

		// moved into 15 & 388
		// // TODO same as above
		// if (SHOW_ALWAYS || headings.length > 0
		// || target.getElementsByTagName("label").getLength() > 0)
		// addCheckerProblem("C_500.4");

		addCheckerProblem("C_500.5");
		addCheckerProblem("C_500.6");
		addCheckerProblem("C_500.7");
		addCheckerProblem("C_500.8");
		addCheckerProblem("C_500.9");
		addCheckerProblem("C_500.10");

		// addCheckerProblem("C_500.13");
		// addCheckerProblem("C_500.14");
		// addCheckerProblem("C_500.15");
		// addCheckerProblem("C_500.16");

		addCheckerProblem("C_600.0");

		// moved into mediaCheck
		// addCheckerProblem("C_600.1");
		// addCheckerProblem("C_600.2");
		// addCheckerProblem("C_600.6");
		// addCheckerProblem("C_600.7");

		addCheckerProblem("C_600.3");
		addCheckerProblem("C_600.4");
		addCheckerProblem("C_600.5");

		addCheckerProblem("C_600.8");
		addCheckerProblem("C_600.9");
		addCheckerProblem("C_600.10");
		addCheckerProblem("C_600.11");
		addCheckerProblem("C_600.12");
		addCheckerProblem("C_600.13");
		addCheckerProblem("C_600.14");
		addCheckerProblem("C_600.15");

		// move into mediaCheck
		// addCheckerProblem("C_600.16");

		addCheckerProblem("C_600.17");
		addCheckerProblem("C_600.18");
		addCheckerProblem("C_600.19");
	}

	private void styleCheck() {
		Set<Element> styleElementList = styleElementMap.keySet();
		for (Element e : styleElementList) {
			String style = styleElementMap.get(e);
			if (style != null) {
				Set<String> colorSelector = new HashSet<String>();
				Set<String> bgcolorSelector = new HashSet<String>();
				Set<String> allcolorSelector = new HashSet<String>();
				Set<String> fixSelector = new HashSet<String>();

				Matcher matcher = STYLEITEM.matcher(style);
				while (matcher.find()) {
					String group = matcher.group();
					boolean color = COLOR.matcher(group).find();
					boolean bgColor = BGCOLOR.matcher(group).find()
							|| BGCOLOR2.matcher(group).find();

					boolean fix = FIXSIZE_PATTERN.matcher(group).find();

					// System.out.println(color + "/" + bgColor + "\t" + group);
					if (color || bgColor) {
						String selector = getSelector(group);
						if (color && !bgColor) {
							colorSelector.add(selector);
						} else if (!color && bgColor) {
							bgcolorSelector.add(selector);
						} else {
							allcolorSelector.add(selector);
						}
					}
					if (fix) {
						fixSelector.add(getSelector(group));
					}
				}
				if (colorSelector.size() > 0) {
					addCheckerProblem("C_500.17", "(" + Messages.StyleElement
							+ ", " + Messages.Selector + "="
							+ getSelectors(colorSelector) + ")", e);
				}
				if (bgcolorSelector.size() > 0) {
					addCheckerProblem("C_500.18", "(" + Messages.StyleElement
							+ ", " + Messages.Selector + "="
							+ getSelectors(bgcolorSelector) + ")", e);
				}
				if (allcolorSelector.size() > 0) {
					addCheckerProblem("C_8.0", "(" + Messages.StyleElement
							+ ", " + Messages.Selector + "="
							+ getSelectors(allcolorSelector) + ")", e);
				}
				if (fixSelector.size() > 0) {
					addCheckerProblem("C_500.19", "(" + Messages.StyleElement
							+ ", " + Messages.Selector + "="
							+ getSelectors(fixSelector) + ")", e);
				}

			}
		}

		Set<IStyleSheet> keys = styleSheetsMap.keySet();
		for (IStyleSheet ss : keys) {
			if (ss.getHref() != null && ss.getHref().length() > 0) {
				// avoid duplication
				String style = styleSheetsMap.get(ss);
				Set<String> colorSelector = new HashSet<String>();
				Set<String> bgcolorSelector = new HashSet<String>();
				Set<String> allcolorSelector = new HashSet<String>();
				Set<String> fixSelector = new HashSet<String>();

				Matcher matcher = STYLEITEM.matcher(style);
				while (matcher.find()) {
					String group = matcher.group();
					boolean color = COLOR.matcher(group).find();
					boolean bgColor = BGCOLOR.matcher(group).find()
							|| BGCOLOR2.matcher(group).find();
					boolean fix = FIXSIZE_PATTERN.matcher(group).find();

					if (color || bgColor) {
						String selector = getSelector(group);
						if (color && !bgColor) {
							colorSelector.add(selector);
						} else if (!color && bgColor) {
							bgcolorSelector.add(selector);
						} else {
							allcolorSelector.add(selector);
						}
					}
					if (fix) {
						fixSelector.add(getSelector(group));
					}

					// System.out.println(color + "/" + bgColor + "\t" +
					// group);

				}
				if (colorSelector.size() > 0) {
					addCheckerProblem("C_500.17", "(" + ss.getHref() + ", "
							+ Messages.Selector + "="
							+ getSelectors(colorSelector) + ")");
				}
				if (bgcolorSelector.size() > 0) {
					addCheckerProblem("C_500.18", "(" + ss.getHref() + ", "
							+ Messages.Selector + "="
							+ getSelectors(bgcolorSelector) + ")");
				}
				if (allcolorSelector.size() > 0) {
					addCheckerProblem("C_8.0", "(" + ss.getHref() + ", "
							+ Messages.Selector + "="
							+ getSelectors(allcolorSelector) + ")");
				}
				if (fixSelector.size() > 0) {
					addCheckerProblem("C_500.19", "(" + ss.getHref() + ", "
							+ Messages.Selector + "="
							+ getSelectors(fixSelector) + ")");
				}

			}
		}

		for (Element e : elementsWithStyleList) {
			String style = e.getAttribute("style");

			boolean color = COLOR_ATTR.matcher(style).matches(); // need to use
																	// matches()
			boolean bgColor = BGCOLOR_ATTR.matcher(style).find()
					|| BGCOLOR2_ATTR.matcher(style).find();

			boolean fix = FIXSIZE_PATTERN_ATTR.matcher(style).find();
			// System.out.println(color + "/" + bgColor + "\t" + style);

			if (color || bgColor) {
				if (color && !bgColor) {
					addCheckerProblem("C_500.17", "(" + style + ")", e);
				} else if (!color && bgColor) {
					addCheckerProblem("C_500.18", "(" + style + ")", e);
				} else {
					addCheckerProblem("C_8.0", "(" + style + ")", e);
				}
			}

			if (fix) {
				addCheckerProblem("C_500.20", "(" + style + ")", e); // error
			}
		}

		// Special check for body element
		// http://www.w3.org/TR/html4/sgml/loosedtd.html#bodycolors

		if (body_elements.length > 0) {
			Element bodyEl = body_elements[0];
			boolean color = bodyEl.getAttribute("text").length() > 0;
			boolean bgColor = bodyEl.getAttribute("bgcolor").length() > 0;

			boolean linkColor = (bodyEl.getAttribute("link").length() > 0
					|| bodyEl.getAttribute("vlink").length() > 0 || bodyEl
					.getAttribute("alink").length() > 0);

			if (color && !bgColor) {
				addCheckerProblem("C_500.17", "", bodyEl);
			} else if (!color && bgColor) {
				addCheckerProblem("C_500.18", "", bodyEl);
			}

			if (linkColor) {
				addCheckerProblem("C_500.18", "(link)", bodyEl);
			}

		}
	}

	private String getSelector(String targetString) {
		Pattern SELECTOR = Pattern.compile("^.*\\{", Pattern.MULTILINE);
		Matcher matcher = SELECTOR.matcher(targetString);
		if (matcher.find()) {
			String tmpS = matcher.group();
			return (tmpS.substring(0, tmpS.lastIndexOf("{")).trim());
		}
		return "";
	}

	private String getSelectors(Set<String> target) {
		StringBuffer tmpSB = new StringBuffer();
		for (String tmpS : target) {
			tmpSB.append("\"" + tmpS + "\", ");
		}
		if (tmpSB.length() > 2) {
			tmpSB.setLength(tmpSB.length() - 2);
		}
		return (tmpSB.toString());
	}

	// Mobile Web Evaluation (from here)
	private void mobile_1() {
		// TODO implement evaluation
		//addCheckerProblem("M_1"); //$NON-NLS-1$
	}

	// Mobile Web Evaluation (end here)

	private void validateHtml() {
		if (body_elements.length > 1) {
			addCheckerProblem("C_1000.0"); //$NON-NLS-1$
		} else if (body_elements.length == 0
				&& !docTypeS.toLowerCase().contains("frameset")) {
			addCheckerProblem("C_1000.4"); //$NON-NLS-1$
		}
	}

	// @SuppressWarnings("nls")
	// private void checkDomDifference() {
	//
	// if (edu.getInvisibleElementCount() > 0) {
	// addCheckerProblem("C_201.0");
	// }
	// String[] invisibleLinkStrings = edu.getInvisibleLinkStrings();
	// for (int i = 0; i < invisibleLinkStrings.length; i++) {
	// if (invisibleLinkStrings[i].trim().length() > 0) {
	// addCheckerProblem("C_201.1", " (href="
	// + invisibleLinkStrings[i] + ")");
	// }
	// }
	//
	// Set<String> notExistSet = edu.getNotExistHrefSet();
	// for (String href : notExistSet) {
	// addCheckerProblem("C_200.0", " (href=" + href + ")");
	// }
	// if (notExistSet.size() > 10) {
	// addCheckerProblem("C_200.1");
	// }
	//
	// }

	private void checkAbsoluteSize(String strName) {
		NodeList nl = target.getElementsByTagName(strName);
		int length = nl.getLength();
		Vector<Node> nodeV = new Vector<Node>();
		for (int i = 0; i < length; i++) {
			Element el = (Element) nl.item(i);
			String strWidth = el.getAttribute("width"); //$NON-NLS-1$
			String strHeight = el.getAttribute("height"); //$NON-NLS-1$
			if ((strWidth != null && !strWidth.equals("") //$NON-NLS-1$
			&& strWidth.indexOf("%") == -1) //$NON-NLS-1$
					|| (strHeight != null && !strHeight.equals("") //$NON-NLS-1$
					&& strHeight.indexOf("%") == -1)) { //$NON-NLS-1$
				// absolute width or height
				nodeV.add(el);
			}
		}
		if (nodeV.size() > 0) {
			addCheckerProblem("C_13.0", "", nodeV);//$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	private boolean hasOpenWndEvent(Element element, String[] targetAttrs) {

		// need to check open(...) (can use without 'window.')

		for (int i = 0; i < targetAttrs.length; i++) {
			String str = element.getAttribute(targetAttrs[i]);
			if (str.toLowerCase().indexOf(WINDOW_OPEN) >= 0) {
				return true;
			}
		}
		return false;
	}

	private void checkObsoluteEle(String problemId, String strEle) {
		NodeList nl = target.getElementsByTagName(strEle);
		if (nl.getLength() > 0) {
			addCheckerProblem(problemId, strEle, nl);
		}
	}

	private String getFormControlType(Element el) {
		String strName = el.getNodeName().toLowerCase();
		if (strName.equals("input")) { //$NON-NLS-1$
			return el.getAttribute("type").toLowerCase(); //$NON-NLS-1$
		} else {
			return strName;
		}
	}

	/**
	 * Returns radio buttons and check boxes contained in the specified form
	 * element.
	 * 
	 * @param form
	 * @return A <code>List</code> of <code>Element</code>s.
	 */
	private List<Element> getRadioAndCheck(Element form) {
		List<Element> returns = new ArrayList<Element>();
		List<Element> inputs = edu.getElementsList(form, "input");
		for (Element e : inputs) {
			if (e.getAttribute("type").toLowerCase().matches("radio|checkbox"))
				returns.add(e);
		}
		return returns;
	}

	/**
	 * Obtains input controls in the given form element.
	 * 
	 * @param formEl
	 * @return a Vector of controls
	 */
	private List<Element> getFormControl(Element formEl) {
		List<Element> fcVector = new ArrayList<Element>();
		NodeList nl = formEl.getElementsByTagName("input"); //$NON-NLS-1$
		int length = nl.getLength();
		for (int i = 0; i < length; i++) {
			Element el = (Element) nl.item(i);
			String strType = el.getAttribute("type").toLowerCase(); //$NON-NLS-1$
			if (strType.equals("") // default is text? //$NON-NLS-1$
					|| strType.equals("text") //$NON-NLS-1$
					|| strType.equals("textarea") //$NON-NLS-1$
					|| strType.equals("radio") //$NON-NLS-1$
					|| strType.equals("checkbox") //$NON-NLS-1$
					|| strType.equals("file") //$NON-NLS-1$ // For new JIS
					|| strType.equals("password")) { //$NON-NLS-1$
				fcVector.add(el);
			}

		}

		nl = formEl.getElementsByTagName("textarea"); //$NON-NLS-1$
		length = nl.getLength();
		for (int i = 0; i < length; i++) {
			Element el = (Element) nl.item(i);
			fcVector.add(el);
		}

		nl = formEl.getElementsByTagName("select"); //$NON-NLS-1$
		length = nl.getLength();
		for (int i = 0; i < length; i++) {
			Element el = (Element) nl.item(i);
			fcVector.add(el);
		}

		nl = formEl.getElementsByTagName("html:text"); //$NON-NLS-1$
		length = nl.getLength();
		for (int i = 0; i < length; i++) {
			Element el = (Element) nl.item(i);
			fcVector.add(el);
		}

		nl = formEl.getElementsByTagName("html:radio"); //$NON-NLS-1$
		length = nl.getLength();
		for (int i = 0; i < length; i++) {
			Element el = (Element) nl.item(i);
			fcVector.add(el);
		}

		return fcVector;
	}

	private int getFormControlNum(Element formEl) {
		int iNum = 0;
		NodeList nl = formEl.getElementsByTagName("input"); //$NON-NLS-1$
		iNum += nl.getLength();
		nl = formEl.getElementsByTagName("select"); //$NON-NLS-1$
		iNum += nl.getLength();
		nl = formEl.getElementsByTagName("textarea"); //$NON-NLS-1$
		iNum += nl.getLength();
		nl = formEl.getElementsByTagName("html:text"); //$NON-NLS-1$
		iNum += nl.getLength();
		nl = formEl.getElementsByTagName("html:radio"); //$NON-NLS-1$
		iNum += nl.getLength();
		return iNum;
	}

	/**
	 * Returns true if the specified form element has any text input controls.
	 * For new JIS.
	 * 
	 * @param form
	 * @return
	 */
	private boolean hasTextFormControl(Element form) {
		int iNum = 0;
		for (Element e : edu.getElementsList(form, "input")) { //$NON-NLS-1$
			if (e.getAttribute("type").toLowerCase()
					.matches("|text(area)?|password"))
				iNum++;
		}
		iNum += form.getElementsByTagName("textarea").getLength(); //$NON-NLS-1$
		iNum += form.getElementsByTagName("html:text").getLength(); //$NON-NLS-1$
		return (iNum > 0);
	}

	private Vector<Node> getFormsWithTextinput() {
		Vector<Node> forms = new Vector<Node>();
		for (Element form : formList) {
			if (hasTextFormControl(form))
				forms.add(form);
		}
		return forms;
	}

	/**
	 * Returns true if the given control type is usually used with label
	 * elements.
	 * 
	 * @return
	 */
	private boolean isLabelable(String type) {
		return type.matches("|text(area)?|checkbox|radio|file|password|select");
	}

	/**
	 * For new JIS
	 * 
	 * @param el
	 * @param labels
	 * @return
	 */
	private boolean hasLabel(Element el) {
		String strid = el.getAttribute("id"); //$NON-NLS-1$

		if (strid.equals("")) //$NON-NLS-1$
			return false; // no id

		for (Element e : labelList) {
			String strFor = e.getAttribute("for"); //$NON-NLS-1$
			if (strFor != null && strFor.equalsIgnoreCase(strid)) {
				return true; // label found
			}
		}
		return false; // no label found
	}

	/**
	 * Detects use of implicit labels. If an implicit label is used, the label
	 * element is returned. Otherwise, null is returned. For new JIS.
	 * 
	 * @param el
	 * @return label element when an implicit label is used.
	 */
	private Element hasImplicitLabel(Element el) {
		// TODO to be refined so that it looks up in ascendant, not in a parent
		Node n = el.getParentNode();
		if (!(n instanceof Element))
			return null;
		Element e = (Element) n;
		if (e.getTagName().toLowerCase().equals("label"))
			return e;
		else
			return null;
	}

	/**
	 * Stub function, to be refined. For new JIS
	 * 
	 * @param title
	 * @return
	 */
	private boolean isInappropriateTitle(String title) {
		return title.matches("(?i).*untitled.*");
	}

	/**
	 * Checks if the specified form control has a properly located label.
	 * 
	 * @param el
	 * @return
	 */
	private boolean hasProperLabel(Element el) {

		// need to consider position
		boolean bRadioCheckbox = getFormControlType(el).matches(
				"radio|checkbox"); //$NON-NLS-1$

		Node node = el;
		if (bRadioCheckbox) {
			while (node.getNextSibling() == null) {
				if (node.getNodeName().equalsIgnoreCase("body")) { //$NON-NLS-1$
					return false;
				}
				node = node.getParentNode();
			}
			if (node.getNextSibling().getNodeType() != Node.ELEMENT_NODE)
				return false;
			Element nextEl = (Element) node.getNextSibling();
			Element labelEl;
			if (nextEl.getNodeName().equalsIgnoreCase("label")) { //$NON-NLS-1$
				labelEl = nextEl;
			} else {
				NodeList nl = nextEl.getElementsByTagName("label"); //$NON-NLS-1$
				if (nl.getLength() == 0) {
					return false;
				} else {
					labelEl = (Element) nl.item(0);
				}
			}

			String strId = el.getAttribute("id"); //$NON-NLS-1$
			String strFor = labelEl.getAttribute("for"); //$NON-NLS-1$
			if (!strId.equals(strFor)) {
				return false;
			} else {
				if (getTextAltDescendant(nextEl).trim().indexOf(
						getTextAltDescendant(labelEl).trim()) == 0) {
					return true;
				} else {
					return false;
				}
			}

		} else {
			while (node.getPreviousSibling() == null) {
				if (node.getNodeName().equalsIgnoreCase("body")) { //$NON-NLS-1$
					return false;
				}
				node = node.getParentNode();
			}
			if (node.getPreviousSibling().getNodeType() != Node.ELEMENT_NODE)
				return false;
			Element preEl = (Element) node.getPreviousSibling();
			Element labelEl;
			if (preEl.getNodeName().equalsIgnoreCase("label")) { //$NON-NLS-1$
				labelEl = preEl;
			} else {
				NodeList nl = preEl.getElementsByTagName("label"); //$NON-NLS-1$
				if (nl.getLength() == 0) {
					return false;
				} else {
					labelEl = (Element) nl.item(nl.getLength() - 1);
				}
			}
			String strId = el.getAttribute("id"); //$NON-NLS-1$
			String strFor = labelEl.getAttribute("for"); //$NON-NLS-1$
			if (!strId.equals(strFor)) {
				return false;
			} else {
				String strWhole = getTextAltDescendant(preEl).trim();
				String strLabel = getTextAltDescendant(labelEl).trim();
				if (strWhole.indexOf(strLabel) == strWhole.length()
						- strLabel.length()) {
					return true;
				} else {
					return false;
				}
			}

		}
	}

	private boolean isAsciiArtString(String str) {

		if (str == null) {
			return false;
		}

		// int realTotal = str.length();
		String[] tmpS = str.split("\\p{Space}"); //$NON-NLS-1$
		int num = 0;
		int total = 0;

		for (int j = 0; j < tmpS.length; j++) {
			String target = tmpS[j];
			int strLength = target.length();
			total += strLength;

			target = target.replaceAll("\\p{Punct}", ""); //$NON-NLS-1$  //$NON-NLS-2$
			num += strLength - target.length();

			strLength = target.length();
			for (int i = 0; i < strLength; i++) {
				if (artCharSet.contains(target.substring(i, i + 1))) {
					num++;
				}
			}

		}
		if (total == 0)
			total = 1;
		if (num > 30 && (double) num / total > 0.8)
			return true;
		else if (num > 30 && checker.isAsciiArtString(str)) // another AA
															// checking routine
			return true;
		else
			return false;
	}

	private boolean isNormalImage(Element imgEl) {
		String strWidth = imgEl.getAttribute("width"); //$NON-NLS-1$
		String strHeight = imgEl.getAttribute("height"); //$NON-NLS-1$
		int iWidth = 0, iHeight = 0;
		try {
			if (strWidth != null)
				iWidth = Integer.valueOf(strWidth).intValue();
			if (strHeight != null)
				iHeight = Integer.valueOf(strHeight).intValue();

		} catch (NumberFormatException e) {
			iWidth = 100;
			iHeight = 100;
		}
		// ignore small image according to bobby
		if (iWidth < 50 || iHeight < 50) {
			int iBig, iSmall;
			if (iWidth > iHeight) {
				iBig = iWidth;
				iSmall = iHeight;
			} else {
				iBig = iHeight;
				iSmall = iWidth;
			}
			if (iBig < 50) {
				return false;
			} else if ((double) iSmall / iBig < 0.2) {
				return false;
			}
		}
		return true;
	}

	// TODO check
	private boolean isHtmlFile(String strFile) {
		int iPos = strFile.lastIndexOf("."); //$NON-NLS-1$
		if (iPos > 0) {
			String strExt = strFile.substring(iPos + 1).toLowerCase();
			if (strExt.equals("html") //$NON-NLS-1$
					|| strExt.equals("htm") //$NON-NLS-1$
					|| strExt.equals("jsp") //$NON-NLS-1$
					|| strExt.equals("php") //$NON-NLS-1$
					|| strExt.equals("shtml")) //$NON-NLS-1$
				return true;
			else if (strFile.toLowerCase().indexOf(".cgi") > 0) //$NON-NLS-1$
				return true;
		}
		return false;
	}

	private boolean isAudioFileExt(String strFileExt) {
		for (int i = 0; i < AUDIO_FILE_EXTENSION.length; i++) {
			if (strFileExt.equalsIgnoreCase(AUDIO_FILE_EXTENSION[i])) {
				return true;
			}
		}
		return false;
	}

	private boolean isMultimediaFileExt(String strFileExt) {
		for (int i = 0; i < MULTIMEDIA_FILE_EXTENSION.length; i++) {
			if (strFileExt.equalsIgnoreCase(MULTIMEDIA_FILE_EXTENSION[i])) {
				return true;
			}
		}
		return false;
	}

	private boolean isLeafBlockEle(Node node) {
		String str = node.getNodeName().toLowerCase();
		if (!blockEleSet.contains(str)) {
			return false;
		}
		if (!node.hasChildNodes()) {
			return true;
		}
		Node curNode = node.getFirstChild();
		Stack<Node> stack = new Stack<Node>();
		while (curNode != null) {
			str = curNode.getNodeName().toLowerCase();
			if (blockEleSet.contains(str)) {
				return false;
			}

			if (curNode.hasChildNodes()) {
				stack.push(curNode);
				curNode = curNode.getFirstChild();
			} else if (curNode.getNextSibling() != null) {
				curNode = curNode.getNextSibling();
			} else {
				curNode = null;
				while ((curNode == null) && (stack.size() > 0)) {
					curNode = stack.pop();
					curNode = curNode.getNextSibling();
				}
			}

		}
		return true;
	}

	private int getWordCount(String str) {
		StringTokenizer st = new StringTokenizer(str,
				" \t\n\r\f,.[]()<>!?:/\"\u3001\u3002\u300c\u300d\u30fb\u3008\u3009\u3000"); //$NON-NLS-1$
		return st.countTokens();

	}

	private String getFileExtension(String strName) {
		int iPos = strName.lastIndexOf("."); //$NON-NLS-1$
		if (iPos > 0) {
			return strName.substring(iPos + 1);
		}
		return ""; //$NON-NLS-1$
	}

	private boolean isElementVisible(Element el) {
		// TODO function stub // For new JIS
		return true;
	}

	// For new JIS
	private boolean isButton(Element el) {
		return (el.getTagName().toLowerCase().equals("input") && (el
				.getAttribute("type").toLowerCase().equals("submit") || el
				.getAttribute("type").equals("image")))
				|| (el.getTagName().toLowerCase().equals("button") && el
						.getAttribute("type").toLowerCase().equals("submit"));
	}

	private List<Element> getDirectDescendantElements(Element element,
			String tagName) {
		return getDirectDescendantElements(element, tagName, element
				.getTagName().toLowerCase());
	}

	/**
	 * Utility function that returns a List array instead of a NodeList array.
	 * 
	 * @param el
	 * @param tagName
	 * @return list of elements with given tag name that are direct descendants
	 *         of the node.
	 */
	private List<Element> getDirectDescendantElements(Element element,
			String tagName, String excluded) {
		List<Element> nodes = new ArrayList<Element>();
		NodeList children = element.getChildNodes();
		for (int i = 0; i < children.getLength(); i++) {
			Node n = children.item(i);
			if (n.getNodeType() == Node.ELEMENT_NODE) {
				Element e = (Element) n;
				if (e.getTagName().toLowerCase().equals(tagName))
					nodes.add(e);
				else if (!e.getTagName().toLowerCase().equals(excluded))
					nodes.addAll(getDirectDescendantElements(e, tagName,
							excluded));
			}
		}
		return nodes;
	}

	/**
	 * Returns string for the attribute value if it is specified in the HTML
	 * source, otherwise this method returns null. Note that hasAttribute()
	 * badly works when the default value of the attribute is specified in the
	 * HTML spec. Using this method and comparing the result to null works well.
	 * 
	 * @param e
	 * @param attr
	 * @return attribute value string or null.
	 */
	// TODO consider <tag attr>, not <tag attr="value">.
	private String getAttribute(Element e, String attr) {
		Attr att = e.getAttributeNode(attr);
		if (att == null)
			return null;
		return att.getValue();
	}

	/**
	 * For new JIS. used in item_23(). Returns the most nearest ascendant table
	 * element. If such table is not found (case of invalid use of caption
	 * elements), this method returns null.
	 */
	private Element nearestTable(Element el) {
		Node e = el;
		while ((e instanceof Element)
				&& !((Element) e).getTagName().toLowerCase().equals("table")) {
			e = ((Element) e).getParentNode();
		}
		return (e instanceof Element) ? (Element) e : null;
	}

	/**
	 * For new JIS. Currently it is not used. It will be used from item_3().
	 * 
	 * @param alt
	 * @param longdescUri
	 * @return
	 */
	private boolean longdescLongerThanALT(String alt, String longdescUri) {
		// TODO Auto-generated method stub
		return false;
	}

	/**
	 * For new JIS. Currently it is not used. It will be used from item_3().
	 * 
	 * @param url
	 * @return
	 */
	private boolean isExistingUrl(String url) {
		url = url.trim();
		if (url.length() == 0)
			return false;
		else
			return true; // check routine comes here
	}

	// For new JIS
	/**
	 * @param table
	 */
	private boolean hasDuplicatedCaptionAndSummary(Element table) {
		String strSum = table.getAttribute("summary").trim(); //$NON-NLS-1$
		NodeList capNl = table.getElementsByTagName("caption"); //$NON-NLS-1$
		for (int i = 0; i < capNl.getLength(); i++) {
			if (strSum.equals(HtmlTagUtil.getTextDescendant(capNl.item(i))
					.trim()))
				return true;
		}
		return false;
	}

	/**
	 * For new JIS
	 * 
	 * @param table
	 */
	private boolean hasSummary(Element table) {
		String strSum = table.getAttribute("summary"); //$NON-NLS-1$
		return strSum.length() > 0;
	}

	private boolean hasCaption(Element table) {
		return table.getElementsByTagName("caption").getLength() > 0; //$NON-NLS-1$
	}

	/**
	 * For new JIS
	 * 
	 * @param el
	 * @param labels
	 * @return
	 */
	private boolean hasTitle(Element el) {
		return el.hasAttribute("title"); //$NON-NLS-1$
	}

	private boolean hasBlankTitle(Element el) {
		if (!el.hasAttribute("title"))
			return true;
		String title = el.getAttribute("title");
		return title.matches("^[\\s\u3000]*$");
	}

	// For new JIS
	private boolean isEmptyString(String s) {
		return (s == null || s.length() == 0);
	}
}
