	var CLASS_CORRECT		= "correct";
	var CLASS_INCORRECT		= "incorrect";
	var CLASS_ONCOMPLETE	= "oncomplete";
	var CLASS_ONINCOMPLETE	= "onincomplete";
	
	// This function shows the answer for a static quiz.
	function quiz_static_show_answer (control)
		{	// Set the containing quiz into the oncomplete state.
			quiz_set_oncomplete(control);
		}; // function quiz_static_show_answer (control)

	// This function hides the answer for a static quiz.
	function quiz_static_hide_answer (control)
		{	// Set the containing quiz into the oncomplete state.
			quiz_reset(control);
		}; // function quiz_static_hide_answer (control)

	// This function checks if an input's value is correct.
	function quiz_check_ans (control, hiding)
		{	// The user answered correctly.
			if ( control )
				{	// Determine if the answer is correct.
					var is_correct = quiz_input_correct(control);

					// Is this a wrong checkbox?
					var wrong_checkbox = control.type == "checkbox" && control.getAttribute("correct") == "no";

					// Get the class name to apply.
					var classname	= is_correct ? CLASS_CORRECT : CLASS_INCORRECT;
					classname		= classname == CLASS_INCORRECT && hiding == true ? "" : classname;

					// Use a blank class name of checkboxes marked as the wrong answer.
					var classname = ( classname == CLASS_CORRECT && wrong_checkbox ) ? "" : classname;

					// Get the current classname.
					var curr_classname = control.parentNode.className;

					// Remove both correct/incorrect subclasses.
					curr_classname = removeCSSStyleName(curr_classname, CLASS_CORRECT);
					curr_classname = removeCSSStyleName(curr_classname, CLASS_INCORRECT);

					// Set the parent's class to correct.
					control.parentNode.className = appendCSSStyleName(curr_classname, classname);

					// Disable the control.
					if ( is_correct )
						{	control.disabled = !wrong_checkbox && true;							
						} // if ( is_correct )

					else
						{	control.disabled = false;
						}; // else

					// Set the show link.
					var alinks		= control.parentNode.getElementsByTagName("a");
					var show_link	= false;
					for ( var index = 0; index < alinks.length; index++ )
						{	if ( alinks.item(index).name == "show_link" )
								{	show_link = alinks.item(index);
									break;
								}; // if ( alinks.item(index).name == "show_link" )
						}; // for ( var index = 0; index < alinks.length; index++ )

					if ( show_link != false )
						{	show_link.innerHTML = is_correct ? "Hide Answer" : "Show Answer";
						}; // if ( show_link != false )

					// Check the quiz.
					quiz_check_is_complete(control);
				}; // if ( control )
		}; // function quiz_check_ans (control)

	// This method determines if a quiz is complete and sets its status accordingly.
	function quiz_check_is_complete (node)
		{	// Now set the quiz to completed if needed.
			var quiz = quiz_get_quiz(node);

			// No quiz element?
			if ( !quiz )
				{	return;
				}; // if ( !quiz )

			// Get the answer containers.
			var nodes = quiz ? quiz.getElementsByTagName("div") : false;

			// Get the number of answers.
			var num_nodes = nodes ? nodes.length : 0;			

			// Boolean value indicating whether the quiz is completed.
			var completed = true;

			// Makes sure all the answers are correct.
			for ( var index = 0; completed && index < num_nodes; index++ )
				{	// Check the next node.
					if ( containsCSSStyleName(nodes.item(index).className, "q") )
						{	completed = completed && quiz_check_node(nodes.item(index));
						}; // if ( containsCSSStyleName(nodes.item(index).className, "q") )
				}; // for ( var index = 0; completed && index < num_nodes; index++ )
			// Get the current classname.
			var curr_classname = quiz.className;

			// Remove both correct/incorrect subclasses.
			curr_classname = removeCSSStyleName(curr_classname, CLASS_ONCOMPLETE);
			curr_classname = removeCSSStyleName(curr_classname, CLASS_ONINCOMPLETE);

			// Mark the quiz as completed or uncompleted.
			quiz.className = appendCSSStyleName(curr_classname, completed ? CLASS_ONCOMPLETE : CLASS_ONINCOMPLETE);
		}; // function quiz_check_is_complete (node)

	// This method determines if a question node's answer is correct.
	function quiz_check_node (node)
		{	// Nothing to check.
			if ( !node )
				{	return false;
				}; // if ( !node )

			// Find the text input control.
			var nodes	= node.getElementsByTagName("input");
			node		= nodes.length == 1 ? nodes.item(0) : false;

			// Check the input's value.
			return node ? quiz_input_correct(node) : false;
		}; // function quiz_check_node (node)

	// This function returns the containing quiz.
	function quiz_get_quiz (node)
		{	// Find the quiz element.
			while ( node && !(node.nodeName.toLowerCase() == "div" && containsCSSStyleName(node.className, "quiz")) )
				{	node = node.parentNode;
				}; // while ( node && !(node.nodeName.toLowerCase() == "div" && containsCSSStyleName(node.className, "quiz")) )

			return node;
		}; // function quiz_get_quiz (node)

	// This function checks if an input's value is correct.
	function quiz_input_correct (control)
		{	// Get the input type.
			var type = control.type;

			// Check the fill-in.
			if ( type == "text" )
				{	// Get the answer and value.
					var ans = "" + (control ? control.getAttribute("ans") : "");
					var val = "" + (control ? control.value : "");

					// Trim leading and trailing whitespace and convert to lowercase.
					ans = ans.replace(/^\s+|\s+$/, "").toLowerCase();
					val = val.replace(/^\s+|\s+$/, "").toLowerCase();

					return val == ans;
				} // if ( type == "text" )

			// Check the selection.
			else if ( type == "checkbox" )
				{	return control.checked ? control.getAttribute("correct") == "yes" : control.getAttribute("correct") != "yes";
				} // else if ( type == "checkbox" )

			// Invalid type.
			else
				{	return false;
				}; // else
		}; // function quiz_input_correct (control)

	// This function sets a quiz into the initial state, searching up the DOM as needed.
	function quiz_reset (node)
		{	// Find the quiz element.
			node = quiz_get_quiz(node);

			// Append the CSS style.
			if ( node )
				{	var classname	= node.className; 
					classname		= removeCSSStyleName(classname, CLASS_ONCOMPLETE);
					node.className	= appendCSSStyleName(classname, CLASS_ONINCOMPLETE);
				}; // if ( node )
		}; // function quiz_reset (node)

	// This function sets a quiz into the oncomplete state, searching up the DOM as needed.
	function quiz_set_oncomplete (node)
		{	// Find the quiz element.
			node = quiz_get_quiz(node);

			// Append the CSS style.
			if ( node )
				{	var classname	= node.className; 
					classname		= removeCSSStyleName(classname, CLASS_ONINCOMPLETE);
					node.className	= appendCSSStyleName(classname, CLASS_ONCOMPLETE);
				}; // if ( node )
		}; // function quiz_set_oncomplete (node)

	function quiz_show_answer (control, show)
		{	// Get the parent node.
			var parent = control && control.parentNode ? control.parentNode : false;

			// Get all the input controls.
			var inputs	= parent ? parent.getElementsByTagName("input") : false;

			// Get the number of inputs.
			var num_inputs = inputs ? inputs.length : 0;

			// The input to set.
			var input = false;

			// Find the input.
			for ( var index = 0; index < num_inputs; index++ )
				{	if ( inputs.item(index).getAttribute("name") == "ans" )
						{	input = inputs.item(index);
						}; // if ( inputs.item(index).getAttribute("name") == "ans" )
				}; // for ( var index = 0; index < num_inputs; index++ )

			// Set the input's value.
			if ( input )
				{	input.value			= control.innerHTML == "Show Answer" ? input.getAttribute("ans") : "";
					control.innerHTML	= control.innerHTML == "Show Answer" ? "Hide Answer" : "Show Answer";					
					quiz_check_ans(input, true);
				}; // if ( input )
		}; // function quiz_show_answer (control)

	function quiz_toggle_completed (control)
		{	var quiz		= quiz_get_quiz(control);
			var className	= quiz.className; 
			var new_state	= containsCSSStyleName(className, CLASS_ONCOMPLETE) ? CLASS_ONINCOMPLETE : CLASS_ONCOMPLETE;
			className		= removeCSSStyleName(className, CLASS_ONCOMPLETE);
			className		= removeCSSStyleName(className, CLASS_ONINCOMPLETE);
			className		= appendCSSStyleName(className, new_state);
			quiz.className	= className;
			if ( new_state == CLASS_ONINCOMPLETE )
				{	quiz_check_is_complete(control.parentNode);
				};
		}; // function quiz_toggle_completed (control)

	function quiz_reset_all (control)
		{	var quiz		= quiz_get_quiz(control);
			var inputs		= quiz.getElementsByTagName("input");
			for ( var index = 0; index < inputs.length; index++ )
			{	inputs.item(index).disabled = false;
				inputs.item(index).checked	= false;
				inputs.item(index).value	= "";
			};
			var divs	= quiz.getElementsByTagName("div");
			for ( var index = 0; index < inputs.length; index++ )
			{	var div = divs.item(index);
				if ( containsCSSStyleName(div.className, "q") )
					{	div.className = removeCSSStyleName(div.className, CLASS_CORRECT);
						div.className = removeCSSStyleName(div.className, CLASS_INCORRECT);
					}; 
			};
			quiz_check_is_complete(inputs.item(0));
		}; 