  Object.extend( String.prototype, {
    empty: function(){
      return '' == this.trim();
    },
    trim: function(){
      return this.replace( /^\s+|\s+$/, '' );
    }
  });

  function addIdsToElements( form )
  {
    inputs  = $A( form.getElementsByTagName('input') );
    selects = $A( form.getElementsByTagName('select') );
    inputs.concat( selects );
    inputs.each( function(elm){
      if( !elm.id ){ elm.id = elm.name }
    });
  }

  function attachLabelsToElements( form )
  {
    labels = $A( $(form).getElementsByTagName('label') );
    labels.each( function(l){
      elm       = $(l.htmlFor);
      if( elm ){ elm.label = l; }
    });
  }

  // see http://www.dustindiaz.com/getelementsbyclass
  function getElementsByClass(searchClass,node,tag) {
    var classElements = new Array();
    if ( node == null )
      node = document;
    if ( tag == null )
      tag = '*';
    var els = node.getElementsByTagName(tag);
    var elsLen = els.length;
    var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
    for (i = 0, j = 0; i < elsLen; i++) {
      if ( pattern.test(els[i].className) ) {
        classElements[j] = els[i];
        j++;
      }
    }
    return classElements;
  }

  function dcValidateForm( e )
  {

    // prevent the default action (meaning: don't submit the form)
    YAHOO.util.Event.stopEvent( e );

    var form = this;
    var msg;
    var empty_fields = new Array;
	var processed_fields = new Array;
	
//	getElementsByClass (class of element, root element to search from, type of element to retrieve)
    var required_labels = getElementsByClass( 'required', form, 'label' );

    for( i=0; i<required_labels.length; i++ )
    {
      elm = $(required_labels[i].htmlFor);
      switch( elm.type )
      {
		// radio added by robertg 10.17.06 note: just copied checkbox and changed case value
		case "radio":
			if( fieldChecked(form.elements[elm.name]) )
			{
				processed_fields.push( elm.name );
			}
			else
			{
				empty_fields.push( (elm.label) ? elm.label.innerHTML : elm.name );
			}
		break;

		case "checkbox":
			if( fieldChecked(form.elements[elm.name]) )
			{
				processed_fields.push( elm.name );
			}
			else
			{
				empty_fields.push( (elm.label) ? elm.label.innerHTML : elm.name );
			}
		break;
        
		// note: this will work with a drop down that allows only one choice, to use a drop down with multiple
		// choices the case value would be "select-multiple" although I have NOT tested this so I am not sure
		// if any other changes would be required to use a multiple-selection drop down  robertg 1.5.07
		case "select-one":
	          if( 0 == elm.selectedIndex ){ empty_fields.push( (elm.label) ? elm.label.innerHTML : elm.name ) }
			// caveat: since this code looks for a selected index that is not 0 to determine if the user has 
			// made a choice, a drop down list that has a default value and the user chooses that default value
			// will always display the "you need to make a choice" message (since selected index will be 0). 
			// This is only an issue when the drop down list is required.  The workaround is to make the default
			// value of the drop down list a "Please select..." message. robertg 1.5.07
		break;
        
		case "text":
        	  if( elm.value.empty() ){ empty_fields.push( (elm.label) ? elm.label.innerHTML : elm.name ) }
	    break;

		// textarea added by robertg 10.19.06 note: just copied text and changed case value
		case "textarea":
        	  if( elm.value.empty() ){ empty_fields.push( (elm.label) ? elm.label.innerHTML : elm.name ) }
	    break;
      }
    }

    if( empty_fields.length > 0 )
    {
      msg = "Please complete the following fields:\n\n";
      msg += empty_fields.join( "\n" );
      window.alert(msg);
      return false;
    }

    // email checking
    var email = form.elements['emailAddress'].value;
//    var email = form.elements['LeadEmail'].value;
//    var email = form.elements['email_address'].value;
	// convert string to all lowercase so case is not an issue when making comparison
	var email = email.toLowerCase();	
	
    if( (email.indexOf('@') < 0) || (email.indexOf('.') < 0) ){ alert("Please check your email format."); return false; }
		
		if( form.elements['confirm_email'] )		
		{
			var confirm_email = form.elements['confirm_email'].value;
			// convert string to all lowercase so case is not an issue when making comparison
			var confirm_email = confirm_email.toLowerCase();
			
			if( email.trim() != confirm_email.trim() ){ alert("Email address and confirmation address don't match."); return 	false; }
		}

	// now perform any tests defined on the actual form itself
	if (localFormTests(this)) {
		// everything is okay so submit the form			
	    form.submit();
	}
}	




//	function fieldChecked( field )   ORIGINAL CODE
//	{
//		var counter = 0;
		// The $A() function converts the single argument it receives into an Array object.
		// .each calls the given iterator function passing each element in the list in the first argument and 
		// the index of the element in the second argument
//		$A(field).each( function(box){
//			if( true == box.checked ){ counter++ }
//		});
//		return counter > 0;
//	}

	// function fieldchecked( field )  robertg's workaround
	// note: original code only worked with at least two checkboxes/radio buttons (not sure why) so I hacked 
	// together this workaround.  there may be a better way to do this but it works so...  robertg 1.2007
	function fieldChecked( field ) {
		var counter = 0;
		
		// The $A() function converts the single argument it receives into an Array object.
		boxesToCheck = $A(field);

		// determine if only one checkbox (my workaround)
		if (boxesToCheck.length == 0) {		
			// only one checkbox
			if(field.checked == true){ 
				// field is checked so increment counter
				counter++ ;
			}
		} else {
			// more than one checkbox (original code)
			boxesToCheck.each( function(box){
			if( true == box.checked ){ counter++ }
			});
		}
		return counter > 0;
	}
	
  // Things to run after the page loads:
  var onload_func = function (){

    var FORM_ID       = 'mail_form';

    //attach ID attributes for form elements that don't have one
    addIdsToElements( $(FORM_ID) );

    // find the elements targeted by labels and explicitly link them
    // via element.label
    attachLabelsToElements( $(FORM_ID) );

    // Attach the validation routine the form's onsubmit event
    YAHOO.util.Event.addListener( FORM_ID, 'submit', dcValidateForm );
  };

  // Run the above function when the page is loaded.
  YAHOO.util.Event.addListener( window, 'load', onload_func );
