/*******************************************************************************
 * Copyright (c) 2004, 2016 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", "ogg", "spx", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
			"oga" };

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

	/**
	 * 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 boolean isHTML5 = 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);
			try {
				liveObject = tmpD.getElementsByTagName("object").getLength();
			} catch (Exception e) {
				liveObject = 0;
			}
			try {
				liveEmbed = tmpD.getElementsByTagName("embed").getLength();
			} catch (Exception e) {
				liveEmbed = 0;
			}
		}

		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();

		// use original document's doctype
		DocumentType docType = edu.getSrcDom().getDoctype();
		docTypeS = DocumentTypeUtil.getOriginalID(docType);
		isXHTML = DocumentTypeUtil.isOriginalXHTML(docType);
		isHTML5 = DocumentTypeUtil.isOriginalHTML5(docType);

		// System.out.println(docTypeS + " : " + isXHTML + " : " + isHTML5);

		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 //$NON-NLS-1$
																// size
						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$
		}

		NodeList tmpNL = target.getElementsByTagName("math");
		if (tmpNL.getLength() > 0) {
			addCheckerProblem("C_600.20", "MathML", tmpNL);
		}
		tmpNL = target.getElementsByTagName("svg");
		if (tmpNL.getLength() > 0) {
			addCheckerProblem("C_600.20", "SVG", tmpNL);
		}

		Vector<Node> autoError = new Vector<Node>();
		Vector<Node> autoUserCheck = new Vector<Node>();

		tmpNL = target.getElementsByTagName("video");
		if (tmpNL.getLength() > 0) {
			addCheckerProblem("C_500.0", "", tmpNL);
			addCheckerProblem("C_500.1", "", tmpNL);

			addCheckerProblem("C_600.1", "", tmpNL);
			addCheckerProblem("C_600.2", "", tmpNL);
			addCheckerProblem("C_600.7", "", tmpNL);

			for (int i = 0; i < tmpNL.getLength(); i++) {
				Element e = (Element) tmpNL.item(i);
				if (e.hasAttribute("autoplay")) {
					String autoplay = e.getAttribute("autoplay");
					if (!autoplay.equalsIgnoreCase("false")) {
						autoError.add(e);
					} else {
						autoUserCheck.add(e);
					}
				} else {
					autoUserCheck.add(e);
				}
			}
		}
		tmpNL = target.getElementsByTagName("audio");
		if (tmpNL.getLength() > 0) {
			addCheckerProblem("C_600.1", "", tmpNL);
			for (int i = 0; i < tmpNL.getLength(); i++) {
				Element e = (Element) tmpNL.item(i);
				if (e.hasAttribute("autoplay")) {
					String autoplay = e.getAttribute("autoplay");
					if (!autoplay.equalsIgnoreCase("false")) {
						autoError.add(e);
					} else {
						autoUserCheck.add(e);
					}
				} else {
					autoUserCheck.add(e);
				}
			}
		}
		if (autoError.size() > 0) {
			addCheckerProblem("C_85.0", "", autoError);
		}
		if (autoUserCheck.size() > 0) {
			addCheckerProblem("C_600.6", "", autoUserCheck);
		}
	}

	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$
													+ "\")", //$NON-NLS-1$
											el);
									edu.appendErrorIcon(tmpCP, el);
								} else {
									// WARN
									IProblemItem tmpCP = addCheckerProblem("C_57.2", //$NON-NLS-1$
											" (href=\"" + aWithHref_hrefs[i] //$NON-NLS-1$
													+ "\")", //$NON-NLS-1$
											el);
									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);
								}
							}
						}
					}
				}
			} else if (isHTML5 && el.hasAttribute("charset")) {
				charset = el.getAttribute("charset");
			}
		}

		if (charset.length() == 0) {
			if (isHTML5) {
				// check existence of BOM in BlindVisualizerHTMl.visualize().
				result.add(new ProblemItemImpl("C_88.1")); //$NON-NLS-1$
			} else {
				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$
	}

	// 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);
	}
}
