function mcFramework(ContentContainer,AVContainer,isCustom) {
	// ===========================
	// = Global Variables        =
	// ===========================
	
	var _this = this;
	var _SiteCode = '';
	var _WebServiceURL = 'coreframework.millercoors.com';
	var _isCustom = false;
	var _AVContainer = false;
	//var _AVForm = 'mc_av'; Need to remove this.
	var _AVContent = 'Please enter your date of birth.';
	var _AVFailContent = 'You must be of legal drinking age (21 or older) to enter our site. You are being redirected to http://www.thecoolspot.gov/ - a place for teens to find info on alcohol and resisting peer pressure.';
	var _AVFailForward = true;
	var _ContentContainer = false;
	var _PageLoaded = false;
	var _AVForm = new Object();
	var _AVBToUrl = '';
	var _AVBTarget = '';
	var _Luid = '';
	var _CallbackFunction = false;
	var _AVTag = false;
	var _AVFailTag = false;
	var _ContentDisplay = 'inline';
	var _Language = 'eng';
	var _AVBypassParameter = 'avToken';
	
	// Add path to framework web service
	_WebServiceURL = _WebServiceURL + '/core-framework'
	
	// =============================
	// = Initialization Operations =
	// =============================
	if(isCustom) {
		_isCustom = true
	}
	
	if(ContentContainer) {
		_ContentContainer = ContentContainer;
		_addStyles('#' + _ContentContainer + ' { display: none; }');
	}
	
	if(AVContainer) {
		_AVContainer = AVContainer;
	}
	
	if(!_isCustom) {
		_InitializeFramework();
	}
	
	/*
	This should be removed at some point
	if(isCustom) {
		_isCustom = true;
	}
	
	if(!_isCustom) {
		_InitializeFramework();
	}
	*/
	
	// =================================
	// = Public Get And Set Properties =
	// =================================
	
	this.mcSetSiteCode = function(val){_SiteCode = val};
	this.mcSetWebServiceURL = function(val){_WebServiceURL = val};
	this.mcSetCallbackFunction = function(val){_CallbackFunction = val};
	this.mcSetAVContainer = function(val){_AVContainer = val};
	this.mcSetAVContent = function(val){_AVContent = val};
	this.mcSetAVFailContent = function(val){_AVFailContent = val};
	this.mcSetAVFailForward = function(val){_AVFailForward = val};
	this.mcGetLuid = function(){return _Luid};
	this.mcSetContentDisplay = function(val){_ContentDisplay = val};
	this.mcSetLanguage = function(val){_Language = val};
	this.mcGetAVCookie = function(){return _GetAVCookie()};
	this.mcSetAVBypassParameter = function(val){_AVBypassParameter = val};
	
	
	// Set the tracking tag function which will fire on AV or AV Fail
	this.mcSetAVTag = function(val) {_AVTag = val;}
	this.mcSetAVFailTag = function(val) {_AVFailTag = val;}
	
	// ==========================
	// = Initialization Methods =
	// ==========================
	
	function _InitializeFramework() {
		if(_PageLoaded == true) {
			_CreateAVContainer();
			if(_CheckAV()) {
				_ShowContent();
			} else {
				if(_getParam('avToken')) {
					var parameters = new Object();
					parameters['token'] = _getParam('avToken');
					_buildUrlAndMakeRequest('AVTokenValidServlet','mcHandleWebServiceCallback.avbcheck',parameters);
				} else {
					_ShowAV();
				}
			}
		} else {
			// If the AV element has not been loaded, keep checking until it is.
			_PageLoaded = setInterval(_checkPageLoaded, 1);
		}
		_buildUrlAndMakeRequest('LuidServlet','mcHandleWebServiceCallback.luid');
	}
	
	function _checkPageLoaded() {
		var av = document.getElementById(_AVContainer);
		//var av = document.getElementById('mc_avform');
		if(av) {
			clearInterval(_PageLoaded);
			_PageLoaded = true;
			_InitializeFramework();
		}
	}
	
	// ============================
	// = Age Verification Methods =
	// ============================
	
	function _CheckAV() {
		// Check to see if the AV cookie has already been set
		if(_GetAVCookie() == 'true') {
			return true;
		} else {
			return false;
		}
	}
	
	// Send a request to the server to check if the user is 21 or over
	function _AgeVerify(month,day,year) {
		var parameters = new Object();
		parameters['year'] = year;
		parameters['month'] = month;
		parameters['day'] = day;
		_buildUrlAndMakeRequest('AgeVerifyServlet','mcHandleWebServiceCallback.av',parameters);
	}
	
	// ===================================
	// = Age Verification Bypass Methods =
	// ===================================
	
	this.mcAVBypass = function(url,target){
		var parameters = new Object();
		parameters['fromUrl'] = location.hostname;
		parameters['toUrl'] = url
		
		_AVBToUrl = url;
		_AVBTarget = target;
		
		_buildUrlAndMakeRequest('AVTokenGetServlet','mcHandleWebServiceCallback.avbsend',parameters);
	}
	
	// =====================
	// = Interface Methods =
	// =====================
	
	function _addStyles(styles) {
		var head = document.getElementsByTagName('head')[0],
		    style = document.createElement('style'),
		    rules = document.createTextNode(styles);
		style.type = 'text/css';
		if(style.styleSheet)
		    style.styleSheet.cssText = rules.nodeValue;
		else style.appendChild(rules);
		head.appendChild(style);
	}
	
	function _CreateAVContainer() {
		// Create the AV content div
		var container = document.getElementById(_AVContainer);
		//alert(container.hasChildNodes());
		//alert(container.firstChild.textContent);
		if (container) {
			var elem = document.createElement('div');
			elem.id = _AVContainer + '_inner';
			container.appendChild(elem);
		}
	}
	
	function _ShowAV() {
		switch (_Language) {
			case 'eng':
				mm_val = 'MM'
				dd_val = 'DD'
				yyyy_val = 'YYYY'
			break;
			case 'esp':
				mm_val = 'MM'
				dd_val = 'DD'
				yyyy_val = 'AAAA'
			break;
		}
		
		avhtml = '<form id="mc_avform" onSubmit="return false;">'
		       + '<div id="mc_avcontent">' + _AVContent + '</div>'
           + '<div id="mc_averrors"></div>'
		       + '<table>'
		       + '<tr>'
		       + '<td><input type="text" id="mc_avmonth" name="mc_avmonth" value="' + mm_val + '" maxLength="2" tabindex="1" autocomplete="off" /></td>'
		       + '<td><input type="text" id="mc_avday" name="mc_avday" value="' + dd_val + '" maxLength="2" tabindex="2" autocomplete="off" /></td>'
		       + '<td><input type="text" id="mc_avyear" name="mc_avyear" value="' + yyyy_val + '" maxLength="4" tabindex="3" autocomplete="off" /></td>'
		       + '</tr>'
		       + '</table>'
		       + '<div id="mc_avsubmit" style="cursor:pointer;"></div>'
		       + '</form>';
		
		document.getElementById(_AVContainer + '_inner').innerHTML = avhtml
		_AVFormInit();
		
		if (_AVTag) {
			_AVTag();
		}
	}
	
	function _ShowAVFail(callback) {
		avfailhtml = '<div id="mc_avfail">' + _AVFailContent + '</div>';
		document.getElementById(_AVContainer + '_inner').innerHTML = avfailhtml;
		if(_AVFailForward) {
			setTimeout('document.location.href="http://www.thecoolspot.gov"', 5000);
		}
		if (_AVFailTag) {
			_AVFailTag();
		}
	}
	
	function _ShowContent() {
		document.getElementById(_AVContainer).style.display = 'none';
		document.getElementById(_ContentContainer).style.display = _ContentDisplay;
		_SetAVCookie();
		if(_CallbackFunction) {
			_CallbackFunction();
		}
	}
	
	
	// =====================
	// = AV Cookie Methods =
	// =====================

	// Get the value of the sites AV cookie
	function _GetAVCookie() {
		var cookieName = _SiteCode + 'av';
		if (document.cookie.length>0) {
			c_start=document.cookie.indexOf(cookieName + '=');
		  if (c_start!=-1) { 
		    c_start=c_start + cookieName.length+1; 
		    c_end=document.cookie.indexOf(';',c_start);
		    if (c_end==-1) c_end=document.cookie.length;
		    return unescape(document.cookie.substring(c_start,c_end));
			} 
		}
		return '';
	}

	// Set the site AV cookie
	function _SetAVCookie() {
		var cookieName = _SiteCode + 'av';
		document.cookie = cookieName + '=true;path=/';
	}
	
	// =================================
	// = Web Service Request Methods   =
	// =================================
	
	function _buildUrlAndMakeRequest(servletName,callback,parameters) {
		var urlstr = _createUrlString(servletName,callback,parameters);
		_makeRequest(urlstr);
	}
	function _createUrlString(servletName,callback,parameters) {
		var paramStr = _createParameters(parameters);
		var urlstr = _createUrl(servletName,callback,paramStr);
		return urlstr;
	}
	function _createParameters(params) {
		var retval = "";
		for(var key in params) {
			retval += "&" + key + "=" + params[key];
		}
		return retval;
	}
	function _createUrl(servletName,callback,parameters) {
		var retval = 'http://' + _WebServiceURL + '/SERVLET?callback=CALLBACK'
		retval = retval.replace('SERVLET',servletName);
		retval = retval.replace('CALLBACK',callback);
		retval += parameters;
		return retval;
	}
	function _makeRequest(req) {
		var fullUrl = req;
    var noCacheIE = '&noCacheIE=' + (new Date()).getTime();
    var headLoc = document.getElementsByTagName("head").item(0);
    var scriptCounter = 1
		var scriptId = 'scriptId' + scriptCounter++;
		// Create script object
    var scriptObj = document.createElement("script");
    scriptObj.setAttribute("type", "text/javascript");
    scriptObj.setAttribute("charset", "utf-8");
    scriptObj.setAttribute("src", fullUrl + noCacheIE);
    scriptObj.setAttribute("id", scriptId);
		// Append script object to document head
		headLoc.appendChild(scriptObj);
	}
	// Handles all callbacks from each web service request
	mcHandleWebServiceCallback =  {
		av: function(val) {
			if(val == 'true') {
				_SetAVCookie()
				_ShowContent();
			} else {
				_ShowAVFail();
			}
		},
		avbsend: function(val) {
			var toUrl = '';
			
			if (_AVBToUrl.indexOf('?') > -1) {
				toUrl = _AVBToUrl + '&' + _AVBypassParameter + '=' + val;
			} else {
				toUrl = _AVBToUrl + '?' + _AVBypassParameter + '=' + val;
			}
			
			if(_AVBTarget == 'blank') {
				window.open(toUrl);
			} else {
				document.location.href = toUrl;
			}
		},
		avbcheck: function(val) {
			if(val == 'true') {
				_ShowContent();
			} else {
				_ShowAV();
			}
		},
		luid: function(val) {
			_Luid = _SiteCode + val;
		}
	}

	// =========================
	// = AV Form Functionality =
	// =========================

	// Initialize the AV Form
	function _AVFormInit() {
		// Initialize AV Form object
		_AVForm['object'] = document.getElementById('mc_avform');
		_AVForm['submit'] = document.getElementById('mc_avsubmit');
		_AVForm['month'] = document.getElementById('mc_avmonth');
		_AVForm['day'] = document.getElementById('mc_avday');
		_AVForm['year'] = document.getElementById('mc_avyear');
	
		// Add form event listners
		_listen(_AVForm['submit'], 'click', _AVFormSubmit);
		_listen(_AVForm['object'], 'keyup', _AVFormAutoTab);
		_listen(_AVForm['month'], 'focus', _AVFormFocusElement);
		_listen(_AVForm['day'], 'focus', _AVFormFocusElement);
		_listen(_AVForm['year'], 'focus', _AVFormFocusElement);
	
		// Set focus on month field
		_AVForm['month'].focus();
		_AVForm['month'].select();
		
	}
	
	// Handle auto tabbing
	function _AVFormAutoTab(e) {
		var srcElem = (window.event) ? e.srcElement : e.target;
		
		if(e.keyCode == 13) {
			_AVFormSubmit();
		} else {
			switch (srcElem.id) {
			case _AVForm['month'].id:
				if (_AVForm['month'].value.match(/^[0-9]{2}$/)) {
				  _AVForm['day'].focus();
					_AVForm['day'].select();
				}
				break;
			case _AVForm['day'].id: 
				if (_AVForm['day'].value.match(/^[0-9]{2}$/)) {
				  _AVForm['year'].focus();
					_AVForm['year'].select();
				}
				break; 
			default:
				result = 'unknown';
			}
		}
	}
	
	function _AVFormFocusElement(e) {
		var srcElem = (window.event) ? e.srcElement : e.target;
		srcElem.focus();
		srcElem.select();
	}
	
	// Submit AV form
	function _AVFormSubmit() {
		if(_AVFormValidate()) {
			var month = _AVForm['month'].value;
			var day = _AVForm['day'].value;
			var year = _AVForm['year'].value;
			_AgeVerify(month,day,year);
		}
	}

	// ======================
	// = AV Form Validation =
	// ======================

	// Validate the AV form
	function _AVFormValidate() {
		switch (_Language) {
			case 'eng':
				error_month = 'Please enter a valid month.';
				error_day = 'Please enter a valid day.';
				error_year = 'Please enter a valid year.';
				error_date = 'Please enter a valid date.';
			break;
			case 'esp':
				error_month = 'Indica el mes con números.';
				error_day = 'Indica el día con números.';
				error_year = 'Indica el año completo.';
				error_date = 'Indícala con números (mes-día-año).';
			break;
		}
		
		var av_errors = document.getElementById('mc_averrors');
	
	  if(!(_isNumeric(_AVForm['month'].value))) {
	    av_errors.innerHTML = error_month;
			_AVForm['month'].focus();
			_AVForm['month'].select();
	    return false;
	  }
	  if(!(_isNumeric(_AVForm['day'].value))) {
	    av_errors.innerHTML = error_day;
	    _AVForm['day'].focus();
			_AVForm['day'].select();
	    return false;
	  }
	  if(!(_isNumeric(_AVForm['year'].value))) {
	    av_errors.innerHTML = error_year;
	    _AVForm['year'].focus();
			_AVForm['year'].select();
	    return false;
	  }
	  if(_AVForm['year'].value.length < 4) {
	    av_errors.innerHTML = error_year;
	    _AVForm['year'].focus();
			_AVForm['year'].select();
	    return false;
	  }

	  if (!_checkdate(_AVForm['month'].value,_AVForm['day'].value,_AVForm['year'].value)) {
	    av_errors.innerHTML = error_date;
	    return false;
	  }
	  return true;
	}

	// Check if a string is numeric
	function _isNumeric(str) {
	   return /^\d+$/.test(str);
	}

	// Check if a string is a valid date
	function _checkdate(m,d,y) {
	  var now = new Date(); // current date from clients system
	  var yc = now.getYear(); // get current year
	  if (yc < 2000) yc = yc + 1900; // in case the year is < 2000
	  var yl=yc - 120; // least year to consider
	  var ym=yc; // most year to consider

	  if (m<1 || m>12) return(false);
	  if (d<1 || d>31) return(false);
	  if (y<yl || y>ym) return(false);
	  if (m==4 || m==6 || m==9 || m==11)
	  if (d==31) return(false);
	  if (m==2) {
	    var b=parseInt(y/4);
	    if (isNaN(b)) return(false);
	    if (d>29) return(false);
	    if (d==29 && ((y/4)!=parseInt(y/4))) return(false);
	  }
	  return(true);
	}
		
	// ==========================
	// = Event Listner Function =
	// ==========================
	
	function _listen(elem, evnt, func) {
		if (elem.addEventListener) // W3C DOM
			elem.addEventListener(evnt,func,false);
		else if (elem.attachEvent) { // IE DOM
			var r = elem.attachEvent("on"+evnt, func);
			return r;
		}
	}
	
	// ===============================
	// = Get Query String Parameters =
	// ===============================
	
	function _getParam(name) {
	  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
	  var regexS = "[\\?&]"+name+"=([^&#]*)";
	  var regex = new RegExp( regexS );
	  var results = regex.exec( window.location.href );
	  if( results == null ) {
	    return false;
		} else {
	    return results[1];
		}
	}
	
	// ================================================
	// = Terms & Conditions and Privacy Policy Popups =
	// ================================================
	
	this.mcLaunchPrivacy = function() {
	  var name = Math.round( 9999*Math.random( ) ) + new Date( ).getTime( );
	  var win = window.open( "http://www.millercoors.com/privacy-policy.aspx","FooterLinks" + name,"toolbar=0,menubar=0,width=640,height=500,status=0,resizable=1,scrollbars=1" );
	  //Figure out how to actually make this work
		//if( !win ) { getSwf(swfId).openWindowFromSwf( "http://www.millercoors.com/privacy-policy.aspx" ); }
	  //else { winNew.focus( ); }
	}

	this.mcLaunchTerms = function() {
	  var name = Math.round( 9999*Math.random( ) ) + new Date( ).getTime( );
	  var win = window.open("http://www.millercoors.com/terms-conditions.aspx","FooterLinks" + name,"toolbar=0,menubar=0,width=640,height=500,status=0,resizable=1,scrollbars=1" );
	  //Figure out how to actually make this work
		//if( !win ) { getSwf(swfId).openWindowFromSwf( "http://www.millercoors.com/terms-conditions.aspx" ); }
	  //else { winNew.focus( ); }
	}
	
	this.mcLaunchPrivacyES = function() {
	  var name = Math.round( 9999*Math.random( ) ) + new Date( ).getTime( );
	  var win = window.open( "http://www.millercoors.com/privacy-policy-spanish.aspx","FooterLinks" + name,"toolbar=0,menubar=0,width=640,height=500,status=0,resizable=1,scrollbars=1" );
	  //Figure out how to actually make this work
		//if( !win ) { getSwf(swfId).openWindowFromSwf( "http://www.millercoors.com/privacy-policy.aspx" ); }
	  //else { winNew.focus( ); }
	}

	this.mcLaunchTermsES = function() {
	  var name = Math.round( 9999*Math.random( ) ) + new Date( ).getTime( );
	  var win = window.open("http://www.millercoors.com/terms-conditions-spanish.aspx","FooterLinks" + name,"toolbar=0,menubar=0,width=640,height=500,status=0,resizable=1,scrollbars=1" );
	  //Figure out how to actually make this work
		//if( !win ) { getSwf(swfId).openWindowFromSwf( "http://www.millercoors.com/terms-conditions.aspx" ); }
	  //else { winNew.focus( ); }
	}
}